Skip to content

Serial handling at high data rates with HW flow control on ST platforms #4722

@RobMeades

Description

@RobMeades

Description

  • Type: Possible Bug?
  • Priority: Minor

Target
STM

I'm dealing with an application on an ST platform in which the serial port is being run at quite a high rate (460800 bits/s). In order to receive characters reliably at the MCU with this kind of rate, HW flow control is being employed. While investigating some character loss I'm seeing in this scenario I noticed something odd: once the serial port buffer is sufficiently full for the RTS line to be raised, it remains in that state; the RTS line is raised after every character, like the serial port's HW buffer is never being emptied.

Looking at the code from UARTSerial() down:

  • UARTSerial::rx_irq() calls SerialBase::_base_getc() in a loop while SerialBase::readable() is true.
  • ST's serial_readable() (in targets/TARGET_STM/serial_api.c) just checks for the flag UART_FLAG_RXNE being set for the UART.
  • However, the interrupt handler (uart_irq() in targets/TARGET_STM/TARGET_STM32F4/serial_device.c) clears the UART_FLAG_RXNE flag.

So if the interrupt has gone off and flow control has stopped any more characters being received, the flag will not be set and UARTSerial::rx_irq() won't go around its loop at all, which would lead to the buffer never being emptied. I think...?

Aside from the fact that this would be inefficient, I wonder if it might be implicated in the character loss I'm seeing.

Steps to reproduce
Run serial port via UARTSerial class (e.g. the new Cellular API) on STM part at a data rate high enough that the interrupt can't be serviced within the usual interrupt latency (e.g. 460800 bits/s) and watch how quickly RTS is raised once a few 10's of characters have been received.

cc: @kjbracey-arm , @hasnainvirk , @adustm , @LMESTM , @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