Skip to content

The BufferedSerial class does not wait for end of transfer of the last byte in the unblocking mode. #14703

Open
@rkotan

Description

@rkotan

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:

  1. User should provide a delay before calling BufferedSerial::set_baud, especially on low baudrates (19200 bps and lower).
  2. 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 ?

  1. Set the serial rate to 9600 bps and mode to unblocking
  2. [Optional] Connect a device that supports 9600 bps and 115200 bps speeds. The Ublox NEO-M8N, for example.
  3. Try to change baudrate from 9600 bps to 115200 bps with BufferedSerial::set_baud function immediately after sending command to the device (calling BufferedSerial::write). In most cases the last command byte will be broken.

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