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

[gen4] prebootloader: fix STOP/ULP sleep with disabled rtos, get correct wake-up reason #2825

Merged
merged 1 commit into from
Sep 4, 2024

Conversation

avtolstoy
Copy link
Member

@avtolstoy avtolstoy commented Sep 3, 2024

Problem

IPC communications are currently broken with KM0 after 1 STOP/ULP sleep cycle when WiFi interface is not initialized and thus KM0 RTOS and WiFi firmware are not initialized.

Solution

taskENTER_CRITICAL() and taskEXIT_CRITICAL() should only be used if RTOS has been started.

This PR also improves RTC wake-up reason detection.

Steps to Test

Run the test app below with both WiFi.on() in setup() and without it. Wake-up reason should be correct, sleep time should be correct too in both cases through multiple sleep cycles.

Example App

#include "application.h"

SerialLogHandler dbg1(LOG_LEVEL_ALL);
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
    // IMPORTANT: Run with WiFi.on() below and without it, should work in either case correctly.
    // WiFi.on();
    delay(1000);
}

SystemSleepResult result;
system_tick_t start = 0, end = 0;

void loop() {
    waitUntil(Serial.isConnected);
    delay(1000);
    Log.info("Start sleep test slept=%u result=%d", end - start, (int)result.wakeupReason());

    SystemSleepConfiguration config;

    config.mode(SystemSleepMode::ULTRA_LOW_POWER)
        .gpio(A7, FALLING)
        .duration(30s);

    Log.info("going to ULP");
    delay(10);

    start = millis();
    result = System.sleep(config);
    end = millis();
}

References

N/A


Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

@avtolstoy avtolstoy added the bug label Sep 3, 2024
@avtolstoy avtolstoy added this to the 5.9.0 milestone Sep 3, 2024
@@ -327,13 +331,22 @@ void sleepProcess(void) {
auto config = sleepConfigShadow.config();
if (config->mode == HAL_SLEEP_MODE_HIBERNATE) {
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
taskENTER_CRITICAL();
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
Copy link
Member

Choose a reason for hiding this comment

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

Just wondering why this matters. Is it the root cause of the sleep duration being incorrect?

Copy link
Member Author

Choose a reason for hiding this comment

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

In non-RTOS mode (when WiFi firmware is not initialized) this will disable interrupts and we'll no longer wake up KM0 on IPC interrupts. So 5 second 'sleep' was actually just a 5 second timeout waiting to get an IPC response.

@avtolstoy avtolstoy merged commit c380e88 into develop Sep 4, 2024
13 checks passed
@avtolstoy avtolstoy deleted the fix/gen4-prebootloader-sleep branch September 4, 2024 05:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants