-
Notifications
You must be signed in to change notification settings - Fork 6.5k
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
UART RTT devicetree & async support #27704
UART RTT devicetree & async support #27704
Conversation
What is the real benefit of this? RTT is not a hardware device, it is purely software. |
The benefit is that it allows the use of RTT in chosen and alias nodes. As a more concrete example, I have a binary data logging system built on top of serial ports, and boards that use both UART and RTT as the primary serial comms output. This change lets me do
Instead of trying to detect somehow if this particular board uses serial or RTT. |
drivers/serial/uart_rtt.c
Outdated
ARG_UNUSED(timeout); | ||
|
||
/* Output the buffer */ | ||
SEGGER_RTT_Write(ch, buf, len); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SEGGER_RTT_Write
is taking a lock (mutex in case of zephyr). This can limit places where this driver can be used.
Does Zephyr allow calling uart_tx from atomic context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect that its not defined, and probably won't be until #18970 is resolved.
The nrfx and sam0 drivers are the only ones that currently implement UART_ASYNC_API
.
They both look like they will work/return -EBUSY
with interrupts disabled.
I will update to manually take the lock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a bad idea but it will cover only cases when uart_tx is called from under irq_lock. It won't cover the case when it is called from an interrupt (mutex cannot be taken from an interrupt).
Maybe it would be enough to leave SEGGER_RTT_Write
and add a check blocking usage from atomic context?
there is no is_atomic api in Zephyr but check can be done as
int key = irq_lock();
irq_unlock(key);
bool is_atomic = arch_irq_unlocked(key) || k_is_in_isr();
if (is_atomic) return -ENOTSUP;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not fail when IRQ's are locked if the mutex take would still succeed.
Is adding the following sufficient?
if (k_in_in_isr()) {
return -ENOTSUP;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's ok. But I strongly suggest adding a check against calling from an interrupt. If anybody does it at least problem will be visible and explicit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this setup cover the cases?
If in ISR the k_in_in_isr
will fail.
If interrupts are locked in a thread the TX will pass if mutex is free, fail if it is in use.
Otherwise it will pass.
Is there some other situation I'm missing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's fine :)
I would still like a discussion on if this really is the right solution here. I often find myself enabling the RTT console as a pure software configuration change while debugging. It would be quite bothersome to have to edit the devicetree for this to work. Is there any way we could support both methods? After all, this is pure software functionality. |
My understanding is that changes to the uart_rtt driver are completely independent of the RTT console. |
@galak @carlescufi any chance of another review, hoping to get this into 2.4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is a zephyr policy that code must be somehow validated in the tree (compiled). Is it used somewhere?
Instantiate RTT UART instances from devicetree nodes instead of from Kconfig symbols. While RTT is implemented using software, not hardware, it is emulating a hardware device, and thus should be configured through devicetree. This allows the simulated UART device to be selected via devicetree aliases and chosen nodes. The following devicetree snippet will instantiate RTT channels 0 and 2 as UART devices. ``` / { rtt0: rtt_terminal { compatible = "segger,rtt-uart"; label = "rtt_terminal"; status = "okay"; }; rtt2: rtt_secondary { compatible = "segger,rtt-uart"; label = "rtt_app_specific"; status = "okay"; }; }; ``` Fixes the RTT portion of #10621. Signed-off-by: Jordan Yates <[email protected]>
Add support for `CONFIG_UART_ASYNC_API` to the uart_rtt driver. As RTT provides no mechanism for knowing when new data has arrived, the reception commands all return errors. This fixes hard faults when asynchronous calls are made on the uart_rtt driver, in addition to providing a small level of functionality. Signed-off-by: Jordan Yates <[email protected]>
uart_rtt was previously not used anywhere in tree. I can whip up a sample application. |
@nordic-krch Pretty sure the testcase I added will compile for the 'qemu_cortex_m0' platform at least. (It does locally for me) |
don't you need overlay which will configure uart rtt? |
Thats the |
Add a build only test to validate correct compilation of the uart_rtt driver. No harness that connects to RTT is defined, and therefore the test can't be run by CI. Signed-off-by: Jordan Yates <[email protected]>
somehow i missed that. |
Populate the `channel` index when constructing configuration structs for secondary RTT channels. Originally missed in #27704. Fixes #54955. Signed-off-by: Jordan Yates <[email protected]>
Populate the `channel` index when constructing configuration structs for secondary RTT channels. Originally missed in zephyrproject-rtos#27704. Fixes zephyrproject-rtos#54955. Signed-off-by: Jordan Yates <[email protected]>
Switches instantiation of the
uart_rtt
driver from Kconfig symbols to devicetree nodes.Adds
CONFIG_UART_ASYNC_API
support to the driver, which eliminates hard faults when the RTT backend is used with async functions. Because asynchronous reception is not possible, only the TX path is implemented.There are no in tree users of the previous
CONFIG_UART_RTT_*
symbols, so there are no tests validating the new behavior. The commit message contains an example of the devicetree nodes required to instantiate driver instances.