Async UART; FIFO buffer; buffer length de-synced

Hi folks,

I'm having some UART trouble - help would be much appreciated, and thank you in advance.

------------------------

Overview:

I'm working on a project that sends a few kilobytes of configuration data back and forth over BLE. To this end, I've been working with the peripheral_uart sample, but I began to encounter a strange issue that ended with the uart rx event length not matching the number of characters added to the buffer.

I'm hoping to resolve this so that I can use the UART API to transmit my data without corruption.

------------------------

My Environment:

OS = Windows 11

nRF Connect Toolchain = v2.5.0

Development Board = nRF52840 Dev Kit

------------------------

Project Specifics:

Description: My project (attached as zip) is a minimization of the peripheral_uart sample (nrf/samples/bluetooth/peripheral_uart) that removes the Bluetooth components, and replaces the Bluetooth Writing thread with a loop that just prints the messages to console (as opposed to sending over bluetooth)

Build Instructions: This project can be built by running the west build command located in /scripts/dk.sh, or by generating a build configuration that matches those specified there.

Error Reproduction Steps:

Build and Flash the application

Open Serial Monitor

Type string and terminate with tilde (~)

Sends which end in a partially-filled buffer result in a subsequent message not being processed correctly.

Example of Error:

Above, I run the application and feed it a 101 character test string (100, terminated with a ~)

The first time, 2 blocks of 40 bytes are followed quickly by a final block of 21

Sending the same message again causes concerning behavior -- one full minute goes by before the buffer is flushed.

Introspection:

Here's what I've learned so far.

There are two cases where things go wrong.

In one case, there's a strange one-minute delay between BUF_REQUEST and RDY

[Pictured above - "example of error"]

Adjusting various timeout parameters has no effect on the amount by which the print thread is delayed. I will mention, though won't screenshot, that in the peripheral UART, this delay was 50 seconds, not 60. I don't know why.

In the second case, the length of the buffer doesn't match the length of the entered string. (21 vs 19)

In this case (above), the terminator (~) isn't found, and we've entered the de-synced state I described in the title. buf->len is 2 chars shorter than was sent to UART

Bizarrely, my data output ends with an open parenthesis in this case (length desync), but does not in the other (1 minute delay)

------------------------

Behavior here is odd. It sometimes fixes itself and flushes the buffer once it gets data enough to find the terminating character with the buffers mismatched. In this case (pictured below), it under-counted by two, so inputting 1, 2, caused it to find everything, output, and print to console.

Sometimes, this error propagates and it only finds characters up to the terminator, kicking the error state to the NEXT buffer that gets released. (e.g. it would stop at the [00:06:18.421,875] timestamp, and leave the "1", "2" behind.

Closing:

I would be grateful for advice on how to remove these inconsistencies from my UART data send pipeline.

Please find attached (uart_async_test.zip - at end), which contains a script for building the project.

Thank you very much for any help you can provide!

Best,

    - Finn

uart_async_test.zip

Related