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

UART RTT devicetree & async support #27704

Merged
merged 3 commits into from
Sep 3, 2020
Merged

UART RTT devicetree & async support #27704

merged 3 commits into from
Sep 3, 2020

Conversation

JordanYates
Copy link
Collaborator

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.

@github-actions github-actions bot added area: Devicetree area: Devicetree Binding PR modifies or adds a Device Tree binding labels Aug 21, 2020
@henrikbrixandersen
Copy link
Member

What is the real benefit of this? RTT is not a hardware device, it is purely software.

@JordanYates
Copy link
Collaborator Author

JordanYates commented Aug 21, 2020

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.
I agree that the implementation is pure software, but it is pretending to be a hardware device, and therefore is seems reasonable (to me at least) to specify in devicetree.

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

MY_SERIAL_LOGGER_INIT(DT_LABEL(DT_ALIAS(logger_backend)))

Instead of trying to detect somehow if this particular board uses serial or RTT.

drivers/serial/uart_rtt.c Show resolved Hide resolved
drivers/serial/uart_rtt.c Outdated Show resolved Hide resolved
ARG_UNUSED(timeout);

/* Output the buffer */
SEGGER_RTT_Write(ch, buf, len);
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated

Copy link
Collaborator

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;

Copy link
Collaborator Author

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;
}

Copy link
Collaborator

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.

Copy link
Collaborator Author

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?

Copy link
Collaborator

Choose a reason for hiding this comment

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

No, it's fine :)

@henrikbrixandersen
Copy link
Member

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.

@JordanYates
Copy link
Collaborator Author

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. log_backend_rtt.c calls the SEGGER functions directly, as does the char_out function provided to printk in rtt_console.c. This PR therefore shouldn't change anything about enabling RTT for debug.

@JordanYates
Copy link
Collaborator Author

JordanYates commented Sep 2, 2020

@galak @carlescufi any chance of another review, hoping to get this into 2.4
Actually, merge conflicts from device updates, will fix.

Copy link
Contributor

@nordic-krch nordic-krch left a 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?

drivers/serial/uart_rtt.c Show resolved Hide resolved
Jordan Yates added 2 commits September 3, 2020 18:22
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]>
@JordanYates
Copy link
Collaborator Author

I think there is a zephyr policy that code must be somehow validated in the tree (compiled). Is it used somewhere?

uart_rtt was previously not used anywhere in tree. I can whip up a sample application.

@github-actions github-actions bot added the area: Tests Issues related to a particular existing or missing test label Sep 3, 2020
@JordanYates
Copy link
Collaborator Author

JordanYates commented Sep 3, 2020

I think there is a zephyr policy that code must be somehow validated in the tree (compiled). Is it used somewhere?

@nordic-krch Pretty sure the testcase I added will compile for the 'qemu_cortex_m0' platform at least. (It does locally for me)

@nordic-krch
Copy link
Contributor

don't you need overlay which will configure uart rtt?

@JordanYates
Copy link
Collaborator Author

JordanYates commented Sep 3, 2020

don't you need overlay which will configure uart rtt?

Thats the segger_rtt.overlay

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]>
@nordic-krch
Copy link
Contributor

Thats the segger_rtt.overlay

somehow i missed that.

@carlescufi carlescufi merged commit c4d0c1e into zephyrproject-rtos:master Sep 3, 2020
@JordanYates JordanYates deleted the uart_rtt_async branch September 4, 2020 07:12
nashif pushed a commit that referenced this pull request Feb 25, 2023
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]>
nordicjm pushed a commit to nordicjm/zephyr that referenced this pull request Mar 8, 2023
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Devicetree Binding PR modifies or adds a Device Tree binding area: Devicetree area: Tests Issues related to a particular existing or missing test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants