在C中,指向需要访问字节指针列表的结构的指针

时间:2010-11-20 02:20:44

标签: c

首先,抱歉标题,很难想出一个描述。我正在尝试创建一个访问外设的结构,该外设具有很少的由3个地址线控制的内部寄存器。所以我有以下结构定义:

typedef struct {
  union {
    unsigned char  *reg0aPtr;
    unsigned char  *reg0bPtr;
  } RegsAddrOffset0;

  union {
    unsigned char  *reg1aPtr;
    unsigned char  *reg1bPtr;
  } RegsAddrOffset1;

  ...

  union {
    unsigned char  *reg7aPtr;
    unsigned char  *reg7bPtr;
  } RegsAddrOffset7;
} DeviceRegMap;

然后如果我声明一个变量

DeviceRegMap  *uartRegMap = (DeviceRegMap *)(0xD0000000);

现在,如果我尝试使用uartRegMap变量来访问内存映射寄存器,我想我会看到*(uartRegMap-> RegsAddrOffset0.reg0aPtr)将从地址0xD0000000读取数据,这样做。如果我使用*(uartRegMap-> RegsAddrOffset1.reg1bPtr)我以为我会访问0xD0000001,但它实际上是访问地址0xD0000004。由于处理器是32位,因此自然对齐为4字节。我在想,因为指针的大小是一个int,在这种情况下是32位,这就是我访问4字节地址范围的原因(例如,0xD0000000,0xD0000004,0xD0000008等)。

如果我声明了DeviceRegMap数据类型的实例,我希望进行以下初始化:

DeviceRegMap uartRegMap = {
  (unsigned char  *)0xD0000000,
  (unsigned char  *)0xD0000001,
  ...
  (unsigned char  *)0xD0000007,
};

然后如果我想访问地址0xD0000007那么我会使用*(uartRegMap.RegsAddrOffset7.reg7bPtr)

问题是为什么指向DeviceRegMap数据类型的指针在4字节对齐(例如,0xD0000000,0xD0000004等)而不是字节对齐(例如,0xD0000000,0xD0000001等)上访问存储器。关于工具集我使用的是Wind River diab编译器。感谢。

标记

编辑:基于abelenky的评论

2 个答案:

答案 0 :(得分:1)

如果要访问内存映射寄存器的字节大小的部分,请执行以下操作:

struct DeviceRegMap {
  volatile unsigned char byte0;
  volatile unsigned char byte1;
  volatile unsigned char byte2;
  volatile unsigned char byte3;
};

static struct DeviceRegMap *device = (struct DeviceRegMap *)(0xD0000000);

现在device->byte0指向0xD0000000device->byte3指向0xD00000003。这就是你想要的吗?

答案 1 :(得分:0)

大多数编译器都有办法表明一个结构应该紧密打包,没有填充用于对齐目的。

我不熟悉您的编译器,但请浏览类似

的文档
#pragma pack
在结构定义之前