首先,抱歉标题,很难想出一个描述。我正在尝试创建一个访问外设的结构,该外设具有很少的由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的评论
答案 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
指向0xD0000000
,device->byte3
指向0xD00000003
。这就是你想要的吗?
答案 1 :(得分:0)
大多数编译器都有办法表明一个结构应该紧密打包,没有填充用于对齐目的。
我不熟悉您的编译器,但请浏览类似
的文档#pragma pack
在结构定义之前。