# K14 — Software timer and the timer daemon task ## Position - Series: FreeRTOS C++ - Lesson: L13, card K14 - Duration: 30 minutes - Policies: one-shot and periodic - Static timer/task storage; heap delta zero ## Outcome The student separates command queue acceptance from callback execution, observes timer-daemon context, measures one-shot and periodic timelines, and states the lifetime contract for a typed callback context. ## Lesson plan | Time | Mode | Evidence | | --- | --- | --- | | 0–5 | wrapper contract | non-copy, explicit start, typed context | | 5–10 | command queue | two starts accepted before scheduler, callbacks zero | | 10–15 | initial timeline | periodic ticks 2 and 4 | | 15–20 | reset/change | one-shot reset at 1 expires at 6; period 2→3 at 4 | | 20–25 | daemon proof | current handle/name and separate callback stack | | 25–30 | stop/lifetime | periodic tick 7, then inactive; no fourth callback | ## Acceptance - OneShotTimer and PeriodicTimer encode reload policy in the type; - wrapper is neither copyable nor movable and start is explicit; - xTimerCreateStatic uses caller-owned control blocks in .bss; - both start commands return accepted while callback snapshot is still zero; - reset/change/stop acceptance is recorded separately from execution; - periodic callback ticks are exactly 2, 4 and 7; - reset at tick 1 moves one-shot expiry to tick 6 and it becomes inactive; - callback runs on timer daemon handle/name and a separate stack; - stopping the periodic timer prevents a fourth callback; - heap before/after timer creation is identical and target exits with PASS. ## Main traps 1. A callback runs in the timer service task, not in an ISR. 2. pdPASS means the daemon queue accepted a command, not that it executed. 3. Blocking or long work in one callback delays every software timer. 4. Timer ID/context and StaticTimer_t storage must outlive pending work. 5. Destroying a wrapper cannot synchronously prove queued deletion completed.