Skip to content

Comments

Convert PLUART to queue for sensor lines (#16)#361

Open
keenanjohnson wants to merge 2 commits intobristlemouth:developfrom
keenanjohnson:uart-q
Open

Convert PLUART to queue for sensor lines (#16)#361
keenanjohnson wants to merge 2 commits intobristlemouth:developfrom
keenanjohnson:uart-q

Conversation

@keenanjohnson
Copy link

What changed?

Implements queue-based line buffering for PLUART to prevent data loss when multiple lines arrive before being read.

How does it make Bristlemouth better?

Issue #16 raised by the devs seems to indicate a need and makes sense to me! As mentioned in the issue, many sensors issue multiple lines and this change seems to only make the project more robust to timing jitter without changing the user API.

Where should reviewers focus?

src/lib/common/payload_uart.cpp contains the important bits. I have added a set of basic unit tests as well.

Checklist

  • Add or update unit tests for changed code
  • Ensure all submodules up to date. If this PR relies on changes in submodules, merge those PRs first, then point this PR at/after the merge commit
  • Ensure code is formatted correctly with clang-format. If there are large formatting changes, they should happen in a separate whitespace-only commit on this PR after all approvals.

@keenanjohnson
Copy link
Author

Just ran across this project in open source and seems like a great effort! I've done a few ocean robotics projects in the past and always looking for ways to give back. I saw that this issue was open and seemed straightforward, but let me know if it's not helpful or I am headed in the wrong direction.

@towynlin
Copy link
Contributor

towynlin commented Nov 7, 2025

Thanks @keenanjohnson! Please work on fixing the CI failure, and we'll help with some hardware validation.

@keenanjohnson
Copy link
Author

Great! The latest push fixes the tests I think

@towynlin
Copy link
Contributor

Hey @keenanjohnson CI is still failing — you can see the ❌ next to the latest commit and the "All checks have failed" notice at the bottom fo the PR. Here's a screenshot of the build failure:
Screenshot 2025-11-18 at 4 31 35 PM

@matt001k matt001k self-requested a review November 20, 2025 23:16
Copy link
Contributor

@matt001k matt001k left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I like this change a lot!
I will give it a shot on actual hardware here soon (give me at most a week)!

_user_line.len = len;
_user_line.ready = true;
xSemaphoreGive(_user_line.mutex);
QueuedLine_t queued_line;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this may be a problem here. Every time a line ends we create a queue_line item, this struct has a buffer of 2048 bytes in it. Meaning, 2048+ bytes are allocated to the `serialGenericRxTask. Looking at that task the stack is currently 2048 words (32bit) wide which should be enough for this operation.

Note: I tested this on an application and it seems to be running ok.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also to note, this is not occurring from an ISR. We do not need the xQueueSendFromISR function here.
The xQueueSend function will also copy the above struct (queue_line) and heap allocate it. Meaning every time a line is created >4096 bytes of allocation happen (until queued_line goes out of scope).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend creating some memory pool that the queue items could point to.
There is a module I created exactly for something like this called q.c located in the bm_core submodule of this project (the submodule might have to be updated). This could be a good alternative as:

  • There is no max queue size, it is all dependent of how much memory in the pool has been used
  • Elements in the queue can be of different sizes
  • It is much faster in terms of operation than the FreeRTOS queue

The only downfall is:

  • It is not thread safe and will need mutex protection

Let me know your thoughts on that solution!

BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (xQueueSendFromISR(_line_queue, &queued_line, &xHigherPriorityTaskWoken) != pdTRUE) {
// Queue is full - increment dropped line counter
// Use assignment to avoid C++20 deprecated volatile increment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow did not know about this one... that is a crazy deprecation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants