本篇目标:让 CPU “永远有事干”。任务延时不能空转等,要把 CPU 让给别的任务;实在没任务了,就跑空闲任务。对应 stp_rtos 的
idle.c 与 stp_thread_delay / stp_thread_sleep。一、忙等 vs 阻塞延时
裸机里延时是这么写的:
CPU 在这段时间里啥正事不干,纯烧。RTOS 的思路完全不同:延时 = 放弃 CPU。
- 任务调用延时 → 进入阻塞态,从就绪列表摘掉;
- CPU 去跑别的就绪任务;
- 延时到期 → 任务重新进就绪列表,等调度。
这就是阻塞延时:把“等待”变成“让出”,是 RTOS 榨干 CPU 的核心手段。
二、空闲任务:CPU 的兜底
如果所有任务都在延时,CPU 跑谁?答案是空闲任务——调度器启动时自动创建、优先级最低的那个任务。
空闲任务优先级是
STP_THREAD_PRIORITY_MAX-1(数值最大 = 优先级最低)。它做两件事:- 兜底:保证就绪列表永远非空,调度器永远有线程可切;
- 计数/低功耗:
stp_idletask_counter++可统计 CPU 空闲率;实际产品里还能在空闲任务里进低功耗(tickless)。
三、阻塞延时的实现
3.1 入口:stp_thread_delay → stp_thread_sleep
关键点:延时不是“记一个数然后等”,而是挂起线程 + 启动一个一次性定时器。定时器到期后回调
_thread_timeout 把线程重新插回就绪列表。真实实现里,挂起 + 设置定时器 + 启动定时器这三步是在关中断的临界区里完成的(
stp_hw_interrupt_disable/enable 包住),防止中途被 tick 中断打断、把线程状态改坏。3.2 挂起:stp_thread_suspend
3.3 超时唤醒:_thread_timeout
3.4 时基:stp_tick_increase
SysTick 中断里只做这两件事,绝不直接做上下文切换——切换交给 PendSV,这是贯穿全系列的铁律。
四、小结
- 阻塞延时 = 挂起 + 定时器 + 让出 CPU;
- 空闲任务是优先级最低的兜底线程;
- 延时到期靠定时器回调唤醒,而不是在 tick 里遍历所有线程(FreeRTOS 的 delayed list 是另一种等价实现,原理篇11会对比)。
核心一句话:RTOS 里没有“等”,只有“让出 + 被唤醒”。
- Author:felixfixit
- URL:http://www.felixmicrospace.top/article/freeRTOS_idle_task_implementation
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!





