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

sys: make uart_stdio RX optional (attempt #2) #11310

Merged
merged 1 commit into from
May 9, 2019

Conversation

vincent-d
Copy link
Member

Contribution description

This is a rebase of #7974 that fixes conflicts. This allows to not block the low power mode if the shell is not used.

Issues/PRs references

#7974

@vincent-d vincent-d added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 29, 2019
@jcarrano
Copy link
Contributor

jcarrano commented Apr 1, 2019

If I understand this correctly, it is currently impossible to have UART RX compiled in and be able to go to low power mode, right? So if the user wants to use the RX functionality, he has no way to disable it at runtime to be able to go to sleep.

I'd rather not force the user into choosing either RX or low power. It is better to provide a run-time toggle for the RX function, or to bypass the low power block.

From #7947 I get that this is only a problem on chips that don't have a low power capable UART. In those chips, bypassing the mode blockage would mean that there is no input until the MCU wakes up again. In #7947 (comment) you describe a possible solution which I believe is a good one.

Also, I'm trying to find where in the RIOT code is the lpm block, but I cannot. Which CPUs have this limitation?

@kaspar030
Copy link
Contributor

If I understand this correctly, it is currently impossible to have UART RX compiled in and be able to go to low power mode, right?

Nope. On stm32, if an RX callback is configured and uart is initialized (and not powered off through uart_poweroff()), LPM is blocked such that RX still works.
The problem is that stdio_uart always initializes both RX and TX.

@kaspar030
Copy link
Contributor

Thanks @vincent-d for taking over!

Makefile.dep Outdated
@@ -396,8 +396,20 @@ ifneq (,$(filter stdio_rtt,$(USEMODULE)))
USEMODULE += xtimer
endif

ifneq (,$(filter stdio_uart,$(USEMODULE)))
ifneq (,$(filter shell,$(USEMODULE)))
USEMODULE += stdio_uart_rx
Copy link
Contributor

Choose a reason for hiding this comment

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

this'll not work with stdio_rtt

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe depend on an intermediate module like "stdio_input" and make that depend on stdio_uart_rx if stdio_uart is used?

Copy link
Member Author

Choose a reason for hiding this comment

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

just checked for stdio_uart being used, is it good enough?

Makefile.dep Outdated
USEMODULE += stdio_uart_rx
endif

ifneq (,$(filter rtt_stdio,$(USEMODULE)))
Copy link
Contributor

Choose a reason for hiding this comment

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

and this is unrelated?

Copy link
Member Author

Choose a reason for hiding this comment

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

rebase mess I guess ;)

@jcarrano
Copy link
Contributor

jcarrano commented Apr 1, 2019

On stm32, [...]

I'm not familiar with STM32, but googling around seems to indicate that it has the ability to be woken up from the UART. If that is the case then it is something that should be addressed by the periph implementation.

LPM is blocked such that RX still works.

Ok, but what happens if the block is ignored and the device sleeps? Does anything break? Will the RX work after it wakes up again?

If it is OK for a certain application to not have RX, then it does not matter if the answer is yer or no, and ignoring the blockage is enough to fix the issue (or, rather, work around the lack of low power uart in stm32).

If the answer is "yes" (meaning after wake up the RX is still working) then ignoring the blockage, in combination with something like what @vincent-d proposes in #7947 (comment) is good too.

In both cases, removing RX is a bit of an extreme measure.

@kaspar030
Copy link
Contributor

I'm not familiar with STM32, but googling around seems to indicate that it has the ability to be woken up from the UART. If that is the case then it is something that should be addressed by the periph implementation.

This usually loses the first byte, which may or may not be acceptable.

Ok, but what happens if the block is ignored and the device sleeps? Does anything break? Will the RX work after it wakes up again?

On stm32 (and most platforms I know), yes, unless the MCU sleeps too deep. On stm32, there's e.g., the standby mode, which would lose IO configuration and all RAM contents.

If it is OK for a certain application to not have RX, then it does not matter if the answer is yer or no, and ignoring the blockage is enough to fix the issue (or, rather, work around the lack of low power uart in stm32).

There's many ways to tackle this issue. As of now, if uart is initialized and powered with an RX callback, RX works, but blocks LPM. As long as we don't have a way to specify that losing bytes is acceptable, it should be that way.

"certain applications" should not initialize uart with RX enabled (e.g., they should not pass an rx callback).

This PR tackles the issue by making stdio RX optional, by not configuring it trough an RX callback.

More elaborate alternatives would make stdio RX sleep controllable. Maybe make it only active when someone is waiting in a read() call comes to mind.
IMO, until we have that functionality, making this a compile-time option makes sense. This is also nice for output-only applications that want to save the RX buffer.

@aabadie aabadie added the Area: pm Area: (Low) power management label Apr 11, 2019
@aabadie
Copy link
Contributor

aabadie commented Apr 11, 2019

@kaspar030 @jcarrano, I think this is in good shape and already provide an enhancement regarding power management, without the shell. I'm +1 for merging it. What's your opinion (e.g. do you ACK) ?

@kaspar030
Copy link
Contributor

What's your opinion (e.g. do you ACK) ?

Just gave it a last look. Unfortunately I just realized that as is I think it would break ethos if used with the same uart as stdio (e.g., on the border router or our suit examples).

@kaspar030
Copy link
Contributor

Please squash!

@kaspar030 kaspar030 added the CI: run tests If set, CI server will run tests on hardware for the labeled PR label Apr 11, 2019
@vincent-d vincent-d force-pushed the make_uart_stdio_rx_optional branch from 386c187 to 002057f Compare April 11, 2019 12:27
@vincent-d
Copy link
Member Author

Squashed

@kaspar030 kaspar030 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Apr 11, 2019
cb = (uart_rx_cb_t) isrpipe_write_one;
arg = &stdio_uart_isrpipe;
#else
#ifdef USE_ETHOS_FOR_STDIO
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if we could make stdio_uart_rx a dependency of ethos in the build system instead of preprocessor macros ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am not sure about this... @kaspar030 any opinion?

Copy link
Contributor

Choose a reason for hiding this comment

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

hm, ethos itself doesn't need stdio_uart_rx.
stdio-over-ethos should probably be a pseudomodule...

I guess as is this is fine for now.

@aabadie
Copy link
Contributor

aabadie commented May 9, 2019

@kaspar030, can you give a final review and eventually ACK this one ?

@kaspar030 kaspar030 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels May 9, 2019
@kaspar030 kaspar030 added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label May 9, 2019
Copy link
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

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

ACK.

@kaspar030 kaspar030 merged commit a9f1a85 into RIOT-OS:master May 9, 2019
@aabadie
Copy link
Contributor

aabadie commented May 9, 2019

Thanks @kaspar030 :)

jcarrano added a commit to jcarrano/RIOT that referenced this pull request May 28, 2019
…_rx_optional"

This change was breaking (dependencies for) ethos, shell, etc, as well as an unknown
number of external apps (API change.) See RIOT-OS#11525 for more details.

Fixes RIOT-OS#11525.
jcarrano added a commit to jcarrano/RIOT that referenced this pull request May 28, 2019
…ional"

This change was breaking (dependencies for) ethos, shell, etc, as well as an unknown
number of external apps (API change.) See RIOT-OS#11525 for more details.

Fixes RIOT-OS#11525.
jcarrano added a commit to jcarrano/RIOT that referenced this pull request May 28, 2019
…ional"

This change was breaking (dependencies for) ethos, and other serial users,
as well as an unknown number of external apps (API change.).
See RIOT-OS#11525 for more details.

Fixes RIOT-OS#11525.
@benemorius
Copy link
Member

I'm not familiar with STM32, but googling around seems to indicate that it has the ability to be woken up from the UART. If that is the case then it is something that should be addressed by the periph implementation.

This usually loses the first byte, which may or may not be acceptable.

Is that due to taking too long to wake up and clear the receive buffer or is it actually a documented hardware limitation? I don't think I've ever had to tolerate that problem on any platform, but it's possible I've avoided it by shortening the wakeup sequence.

I recall some time ago moving the main oscillator startup to a later point and making it conditional, but I don't remember if that was for the uart or just to avoid wasting power for xtimer overflow wakeups which come very frequently on EFM32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: pm Area: (Low) power management CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: run tests If set, CI server will run tests on hardware for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants