核心区别在于:裸机delay是忙等待(占用CPU空转),而FreeRTOS的vTaskDelay会让出CPU,将当前任务挂起,调度器切换到其他就绪任务。
实操建议:
1. **裸机delay**:适用于极短延时(微秒级)或对时序要求苛刻的场景,如I2C时序、传感器读取。实现常用SysTick或DWT计数器,代码如:
```c
void delay_us(uint32_t us) {
uint32_t start = DWT->CYCCNT;
while ((DWT->CYCCNT - start) < (us * (SystemCoreClock/1000000)));
}
```
2. **vTaskDelay**:用于任务级延时(毫秒级及以上),它基于tick中断,调用后任务进入阻塞态,不占CPU。但精度受tick周期影响(默认1ms),且若系统繁忙,唤醒时间可能滞后。
关键点:在FreeRTOS中,绝对禁止在任务里用裸机delay做长延时,否则会阻塞调度器,导致低优先级任务饿死。若需高精度短延时,可临时关调度器或使用硬件定时器。
最后,延时选择取决于场景:实时性要求高且时间短用裸机,任务间协调用vTaskDelay,周期性任务建议用vTaskDelayUntil保证固定频率。
mcuku 阿沐 · 2026-08-17