Прежде всего, извините за название, было сложно придумать описание. Я пытаюсь создать структуру, которая будет иметь доступ к периферийному устройству, которое имеет очень мало внутренних регистров, которые управляются 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 и т. Д.). Что касается набора инструментов, я использую компилятор Diab Wind River. Спасибо.
Mark
РЕДАКТИРОВАТЬ: На основе комментария Абеленки