2023-03-19 08:23 AM
Hi, I am developing an application which involves UART for the STM32F411VE, I am using FreeRTOS and I want to know if the HAL APIs and the HAL_UART_Transmit_IT in this case are thread safe, thanks
Solved! Go to Solution.
2023-03-19 09:35 AM
Hello @jg_spitfire ,
UART hardware generally have a transmit shift register (TSR) and some kind of data register (DR). The software loads the DR, and if the TSR is empty, DR is instantly transferred into TSR and TX begins. The software is free to load another byte into DR, and the hardware loads the new byte from DR to TSR whenever the TX (shift-out) of the previous byte finishes.
Hardware provides status bits for querying the status of DR & TSR. This way, the software can using polling method and still achieve continuous transmission with no gaps between the bytes.
for freeRTOS, obviously, your TX task needs to be polling UART status bits.
The general rule of RTOS is that if you are waiting for something to happen, your task needs to be blocked so other tasks can run.
Your task blocks on task notification, (ulTaskNotifyTake()), and the interrupt gives the notification using xTaskNotifyGive().
So, I can't imagine any other way without using interrupts. It makes no sense to block - unblock with each byte.
So, Move TX handling completely to interrupt handler (ISR), and notify the task when TX is completed.
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-03-19 09:35 AM
Hello @jg_spitfire ,
UART hardware generally have a transmit shift register (TSR) and some kind of data register (DR). The software loads the DR, and if the TSR is empty, DR is instantly transferred into TSR and TX begins. The software is free to load another byte into DR, and the hardware loads the new byte from DR to TSR whenever the TX (shift-out) of the previous byte finishes.
Hardware provides status bits for querying the status of DR & TSR. This way, the software can using polling method and still achieve continuous transmission with no gaps between the bytes.
for freeRTOS, obviously, your TX task needs to be polling UART status bits.
The general rule of RTOS is that if you are waiting for something to happen, your task needs to be blocked so other tasks can run.
Your task blocks on task notification, (ulTaskNotifyTake()), and the interrupt gives the notification using xTaskNotifyGive().
So, I can't imagine any other way without using interrupts. It makes no sense to block - unblock with each byte.
So, Move TX handling completely to interrupt handler (ISR), and notify the task when TX is completed.
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-03-19 03:43 PM
In addition to what @KHALSI_Foued replied - HAL_UART_Transmit_IT by itself (and most of HAL interfaces generally) is not reentrant because it modifies a shared data structure (huart).
The HAL public functions look like they are protected by some lock, but in fact this thing is not a real RTOS-level lock (TL;DR) so if you call these functions from several threads, either add your own RTOS lock - or redesign and call them from a single thread.
2023-03-20 01:20 AM
Hint: that's what mutexes were created for.