casaroli opened a new pull request, #19530:
URL: https://github.com/apache/nuttx/pull/19530
## Summary
The RP2350 has two independent system timer blocks (TIMER0, TIMER1), each a
free-running 64-bit microsecond counter clocked by the TICKS block (1 MHz)
and
independent of the ARM SysTick that drives the OS tick. Each block has four
independent alarms (ALARM0–3), each with its own compare register and IRQ.
The port had no driver for these blocks. This PR adds two features built on
them and makes them share the hardware cleanly.
**1. `/dev/timer` driver (`rp23xx_timer.c`)**
- A standard NuttX timer lower-half bound to a block; uses ALARM0 (matches
the
low 32 bits of the counter) for single-shot or periodic timeouts, 1 µs
resolution, up to 2³²−1 µs (~71.5 min) per interval.
- Periodic reloads are scheduled relative to the previous expiry (no drift),
never behind the counter (a past alarm would not match until the 32-bit
counter wraps).
- Enabled with `CONFIG_RP23XX_TIMER`; each block is toggled independently:
`CONFIG_RP23XX_TIMER0` → `/dev/timer0`, `CONFIG_RP23XX_TIMER1` →
`/dev/timer1`.
**2. Tickless OS (`rp23xx_oneshot.c`)**
- An `ONESHOT_COUNT` alarm/oneshot lower-half (mirrors
`arch/risc-v/src/common/riscv_mtimer.c`) that drives the tickless scheduler
through `up_alarm_set_lowerhalf()`. The 64-bit counter is the monotonic
time
base (`current()`); ALARM0 is the next-event compare.
- The one adaptation vs. a full 64-bit-compare timer: the ALARM registers
match
only the low 32 bits of the counter. `max_delay()` is capped below 2³²
counts
so the scheduler never asks for a longer interval, and any deadline already
due — or reached while the alarm is being armed — is forced immediately via
the INTF register instead of waiting a full 32-bit wrap.
- Enabled with `CONFIG_RP23XX_SYSTIMER_TICKLESS` (mutually exclusive with
`CONFIG_RP23XX_SYSTIMER_SYSTICK`); the block is selectable with
`CONFIG_RP23XX_SYSTIMER_TICKLESS_TIMER0` (default) / `_TIMER1`.
`ARCH_CHIP_RP23XX` now selects `ARCH_HAVE_TICKLESS`.
**Coexistence.** The block chosen for tickless is claimed exclusively by the
scheduler and is removed from the `/dev/timer` choices in Kconfig
(`RP23XX_TIMER0 depends on !RP23XX_SYSTIMER_TICKLESS_TIMER0`, and likewise
for
TIMER1), so the two features never collide on the same block or its alarm
IRQ.
Result:
- tickless disabled → both `/dev/timer0` and `/dev/timer1` available;
- tickless on TIMER0 → scheduler owns TIMER0, `/dev/timer1` available;
- tickless on TIMER1 → scheduler owns TIMER1, `/dev/timer0` available.
## Impact
- New feature, opt-in; no change to existing behavior when both options are
disabled. Default OS tick remains the ARM SysTick.
- Arch: `arm` (rp23xx / RP2350). Boards: rp23xx common bringup registers the
enabled `/dev/timerN` device(s).
- No new external dependencies. No ABI/API changes outside the new Kconfig
symbols and the new `/dev/timerN` device nodes.
## Testing
**Hardware:** RP2350 board (Pimoroni Pico Plus 2), `raspberrypi-pico-2:nsh`
configuration, programmed over SWD with a Raspberry Pi Debug Probe (probe-rs)
and driven from the `nsh` console on UART0 through the same probe's UART
bridge. Both timer blocks were exercised in **both roles**, and in each build
the two features ran **at the same time** on different blocks.
### Configuration A — tickless on TIMER0, `/dev/timer1` on TIMER1
`RP23XX_SYSTIMER_TICKLESS` + `SYSTIMER_TICKLESS_TIMER0` + `SCHED_TICKLESS` +
`SCHED_TICKLESS_ALARM` + `RP23XX_TIMER` + `RP23XX_TIMER1` + `EXAMPLES_TIMER`
with `CONFIG_EXAMPLES_TIMER_DEVNAME="/dev/timer1"`.
- Boots to `nsh`.
- **Kconfig exclusion confirmed at runtime:** `ls /dev` lists `timer1` and
**not** `timer0` — the block the scheduler claimed is not offered as a
`/dev/timer` device.
- **`examples/timer` on `/dev/timer1` runs while tickless drives the
scheduler
from TIMER0** — this is the coexistence proof. `timeleft` counts down
smoothly within each 1 s interval and `nsignals` increments 0 → 1 → 2 as
the
ALARM0 matches are delivered to the user signal handler; the app stops the
timer and exits cleanly.
- **Timed wakeups** (`sleep N`, measured by when the prompt returns):
1 s → +0.014 s, 2 s → +0.061 s, 4 s → +0.053 s, 8 s → +0.063 s.
- **Clock rate:** board `uptime` advanced **123 s while the host wall clock
advanced 123.04 s** — −0.034 % over two minutes, within `uptime`'s 1 s
display quantization.
### Configuration B — tickless on TIMER1, `/dev/timer0` on TIMER0
The mirror image of A (`SYSTIMER_TICKLESS_TIMER1` + `RP23XX_TIMER0`,
`CONFIG_EXAMPLES_TIMER_DEVNAME="/dev/timer0"`), which exercises the
block-select
path for both features.
- Boots to `nsh`; `ls /dev` lists `timer0` and **not** `timer1`.
- `examples/timer` on `/dev/timer0` runs to completion with `nsignals`
incrementing, while tickless runs on TIMER1.
- **Timed wakeups:** 1 s → +0.055 s, 2 s → +0.043 s, 4 s → +0.059 s,
8 s → +0.061 s.
- **Clock rate:** `uptime` +123 s vs 123.02 s wall — −0.016 % over two
minutes.
The residual tens of milliseconds on `sleep` are shell/scheduler round-trip
overhead, not clock drift: the two-minute rate measurements bound the drift
at
well under 0.05 %.
### Build / config matrix (all clean)
| Configuration | Result |
|---|---|
| `RP23XX_TIMER` + `RP23XX_TIMER0` + `RP23XX_TIMER1` + `EXAMPLES_TIMER` |
builds & links |
| tickless on TIMER0 + `/dev/timer1` (config A above) | builds, links,
**HW-tested** |
| tickless on TIMER1 + `/dev/timer0` (config B above) | builds, links,
**HW-tested** |
- `tools/checkpatch.sh -f` (nxstyle) and `-g` (patches + commit messages):
clean on both commits.
- No Kconfig warnings; the forward references between the two features
degrade
to `n` when only one is present.
### Note on the console used
Testing used the UART0 console rather than `usbnsh`. On this board the
USB-CDC
console drops after a couple of commands; that is **independent of this PR**
—
a pristine `raspberrypi-pico-2:usbnsh` build with none of these options
enabled
was flashed as a control and behaved identically, which matches the existing
entry in the rp23xx documentation ("USB — Experimental — usbnsh configuration
is somewhat working with some data corruption"). Nothing in this PR touches
the
USB device driver.
--
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]