Skip to content

STM32: Serial: Overrun not handled properly in serial_readable #14925

Open
@boraozgen

Description

@boraozgen

Description of defect

Introduced in #4502, the following code is supposed to handle overrun condition in the USART peripheral.

/* To avoid a target blocking case, let's check for
* possible OVERRUN error and discard it
*/
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE)) {
__HAL_UART_CLEAR_OREFLAG(huart);
}

The issue is that by clearing the overrun flag (ORE), the data register (USART_DR) is read and the data in the register is lost. Moreover, this also clears the RXNE flag, which results in serial_readable returning false, which was not the case before clearing ORE. In short, the clearing ORE does not belong to this function and should be done somewhere else.

A possible case where this leads to a endless loop is when you call getc (UnbufferedSerial::read) in the Serial RX interrupt. If the peripheral has been initialized and an overrun has occured before the interrupt is enabled, the first getc call on the first interrupt will block forever due to this issue.

Target(s) affected by this defect ?

STM32F4

Toolchain(s) (name and version) displaying this defect ?

GCC

What version of Mbed-os are you using (tag or sha) ?

mbed-os-99.99.99

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

Not relevant

How is this defect reproduced ?

We encountered this issue in a more complicated setup, but the steps are basically these:

  • Construct (enable) UnbufferedSerial
  • Send some bytes to the target
  • Attach the RxIrq interrupt to a function which calls read

@jeromecoutant

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions