Description
Description of defect
The BufferedSerial class (and the underlying API) does not wait for end of transfer of the last character in the unblocking mode.
The BufferedSerial::write
method and underlying BufferedSerial::tx_irq
callback does not provide any delay after completing the transmission and for the blocking mode the 1 ms delay is provided with the following comment "Should we have a proper wait?". This causes problems in certain cases. For example, the Ublox NEO-M8N sends acknowledgment of baudrate change at the new speed. So, if we need to verify baudrate change by listening to the answer on new speed to appropriate command, we need to set desired speed immediately after calling BufferedSerial::write
because the timeout between request and acknowledgment is usually unknown. The BufferedSerial class uses the set_baud
method to change the baudrate and this method in the end performs the complete reinitialization of serial instance by calling init_uart
routine. In this way, if BufferedSerial::set_baud
is called immediately after BufferedSerial::write
, the last transmitted byte will be broken because of the complete reset of serial periphery before the end of transmission.
This is valid for STM32 targets, but others may also be affected.
Possible workarounds:
- User should provide a delay before calling
BufferedSerial::set_baud
, especially on low baudrates (19200 bps and lower). - The transmission should wait for setting the TC flag on STM32 targets (and do something similar on others)
I can provide a fix, but only for STM32 targets. Others will have emtpy stub in the serial_api.c
Target(s) affected by this defect ?
STM32
Toolchain(s) (name and version) displaying this defect ?
gcc version 10.2.1 20201103 (release)
What version of Mbed-os are you using (tag or sha) ?
mbed-os-6.11.0
What version(s) of tools are you using. List all that apply (E.g. mbed-cli)
mbed-cli 1.10.5
How is this defect reproduced ?
- Set the serial rate to 9600 bps and mode to unblocking
- [Optional] Connect a device that supports 9600 bps and 115200 bps speeds. The Ublox NEO-M8N, for example.
- Try to change baudrate from 9600 bps to 115200 bps with
BufferedSerial::set_baud
function immediately after sending command to the device (callingBufferedSerial::write
). In most cases the last command byte will be broken.