指针数组(*(volatile unsigned long *)0x40004000)

我很难搞清楚如何解决以下问题。 我在一个内存非常少的嵌入式系统上,希望尽量减少内存使用量。 指针总是让我感到困惑,并且总是这样。

我有一大堆寄存器地址定义:

#define GPIO_PORTA_BASE (*((volatile unsigned long *)0x40004000)) #define GPIO_PORTB_BASE (*((volatile unsigned long *)0x40005000)) //etc.. 

这些寄存器可直接访问。 例如:

 GPIO_PORT_BASE &= 0x01; 

我需要的是一个包含上述寄存器的数组,以便我可以轻松地将它们映射到索引。 例如:

 not_sure_what_to_declare_the array_as port_base_array[] { GPIO_PORTA_BASE, GPIO_PORTB_BASE, //etc } 

我最终需要做的是这样的事情:

 volatile unsigned long *reg; *reg_a = port_base_array[0]; reg_a &=0x1; 

我正在使用gcc来编译arm cortex m3的代码。

任何见解将不胜感激。

我不知道为什么@Etienne删除了他的答案,但它包含了基本信息:地址被转换为volatile unsigned long * 。 这就是你需要的数组。

 typedef volatile unsigned long* reg_addr; reg_addr registers[] = { &GPIO_PORTA_BASE, &GPIO_PORTB_BASE, // ... }; 

我们需要再次获取地址( &GPIO_PORTA_BASE ),因为宏会自动取消引用它们。 访问:

 *registers[i] &= your_value; 

通常的方法是声明一个结构,例如:

 struct RegsAtAddrA { unsigned int array1[10]; char val1; // etc }; 

然后访问它:

 volatile RegsAtAddrA *pRegsA = (volatile RegsAtAddrA *) 0x40004000; pRegsA->val1= 'a'; //etc 

编辑:我刚才意识到我没有回答这个问题。 所以,这里是:

 #include  unsigned long a=1; unsigned long b=2; volatile unsigned long *port_base_array[] = { &a, &b, //etc }; int main() { std::cout<<"a="<<*port_base_array[0]<
		      	

如果我找对你,这应该足够了:

 volatile unsigned long* GPIO_PORTA = (volatile unsigned long*) 0x40004000; 

你可以用它作为

 volatile unsigned long regxx = GPIO_PORTA[0x17]; // even GPIO_PORTA[10] &= 0xF000; 

我认为你要做的是这样的事情:

 volatile unsigned long * gpio_porta = &GPIO_PORTA_BASE; 

如果您使用的是C ++,还可以执行以下操作:

 volatile unsigned long & reg_foo = (&GPIO_PORTA_BASE)[3]; volatile unsigned long & reg_foo = gpio_porta[3]; 

并将其用作:

 reg_foo &= 0x1; 

但是,大多数情况下,我希望基址寄存器实际上存储为指针,而不是指针的取消引用。 因此,我可能希望将您的宏定义为:

 #define GPIO_PORTA_BASE ((volatile unsigned long *) 0x40004000) #define GPIO_PORTB_BASE ((volatile unsigned long *) 0x40005000) 

然后你可以简单地访问它们

 GPIO_PORTA_BASE[3] &= 0x1