2016-10-19 10 views
0

Я пытаюсь понять заголовочный файл cmsis, который входит в состав микроконтроллера STM-32 Cortex-M4. Они имеют структуру, которая являетсяУказатель структуры для доступа к регистру на микроконтроллере?

typedef struct 
{ 
    __IO uint32_t MODER; /*!< GPIO port mode register,    Address offset: 0x00  */ 
    __IO uint32_t OTYPER; /*!< GPIO port output type register,  Address offset: 0x04  */ 
    __IO uint32_t OSPEEDR; /*!< GPIO port output speed register,  Address offset: 0x08  */ 
    __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C  */ 
    __IO uint32_t IDR;  /*!< GPIO port input data register,   Address offset: 0x10  */ 
    __IO uint32_t ODR;  /*!< GPIO port output data register,  Address offset: 0x14  */ 
    __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18  */ 
    __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A  */ 
    __IO uint32_t LCKR;  /*!< GPIO port configuration lock register, Address offset: 0x1C  */ 
    __IO uint32_t AFR[2]; /*!< GPIO alternate function registers,  Address offset: 0x20-0x24 */ 
} GPIO_TypeDef; 

ли смысл, например, написать:

((GPIO_TypeDef *) 0x08000) -> MODER = 0x12; 

Я не понимаю, что делает эту линию. Было бы больше смысла для меня, если вы сделали

GPIO_TypeDef * td = 0x08000; 
td -> MODER = 0x12; 

ли это то же самое? Зачем?

+0

'(0x3 << (2 * i))' может вызывать неопределенное поведение. Если это код из ST-примеров, я был бы очень обеспокоен качеством кода ST (но тогда я не был бы очень удивлен). И 'MODER' не является« сбросом режима »(что бы это ни значило), но Регистр режима GPIO. Неясно, какова ваша проблема, то есть стандартная C. И этот макрос не оценивает '((GPIO_TypeDef *) 0x0C00)'! Сначала вы должны прочитать справочное руководство. – Olaf

+0

Я отредактировал его, чтобы сделать его более ясным. – ben

+0

Это не что иное, как манипуляция на языке программирования C. Цель состоит в том, чтобы попытаться заставить компилятор генерировать конкретные машинные инструкции с правильным адресом и значением данных, поданным на эту инструкцию. Использование structs - это только последнее причудливое предсказание о гхи. Может быть, есть меньше набрав, чем предыдущие причуды? Тем не менее существует риск того, что компилятор не генерирует правильную инструкцию для вас, видел, как это происходит (но очень редко и не может сделать это по требованию). Разберите двоичный файл, и вы увидите, что адрес и данные втягиваются в регистры, тогда в этом случае происходит сохранение. –

ответ

1

GPIO_TypeDef struct - это умный механизм для смещения адресов кодировки. Поэтому, если нам задан указатель на базовый адрес GPIOD, и мы наложим этот указатель на указатель на структуру GPIO_TypeDef, мы можем использовать стандартный оператор dereference (->) для доступа к адресу с некоторым смещением от базового адреса GPIOD.

Таким образом, в вашем примере, GPIOD_BASE вычисляет (AHB1PERIPH_BASE + 0x0C00) и MODER имеет адрес смещения 0x0 от указателя на GPIO_TypeDef структуры. Это означает, что GPIOD_BASE->MODER оценивает по: (AHB1PERIPH_BASE + 0x0C00) + 0x00. Это только адрес регистра режима порта для GPIOD.

Это работает для всего поля, определенного в структуре GPIO_TypeDef. Например, GPIOD_BASE->PUPDR оценивает (AHB1PERIPH_BASE + 0x0C00) + 0x0C. Это просто адрес регистратора вытягивания/вытягивания для GPIOD.

+0

Почему downvote? Я счастлив отредактировать/разъяснить этот ответ, если что-то не так или неясно. – pymaxion

+0

Ваш текст на самом деле говорит, что «структура» - это умный механизм для ... ». Это базовая C и то, как «struct» работает внутри. Это никоим образом не характерно для этого примера или встроенного программирования. – Olaf

+0

OP, похоже, не понимает функции этой структуры. Он сказал: «Я не понимаю, что делает эта линия». Я даю общий фон, а также конкретные примеры того, как оцениваются выражения OP. – pymaxion