FelipeMdeO opened a new pull request, #20225:
URL: https://github.com/apache/nuttx/pull/20225
## Summary
`esp_pmstandby()` (`arch/xtensa/src/common/espressif/esp_pm.c` and the
RISC-V counterpart `arch/risc-v/src/common/espressif/esp_pm.c`) fed
`up_step_idletime()` the sleep duration it *asked for* (`time_in_us`)
rather than the one it actually got (`rtc_diff_us`), and did so
unconditionally.
`esp_pm_light_sleep_start()` already stalls and restores the systimer
itself, but only where `SOC_SLEEP_SYSTIMER_STALL_WORKAROUND` is defined
(esp32c3, esp32p4). On every other SoC — esp32s3 included — the systimer
keeps counting straight through light sleep, so the elapsed time is
already in the clock, and stepping it again with `up_step_idletime()`
adds it a second time.
Measured on an esp32s3-xiao: over 54 min with 1919 light sleeps totalling
454.7 s, the monotonic clock ran 443.2 s fast — almost exactly the time
slept, double-counted, for a clock running 13.8% fast. Any application
that reconstructs wall time from `CLOCK_MONOTONIC` inherits that error;
for this project it corrupted every IMU sample timestamp.
Fix: use the measured `rtc_diff_us`, and on the xtensa side gate the
`up_step_idletime()` call on `SOC_SLEEP_SYSTIMER_STALL_WORKAROUND` so it
only runs where the systimer genuinely stalls.
Note for reviewers: the RISC-V copy in this PR only switches to the
measured duration and does not add the `SOC_SLEEP_SYSTIMER_STALL_WORKAROUND`
gate — left asymmetric on purpose since I have no RISC-V espressif
hardware to validate that gate against, rather than silently deciding it
for a chip I haven't tested. Happy to add it if a maintainer confirms it
should match.
## Impact
* Is new feature added? No — pure bug fix.
* Is existing feature changed? No behavior change on esp32c3/esp32p4
(unaffected — they already had the correct gate on the sleep-start side,
this only fixes which value is fed to `up_step_idletime()`). On esp32s3
and other SoCs without the stall workaround, corrects a clock that was
running fast in proportion to time spent asleep.
* Impact on hardware? Every espressif board using `CONFIG_PM` +
`CONFIG_SCHED_TICKLESS` with light sleep actually reached — invisible on
a board that never sleeps.
## Testing
I confirm that changes are verified on local setup and works as intended:
* Build Host: Ubuntu 24.04, x86_64, `xtensa-esp-elf-gcc`.
* Target: Xtensa, Seeed XIAO ESP32-S3 (esp32s3-xiao), `CONFIG_PM=y` +
`CONFIG_SCHED_TICKLESS=y`.
Before the fix, 54 min / 1919 sleeps / 454.7 s slept: monotonic clock read
443.2 s ahead of wall time (13.8% fast). After the fix, corroborated
across the same 12 h 25 production run cited in the companion PR
("esp32s3: unwedge the PM state machine after the first wakeup") — this
fix depends on that one to be reproducible at all, since a board that
never really sleeps never steps the clock.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]