Lazy loaded image
🪜 实时操作系统
原理篇05-添加空闲任务(实践2)
Words 788Read Time 2 min
2026-8-19
2026-8-19
🎯
本篇目标:让 CPU “永远有事干”。任务延时不能空转等,要把 CPU 让给别的任务;实在没任务了,就跑空闲任务。对应 stp_rtos 的 idle.cstp_thread_delay / stp_thread_sleep

一、忙等 vs 阻塞延时

裸机里延时是这么写的:
CPU 在这段时间里啥正事不干,纯烧。RTOS 的思路完全不同:延时 = 放弃 CPU
  • 任务调用延时 → 进入阻塞态,从就绪列表摘掉;
  • CPU 去跑别的就绪任务;
  • 延时到期 → 任务重新进就绪列表,等调度。
这就是阻塞延时:把“等待”变成“让出”,是 RTOS 榨干 CPU 的核心手段。

二、空闲任务:CPU 的兜底

如果所有任务都在延时,CPU 跑谁?答案是空闲任务——调度器启动时自动创建、优先级最低的那个任务。
空闲任务优先级是 STP_THREAD_PRIORITY_MAX-1(数值最大 = 优先级最低)。它做两件事:
  1. 兜底:保证就绪列表永远非空,调度器永远有线程可切;
  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 里没有“等”,只有“让出 + 被唤醒”。
上一篇
原理篇04-任务创建和切换(实践01)
下一篇
原理篇06-资源要用在刀刃上-任务调度和算法

Comments
Loading...