Skip to content

RP2040: Fix 64-bit uptime being wrapped as a 32-bit value whenever a timer event happens #38

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

Open
wants to merge 2 commits into
base: extrapatches-6.17.0
Choose a base branch
from

Conversation

nomis
Copy link

@nomis nomis commented May 19, 2025

Summary of changes

The RP2040 timer implementation is wrapping the 64-bit uptime as if it were a 32-bit value, which is unexpected and makes it impossible to use the 64-bit uptime correctly.

Convert 32-bit timestamps to 64-bit values and stop forcing the uptime to be wrapped.

Check for a timer target being missed because it's now in the past and use the correct API to force an immediate timer event in an interrupt context.

Fixes arduino/ArduinoCore-mbed#1063.

Impact of changes

Uptime as a 64-bit value is no longer wrapped as a 32-bit value when a timer event happens.

Uptime as a 32-bit value is not impacted and unaffected.

Migration actions required

Remove workarounds that may have been added because the 64-bit uptime has been wrapped.

Documentation

None


Pull request type

[x] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[x] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

nomis added 2 commits May 19, 2025 18:46
us_ticker_irq_handler() must only be called from interrupt context
There is only one user of this API, the mbed timer queue. It sets targets
a maximum of (2**32)//16*7 microseconds in the future. Assuming there are
no other timer events to be scheduled, after 3 instances of this at 5637s
uptime the 64-bit uptime gets wrapped.

Never modify the system uptime because that makes it unusable when the
64-bit uptime that should never wrap, unexpectedly does. With the uptime
proceeding as normal into large 64-bit values the 32-bit timestamp needs
special handling.

It's ambiguous what the 32-bit timestamp means because time advances while
the ticker functions are being called, so the 64-bit time could wrap
between calculating the next 32-bit timestamp and setting it as the target
time.

The only way to avoid this is to know for certain what the caller meant by
keeping track of the last 32-bit value that was read. This relies on there
only being caller but other mbed timer implementations already keep track
of the last call to us_ticker_read() to handle ambiguity in timestamp
values.

Track the last read of the full 64-bit time too, so that we can always
prepare the correct 64-bit time value. Avoid reading the current time
repeatedly because it could change between calls.

If the timestamp is in the near future it's possible that it has been set
too late and the time has been missed. Force a timer interrupt when this
happens.
@CLAassistant
Copy link

CLAassistant commented May 19, 2025

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RP2040: us_ticker implementation causes system uptime to wrap sporadically after 2^32µs
2 participants