指针数组,如(*(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 <iostream>
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]<<std::endl;
    std::cout<<"b="<<*port_base_array[1]<<std::endl;
}

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

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

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

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

可以写成

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

相关内容

  • 没有找到相关文章

最新更新