The ->
operator is a convenient way to address a memory mapped register of a certain peripheral.
Registers in the STM32 memory map are grouped in a way that makes it possible to write a struct
definition for each peripheral, having the registers of the peripheral in one unit, for example:
typedef struct
{
__IO uint32_t CR; /*!< RCC clock control register, Address offset: 0x00 */
__IO uint32_t PLLCFGR; /*!< RCC PLL configuration register, Address offset: 0x04 */
__IO uint32_t CFGR; /*!< RCC clock configuration register, Address offset: 0x08 */
/* ... */
} RCC_TypeDef;
It's advantage over using a separate definition for each register becomes more apparent when there are more than one peripherals of the same kind, e.g. UARTs. There is a typedef struct { /* ... */ } USART_TypeDef;
similar to the above one, describing the arrangement of the UART registers, then the base address of each USART/UART is defined as pointers to a USART_TypeDef
.
#define USART1 ((USART_TypeDef *) USART1_BASE)
#define USART2 ((USART_TypeDef *) USART2_BASE)
Consider the following function:
void usart1_send_byte(uint8_t data) {
while((USART1->SR & USART_SR_TXE) == 0)
;
USART1->DR = data;
}
If there were separate definitions for each register in the system headers, it would become someting like
void usart1_send_byte(uint8_t data) {
while((*USART1_SR & USART_SR_TXE) == 0)
;
*USART1_DR = data;
}
Now we would like to generalize this function to work with any UART/USART in the system, not just USART1. Converting the first variant is easy,
void usart1_send_byte(USART_TypeDef *u, uint8_t data) {
while((u->SR & USART_SR_TXE) == 0)
;
u->DR = data;
}
but the other one would become quite awkward. Should we pass the address of each register it touches as a parameter? Or use more complicated constructs like *(usart_base + USART_DR_OFFSET)
every time?
RCC
in the stm32 headers. Using the->
operator on a pointer acquired by converting a nonzero integer constant to a pointer is certainly implementation defined, maybe even undefined behaviour. Imagine asking this on stackoverflow, language lawyers would come down on the question with all their wrath. This question makes sense only in an embedded context. \$\endgroup\$