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

cpu/avr8_common: Add support to threadless idle #19741

Closed
wants to merge 1 commit into from

Conversation

nandojve
Copy link
Contributor

Contribution description

This attempts to introduces threadless idle support for AVR-8 platform.

Testing procedure

Local tests was conduct using timer_periodic_wakeup example on a atmega328p-xplained-mini board (m328p).

Original Code
   text	   data	    bss	    dec	    hex
   9814	    126	   1015	  10955	   2acb

With this proposal
   text	   data	    bss	    dec	    hex
   9898	    120	    823	  10841	   2a59

Triggered by #19740

@github-actions github-actions bot added Area: cpu Area: CPU/MCU ports Area: Kconfig Area: Kconfig integration Platform: AVR Platform: This PR/issue effects AVR-based platforms labels Jun 18, 2023
@hugueslarrive
Copy link
Contributor

With this proposal, it fits in the 1KB SRAM of the atmega8

@nandojve
Copy link
Contributor Author

With this proposal, it fits in the 1KB SRAM of the atmega8

Nice! Thank you for feedback.

@nandojve nandojve force-pushed the avr8/add_threadlessidle branch from 6c6063e to c30abf1 Compare June 19, 2023 18:43
AVR platform has few memory in general and each byte saved is precious.
This add support to drop necessity of idle thread which saves hundreds
of SRAM bytes. After this patch is possible to run RIOT-OS on AVR with
1k SRAM.

Signed-off-by: Gerson Fernando Budke <[email protected]>
@nandojve nandojve force-pushed the avr8/add_threadlessidle branch from c30abf1 to 3e207a4 Compare June 19, 2023 18:59
@nandojve nandojve marked this pull request as ready for review June 19, 2023 18:59
@maribu maribu added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jun 19, 2023
@riot-ci
Copy link

riot-ci commented Jun 19, 2023

Murdock results

✔️ PASSED

3e207a4 cpu/avr8_common: Add support to threadless idle

Success Failures Total Runtime
6934 0 6934 11m:34s

Artifacts

@maribu
Copy link
Member

maribu commented Jun 19, 2023

Sadly, this causes a number of regressions. See https://github.com/maribu/riot-test-results/blob/main/pr-19741/arduino-mega2560/failuresummary.md

Note: Some of the test failures are also present in master. https://github.com/maribu/riot-test-results/blob/main/master-2023-01-10-05caaafc3c68776db96afe08c2f8319d482a710c/arduino-mega2560/failuresummary.md is my most recent run of all tests on AVR on master. There might be some new regressions that were merged since, but e.g. tests/core/thread_flags does indeed work with master while it fails here.

Guessing from the shell output I think it might roughly be three causes of issues:

  1. lost IRQs while idling (e.g. tests/core/thread_flags
  2. entering sleep mode while a peripheral is still busy (e.g. tests/sys/sema_inv); it looks like the UART is stopped while idling and keeps sending breaks to me
  3. stack overflows (e.g. tests/core/thread_flags_xtimer)

The stack overflow is quite plausible: The call to sched_arch_idle() may happen when the thread stack is already almost exhausted. Before (without call to sched_arch_idle()) it might have been just enough to still handle an IRQ (or it may not, but due to luck IRQs didn't happen exactly when the worst case situation was reached). Now, the IRQ comes in when the worst case situation + the context and return address prior to the call of sched_arch_idle() have been pushed to stack.

The issue with AVR not having a dedicated IRQ stack and IRQs victimizing the stack of whatever thread is running when the IRQ is triggered is quite a pain in the ass.

@nandojve
Copy link
Contributor Author

Sadly, this causes a number of regressions. See https://github.com/maribu/riot-test-results/blob/main/pr-19741/arduino-mega2560/failuresummary.md

Note: Some of the test failures are also present in master. https://github.com/maribu/riot-test-results/blob/main/master-2023-01-10-05caaafc3c68776db96afe08c2f8319d482a710c/arduino-mega2560/failuresummary.md is my most recent run of all tests on AVR on master. There might be some new regressions that were merged since, but e.g. tests/core/thread_flags does indeed work with master while it fails here.

Guessing from the shell output I think it might roughly be three causes of issues:

  1. lost IRQs while idling (e.g. tests/core/thread_flags
  2. entering sleep mode while a peripheral is still busy (e.g. tests/sys/sema_inv); it looks like the UART is stopped while idling and keeps sending breaks to me
  3. stack overflows (e.g. tests/core/thread_flags_xtimer)

The stack overflow is quite plausible: The call to sched_arch_idle() may happen when the thread stack is already almost exhausted. Before (without call to sched_arch_idle()) it might have been just enough to still handle an IRQ (or it may not, but due to luck IRQs didn't happen exactly when the worst case situation was reached). Now, the IRQ comes in when the worst case situation + the context and return address prior to the call of sched_arch_idle() have been pushed to stack.

The issue with AVR not having a dedicated IRQ stack and IRQs victimizing the stack of whatever thread is running when the IRQ is triggered is quite a pain in the ass.

I realize that is not possible merge this at current state of cpu context switch. I think it will be necessary implement the stack for ISR and maybe more. In this proposal it was necessary re-enable the global interrupt inside context switch because of wake from sleep. However. I believe this could create serious issues because there is no valid context.

For reference: This is one point that cpu call sched_run():

avr8_context_save();
sched_run();
avr8_context_restore();

This is the place that sched_arch_idle() is called:

RIOT/core/sched.c

Lines 158 to 160 in 561e193

do {
sched_arch_idle();
} while (!runqueue_bitcache);

This proposal introduces:

void sched_arch_idle(void)
{
...
+    sei();
...}

In the case above assumption is correct I'll keep this PR on hold for the moment.

@nandojve
Copy link
Contributor Author

I think this won't be necessary after new IRQ handling. The PM from XMega can be moved to avr_common and shared between all SoC variants, initially. Maybe a mechanism will be necessary for Mega to define what Sleep Modes will be available by SoC.

@nandojve nandojve closed this Jun 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports Area: Kconfig Area: Kconfig integration CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: AVR Platform: This PR/issue effects AVR-based platforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants