tests: Generalise rp2 timer test into a cross-port test.

Now all ports with machine.Timer except nrf support both hard and
soft callbacks, generalise tests/ports/rp2_machine_timer.py into
tests/extmod/machine_timer.py.

There is an existing machine_soft_timer.py which varies period= and
covers the nrf port but skips esp32/esp8266 because they don't support
software timers. In our new test, we try varying freq= instead of period=,
and cover esp32/esp8266 (with a fixed choice of hardware timer) but skip
nrf because it doesn't support hard= or freq=.

Add a check that the heap is locked (so allocation fails) in hard
callbacks and it is unlocked (so allocation succeeds) in soft callbacks,
to ensure we're getting the right kind of callback, not falling back to
the default.

Signed-off-by: Chris Webb <chris@arachsys.com>
This commit is contained in:
Chris Webb
2025-08-25 14:49:17 +01:00
committed by Damien George
parent 64fd2f5f36
commit ccc954256f
4 changed files with 64 additions and 36 deletions

View File

@@ -0,0 +1,48 @@
import sys
try:
from machine import Timer
from time import sleep_ms
except:
print("SKIP")
raise SystemExit
if sys.platform in ("esp32", "esp8266", "nrf"):
# Software timers aren't implemented on the esp32 and esp8266 ports.
# The nrf port doesn't support selection of hard and soft callbacks,
# and only allows Timer(period=N), not Timer(freq=N).
print("SKIP")
raise SystemExit
else:
timer_id = -1
# Test both hard and soft IRQ handlers and both one-shot and periodic
# timers. We adjust period in tests/extmod/machine_soft_timer.py, so try
# adjusting freq here instead. The heap should be locked in hard callbacks
# and unlocked in soft callbacks.
def callback(t):
print("callback", mode[1], kind[1], freq, end=" ")
try:
allocate = bytearray(1)
print("unlocked")
except MemoryError:
print("locked")
modes = [(Timer.ONE_SHOT, "one-shot"), (Timer.PERIODIC, "periodic")]
kinds = [(False, "soft"), (True, "hard")]
for mode in modes:
for kind in kinds:
for freq in 50, 25:
timer = Timer(
timer_id,
mode=mode[0],
freq=freq,
hard=kind[0],
callback=callback,
)
sleep_ms(90)
timer.deinit()

View File

@@ -0,0 +1,16 @@
callback one-shot soft 50 unlocked
callback one-shot soft 25 unlocked
callback one-shot hard 50 locked
callback one-shot hard 25 locked
callback periodic soft 50 unlocked
callback periodic soft 50 unlocked
callback periodic soft 50 unlocked
callback periodic soft 50 unlocked
callback periodic soft 25 unlocked
callback periodic soft 25 unlocked
callback periodic hard 50 locked
callback periodic hard 50 locked
callback periodic hard 50 locked
callback periodic hard 50 locked
callback periodic hard 25 locked
callback periodic hard 25 locked

View File

@@ -1,20 +0,0 @@
from machine import Timer
from time import sleep_ms
# Test the rp2-specific adjustable tick_hz and hard/soft IRQ handlers
# for both one-shot and periodic timers.
modes = {Timer.ONE_SHOT: "one-shot", Timer.PERIODIC: "periodic"}
kinds = {False: "soft", True: "hard"}
for mode in modes:
for hard in kinds:
for period in 2, 4:
timer = Timer(
mode=mode,
period=period,
hard=hard,
callback=lambda t: print("callback", modes[mode], kinds[hard], period),
)
sleep_ms(9)
timer.deinit()

View File

@@ -1,16 +0,0 @@
callback one-shot soft 2
callback one-shot soft 4
callback one-shot hard 2
callback one-shot hard 4
callback periodic soft 2
callback periodic soft 2
callback periodic soft 2
callback periodic soft 2
callback periodic soft 4
callback periodic soft 4
callback periodic hard 2
callback periodic hard 2
callback periodic hard 2
callback periodic hard 2
callback periodic hard 4
callback periodic hard 4