Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BufferedUart template and its specialisation for FreeRTOS queues #1156

Open
wants to merge 33 commits into
base: develop
Choose a base branch
from

Conversation

kapacuk
Copy link
Contributor

@kapacuk kapacuk commented Apr 19, 2024

As discussed in PR#1155, here is my attempt to create a wrapper around the UartHal driver which handles the buffering. Not sure if it's what you had in mind, I'm open to suggestions on how to improve it.

I kept the original buffering driver with minor tweaks and created a new templated class BufferedUart. It duplicates some code from the old driver, but I think that's a small price to pay for backward compatibility.

Copy link
Member

@salkinium salkinium left a comment

Choose a reason for hiding this comment

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

Very nice, I'm ok with breaking changes so don't hesitate to generalize the buffers even further.

txResult = {{ hal }}::TxCallback();

if( {{ hal }}::FinalCallback )
{{ hal }}::FinalCallback(rxResult || txResult);
Copy link
Member

Choose a reason for hiding this comment

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

Could we reduce these three callbacks to just a single callback?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My original idea was to allow using different buffer types for Rx and Tx. I can see now that it would be quite difficult to do it generically, given that FreeRTOS does not guarantee that the interrupt handler can do anything after calling portYIELD_FROM_ISR.

If we add the restriction that the Rx buffer must be of the same type as the Tx one, then of course a single callback would be enough. Would you be OK with such restriction?

Copy link
Member

Choose a reason for hiding this comment

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

Would you be OK with such restriction?

I think that's ok. I don't think it makes sense to mix want to have a TX buffer with a FreeRTOS Queue with a "polling" rx queue.

However, I would like to have the option to have a buffer only for one direction and zero-length buffers. For example, our board logger setup is output only, so it doesn't need a RX buffer at all. Similarly for some UART-based communication protocols like AMNB, it would be a software RX buffer of ≥32B and only the hardware TX buffer (aka software buffer of length 0).

src/modm/platform/uart/stm32/uart.hpp.in Outdated Show resolved Hide resolved
static inline modm::atomic::Queue<uint8_t, {{ options["buffer.rx"] }}> rxBuffer;
%% endif
%% if options["buffer.tx"]
static inline modm::atomic::Queue<uint8_t, {{ options["buffer.tx"] }}> txBuffer;
Copy link
Member

Choose a reason for hiding this comment

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

At this point I'd make this a templated class so that we can remove the buffer.* options. I'm ok with breaking changes here, this is a significant improvement.

Copy link
Member

Choose a reason for hiding this comment

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

Actually if we're gonna do breaking changes we can also deduplicate the common code as you initially intended.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I don't need to keep it backward-compatible then it becomes much easier. I'll remove the buffer.* options and will do it via another template specialisation which uses modm::atomic::Queue

Copy link
Member

@salkinium salkinium Apr 23, 2024

Choose a reason for hiding this comment

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

(I really dislike the buffer.* options, they are still from xpcc, modm's ancient predecessor library)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I deleted the buffer.* options (and the old Uart class), which obviously broke a lot of examples. I fixed the blue_pill_f103 examples, it was just a matter of adding

using Usart2 = BufferedUart<UsartHal2, PlainTxBuffer<256>>;

at the top of main.cpp. Before I go ahead and convert all other examples - are you happy with this?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, I think this is pretty awesome, very flexible and fullfills all requirements. The recursive callback chaining is also quite elegant.

src/modm/platform/uart/stm32/uart_hal.hpp.in Outdated Show resolved Hide resolved
src/modm/platform/uart/stm32/module.lb Outdated Show resolved Hide resolved
src/modm/platform/uart/stm32/freertos.hpp Outdated Show resolved Hide resolved
src/modm/platform/uart/stm32/freertos.hpp Outdated Show resolved Hide resolved
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/platform/uart/freertos_uart_buffer.hpp>
Copy link
Member

Choose a reason for hiding this comment

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

I think this is auto-included by <modm/platform.hpp>, which is included by <modm/board.hpp>

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it's not auto-included any more, since I moved it to ext/aws

ext/aws/module.lb Outdated Show resolved Hide resolved
static inline modm::atomic::Queue<uint8_t, {{ options["buffer.rx"] }}> rxBuffer;
%% endif
%% if options["buffer.tx"]
static inline modm::atomic::Queue<uint8_t, {{ options["buffer.tx"] }}> txBuffer;
Copy link
Member

@salkinium salkinium Apr 23, 2024

Choose a reason for hiding this comment

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

(I really dislike the buffer.* options, they are still from xpcc, modm's ancient predecessor library)

src/modm/platform/uart/stm32/uart_hal.hpp.in Show resolved Hide resolved
@kapacuk
Copy link
Contributor Author

kapacuk commented Apr 29, 2024

Sorry it took me so long, that was a bigger change than I expected.. I think I'm done, it's ready for a review.

@kapacuk kapacuk requested a review from salkinium April 29, 2024 21:39
@salkinium
Copy link
Member

Sorry it took me so long

No pressure! I'm very happy with this work, thank you for taking this on! I will review and test this in depth on the weekend.

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

Successfully merging this pull request may close these issues.

None yet

3 participants