Структурировать указатель на регистр доступа на микроконтроллере?
Я пытаюсь понять заголовочный файл 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;
Это одно и то же? Зачем?
1 ответ
GPIO_TypeDef
struct - это умный механизм для кодирования смещений адресов. Так что, если нам дан указатель на базовый адрес GPIOD, и мы приведем этот указатель к GPIO_TypeDef
Используя указатель структуры, мы можем использовать стандартный оператор разыменования Си (->) для доступа к адресу с некоторым смещением от базового адреса 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.