В C указатель на структуру, которая должна получить доступ к списку байтовых указателей. - PullRequest
0 голосов
/ 20 ноября 2010

Прежде всего, извините за название, было сложно придумать описание. Я пытаюсь создать структуру, которая будет иметь доступ к периферийному устройству, которое имеет очень мало внутренних регистров, которые управляются 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

РЕДАКТИРОВАТЬ: На основе комментария Абеленки

Ответы [ 2 ]

1 голос
/ 20 ноября 2010

Если вы хотите получить доступ к размеру байта в регистре с отображением в памяти, выполните следующие действия:

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. Это то, что вы хотите?

0 голосов
/ 20 ноября 2010

У большинства компиляторов есть способ указать, что структура должна быть упакована плотно, без заполнения для выравнивания.

Я не знаком с вашим компилятором, но изучите документацию для чего-то вроде

#pragma pack

до определения вашей структуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...