Hello,
I've found a bug in the CMSIS USART_Driver of the Device Family Pack STM32F4xx, Version 2.4.0. Previous Version are concerned, too.
When frequently polling USART_GetStatus while receiving is still in progress, the memeber 'rx_busy' of 'usart->info->status' becomes corrupted due to concurrently accessing the 'usart->info->status' bitfield inside the functions USART_GetStatus in the application scope and USART_IRQHandler in interrupt scope. The error occurs just after the last RXNE interrupt, where the value of 'usart->info->status.rx_busy' is set to '0', has occured. USART_GetStatus concurrently performs a read-modify operation on 'usart->info->status', which is a bitfield structure. Reading has been done before the occurence of the RXNE interrupt, writing is done after the interrupt routine and overwrites the change done by the interrupt routine. the value of rx_busy is '1' instead of '0'.
Timeline: GetStatus: Read bitfield 'usart->info->status' Interrupt: Read and modify bitfield 'usart->info->status' GetStatus: Write bitfield 'usart->info->status' // this discards the changes done by the irqHandler
Files: USART_GetStatus is implemented in USART_STM32F4xx.c, Revision: V2.01 USART_IRQHandler is implemented in USART_STM32F4xx.c, Revision: V2.01 ARM_USART_STATUS is declare as a bitfield in Driver_USART.h, Revision: V2.02
excerpt of file USART_STM32F4xx.c, Revision: V2.01 :
2681 static ARM_USART_STATUS USART_GetStatus (const USART_RESOURCES *usart) { 2682 usart->info->status.tx_busy = ((usart->reg->SR & USART_SR_TC) ? (0U) : (1U)); 2683 return usart->info->status; 2684 } .. 2757 void USART_IRQHandler (const USART_RESOURCES *usart) { .. 2864 usart->info->status.rx_busy = 0U;