Idle Task Characteristics: - Lowest priority - Preempted by any scheduled task or interrupt - Non-deterministic timing - Execution time varies with CPU load - Continuous loop - Runs whenever CPU is idle - Single instance - Only one idle task per model - Power management - Ideal location for sleep/idle instructions
Usage Scenarios
| 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 |
Block Configuration
The idle task is implemented using a Simulink Function-Call Subsystem:
- Add IdleTask block to your model
- Create Function-Call Subsystem and connect to idle task output
- Add background logic inside subsystem
- Keep execution fast - avoid blocking operations
Examples
Example 1: Power-Saving Idle Mode
// 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
Example 2: Watchdog Service
// 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
Example 3: Background Communication
// 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
Example 4: Heartbeat LED
// 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
Best Practices
| 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 |
CPU Load Impact
// 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
Power Management Integration
dsPIC Low-Power Modes
| Instruction | Mode | Power Savings | Wakeup Source |
|---|
| Idle() | CPU halted, peripherals run | ~50% | Any interrupt |
| Sleep() | CPU + peripherals halted | ~90% | External interrupt, WDT |
ARM Cortex-M Low-Power Modes
| Instruction | Mode | Power Savings | Wakeup Source |
|---|
| __WFI() | Wait For Interrupt | ~40% | Any interrupt |
| __WFE() | Wait For Event | ~40% | Event or interrupt |
Troubleshooting
| 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 |
See Also