0% found this document useful (0 votes)
11 views2 pages

UART Initialization

Uploaded by

dokterhis1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views2 pages

UART Initialization

Uploaded by

dokterhis1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

UART Initialization

Like all STM32 peripherals, even the USARTs⁴ are mapped in the memory mappedperipheral region,
which starts from 0x4000 0000. The CubeHAL abstracts the effective location of each USART for a
given STM32 MCU thanks to the USART_TypeDef⁵ descriptor. For example, we can simply use the
USART2 macro to refer to the second USART peripheral provided by all STM32 microcontrollers with
LQFP64 package. However, all the HAL functions related to UART management are designed so that
they accept as first parameter an instance of the C struct UART_HandleTypeDef, which is defined in
the following way⁶: ⁴Starting from this paragraph, the terms USART and UART are used
interchangeably, unless different noticed. ⁵The analysis of the fields of this C struct is outside of the
scope of this book. ⁶Please, take note that the list of fields of the struct UART_HandleTypeDef is not
complete. Several fields, not relevant to the topics covered in this chapter, are omitted here. For
more information, refer to the CubeHAL. Universal Asynchronous Serial Communications 181
typedef struct { USART_TypeDef UART_InitTypeDef UART_AdvFeatureInitTypeDef uint8_t uint16_t
uint16_t uint8_t uint16_t uint16_t DMA_HandleTypeDef DMA_HandleTypeDef HAL_LockTypeDef
__IO HAL_UART_StateTypeDef __IO HAL_UART_ErrorTypeDef } UART_HandleTypeDef; *Instance;
Init; AdvancedInit; *pTxBuffPtr; TxXferSize; TxXferCount; *pRxBuffPtr; RxXferSize; RxXferCount;
*hdmatx; *hdmarx; Lock; gState; ErrorCode; /* UART registers base address /* UART communication
parameters */ */ /* UART Advanced Features initialization parameters */ /* Pointer to UART Tx
transfer Buffer */ /* UART Tx Transfer size */ /* UART Tx Transfer Counter */ /* Pointer to UART Rx
transfer Buffer */ /* UART Rx Transfer size */ /* UART Rx Transfer Counter /* UART Tx DMA Handle
parameters /* UART Rx DMA Handle parameters /* Locking object /* UART communication state /*
UART Error code Let us see more in depth the most important fields of this struct. */ */ */ */ */ */ •
Instance: is the pointer to the USART descriptor we are going to use (that is, the base address in
memorywheretheperipheral is mapped). For example,USART2 is the descriptor of the UART
associated to the ST-LINK interface of every Nucleo board. • Init: is an instance of the C struct
UART_InitTypeDef, which is used to configure the UART interface. We will study it more in depth in a
while. • AdvancedInit: this field is used to configure more advanced UART features like the
automatic BaudRate detection and the TX/RX pin swapping. Some HALs do not provide this
additional field. This happens because USART interfaces are not equal for all STM32 MCUs. This is an
important aspect to keep in mind while choosing the right MCU for your application. The analysis of
this field is outside the scope of this book. • pTxBuffPtr and pRxBuffPtr: these fields point to the
transmit and receive buffer respectively. TheyareusedassourcetotransmitTxXferSize bytes over the
UARTandtoreceiveRxXferSize when the UART is configured in Full Duplex Mode. The TxXferCount
and RxXferCount fields are used internally by the HAL to take count of transmitted and received
bytes. • Lock: this field is used internally by the HAL to lock concurrent accesses to UART interfaces.
Universal Asynchronous Serial Communications 182 As said above, the Lock field is used to rule
concurrent accesses in almost all HAL routines. If you take a look at the HAL code, you can see
several uses of the __HAL_LOCK() macro, which is expanded in this way: #define
__HAL_LOCK(__HANDLE__) do{ \ \ if((__HANDLE__)->Lock == HAL_LOCKED) \ { \ return HAL_BUSY; }
else { \ \ \ \ (__HANDLE__)->Lock = HAL_LOCKED; \ } }while (0) \ It is not clear why ST engineers
decided to take care of concurrent accesses to the HAL routines. Probably they decided to have a
thread safe approach, freeing the application developer from the responsibility of managing multiple
accesses to the same hardware interface in case of multiple threads running in the same application.
However, this has an annoying side effect for all HAL users: even if my application does not perform
concurrent accesses to the same peripheral, my code will be poor optimized by a lot of checks about
the state of the Lock field. Moreover, that way to lock is intrinsically thread unsafe, because there is
no critical section used to prevent race conditions in case a more privileged ISR preempts the
running code. Finally, if my application uses an RTOS, it is much better to use native OS locking
primitives (like semaphores and mutexes which are not only atomic, but also correctly manages the
task scheduling avoiding the busy waiting) to handle concurrent accesses, without the need to check
for a particular return value (HAL_BUSY) of the HAL functions

You might also like