Skip to the content.
« Previous Index Next »

Firmware Coding Standard — Task Design & Scheduling (FreeRTOS)

1) Purpose

Define enforceable rules for designing tasks, assigning priorities, and scheduling work so that timing is deterministic and failures are visible early.


2) Principles


3) Task Lifecycle Rules

  1. Creation

    • Use xTaskCreateStatic() (see Static Allocation standard).
    • Name required and descriptive: task_sensor_reader, task_comm_tx.
    • Creation happens during system init only.
  2. Startup & Warm-up

    • Tasks must validate dependencies (drivers ready, queues created) before entering steady state.
    • Log readiness (single line at INFO).
  3. Shutdown

    • Support a cancel/stop signal (notification bit or event flag).
    • Drain/flush with bounded timeout; log on forced termination.

4) Priority & Scheduling Policy


5) Periodic Work

Template

static void task_comm_tick(void *arg)
{
    const TickType_t period = pdMS_TO_TICKS(5);
    TickType_t next = xTaskGetTickCount();

    for (;;) {
        next += period;
        do_comm_iteration();  // bounded; no blocking on mutexes here
        vTaskDelayUntil(&next, period);
    }
}

6) Blocking & Timeouts


7) Stack Sizing & Telemetry


8) CPU Load, Jitter & Latency


9) Communication & Ownership


10) Error Paths


11) Anti-Patterns (Do Not Do)


12) Review Checklist (Scheduling)


13) CI/Lint Gates


14) Helper Patterns

Cooperative chunking for heavy work

while (work_left() && (ticks_elapsed(start) < budget_ticks)) {
    do_small_unit();
}
// If not finished, notify self/worker queue to continue next slice.

Watchdog-friendly heartbeat

// Call at the end of each successful period or after N iterations
watchdog_kick();

« Previous Index Next »