-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
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()
callsSerialBase::_base_getc()
in a loop whileSerialBase::readable()
istrue
.- ST's
serial_readable()
(intargets/TARGET_STM/serial_api.c
) just checks for the flagUART_FLAG_RXNE
being set for the UART. - However, the interrupt handler (
uart_irq()
intargets/TARGET_STM/TARGET_STM32F4/serial_device.c
) clears theUART_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