pub async fn device_runner<RK, DLY, M, const RX: usize, const TX: usize>(
lora: LoRa<RK, DLY>,
ch: &'static Channels<M, RX, TX>,
ctl: &'static DeviceControl<M>,
rx_preamble: u16,
tx_preamble: u16,
rx_strategy: RxStrategy,
stats: Option<&'static StatsLedger>,
) -> !Expand description
Device variant of runner: same RX/TX state machine, but the
modulation parameters, frequency, and power come from an
DeviceControl at runtime instead of being fixed at spawn.
The radio starts idle (in standby) until the first enabled settings
arrive. While disabled, TX requests stay queued — the ULCP session
rejects transmits with STATUS_INVALID_STATE before they reach
this queue, so nothing accumulates in practice.
rx_strategy picks how the radio listens between frames; the
duty-cycle windows are recomputed from each new set of modulation
settings (see duty_cycle_rx_mode).
Cancellation-safety analysis is identical to runner: only
wait_for_irq and the two channel/signal waits are cancelled by the
select; IRQ processing and TX always run to completion.