When to use:
When to use:
When NOT to use:

Screenshots taken with chip 33AK512MPS512
The idle task is implemented using a Simulink Function-Call Subsystem:
| Application | Description | Example Code |
|---|---|---|
| Power Saving | Enter low-power mode when idle | Idle(); (dsPIC) __WFI(); (ARM) |
| Watchdog Refresh | Service watchdog timer in idle loop | ClrWdt(); |
| Background Communication | Process non-critical messages | Parse low-priority UART data |
| Diagnostics | Monitor system health | Check stack usage, temperature |
| LED Blinking | Visual heartbeat indicator | Toggle status LED |
| Guideline | Reason | Example |
|---|---|---|
| Keep it short | Idle task should execute in <1ms to allow task scheduling | โ Increment counter โ Complex calculations |
| No blocking | While loops or delays will prevent task scheduling | โ State machine โ while(flag) wait(); |
| Use persistent variables | Maintain state across idle executions | persistent counter; |
| Avoid critical code | Idle task can be interrupted at any time | โ LED toggle โ Safety shutdown |
// Idle task execution frequency varies with system load
CPU Load | Idle Executions/sec | Use Case
---------|---------------------|----------
0% | ~millions/sec | Full idle utilization
50% | ~500k/sec | Moderate background work
90% | ~100k/sec | Limited idle time
>95% | Sporadic | Avoid complex idle operations
| Instruction | Mode | Power Savings | Wakeup Source |
|---|---|---|---|
| Idle() | CPU halted, peripherals run | ~50% | Any interrupt |
| Sleep() | CPU + peripherals halted | ~90% | External interrupt, WDT |
| Instruction | Mode | Power Savings | Wakeup Source |
|---|---|---|---|
| __WFI() | Wait For Interrupt | ~40% | Any interrupt |
| __WFE() | Wait For Event | ~40% | Event or interrupt |
// Idle Task Subsystem content
// Put CPU to sleep when idle - wakes on any interrupt
function IdleTask()
% dsPIC family
Idle(); % Enter idle mode (CPU stops, peripherals run)
% ARM Cortex-M (alternative)
% __WFI(); % Wait For Interrupt
end
% Power savings: ~50% reduction in idle current
% Wakeup latency: <10 instruction cycles
// Keep watchdog from resetting system
function IdleTask()
persistent counter;
if isempty(counter)
counter = 0;
end
% Service watchdog every Nth idle loop iteration
counter = counter + 1;
if counter >= 1000
ClrWdt(); % Clear watchdog timer
counter = 0;
end
end
// Process non-critical diagnostic messages
function IdleTask()
global DiagBuffer;
% Check if diagnostic data available
if ~isempty(DiagBuffer)
% Process one message per idle iteration
ProcessDiagnosticMessage(DiagBuffer(1));
DiagBuffer(1) = []; % Remove from queue
end
end
// Visual indication of system running
function IdleTask()
persistent ledCounter;
if isempty(ledCounter)
ledCounter = 0;
end
% Toggle LED every 500000 idle iterations (~1 Hz at typical load)
ledCounter = ledCounter + 1;
if ledCounter >= 500000
% Toggle status LED
LATB = xor(LATB, 0x0001);
ledCounter = 0;
end
end
| Problem | Cause | Solution |
|---|---|---|
| Idle task never executes | CPU always busy with scheduled tasks | Reduce task execution time or lower sample rates |
| System unresponsive | Blocking code in idle task (while loop, delay) | Remove blocking operations, use state machine |
| Watchdog reset | ClrWdt() not called frequently enough | Increase watchdog period or ensure idle executes more often |
| LED blink rate varies | Normal - idle frequency depends on CPU load | Use hardware timer if precise timing needed |