tags: [source-summary] type: source source: "尚硅谷嵌入式技术之FreeRTOS实时操作系统 V1.0.3 — 第2章" author: "尚硅谷研究院" date: 2026-07-12 url: ""
来源:尚硅谷 FreeRTOS 教程第 2 章。覆盖:多任务处理、任务调度策略、任务状态、滴答定时器、上下文切换、空闲任务。
内核是操作系统的核心组件。多任务操作系统可以将复杂应用程序分割成一组更小、更易管理的任务。即使单核处理器一次只能执行一项任务,通过任务间快速切换也能制造并发执行的假象。
调度器决定在任何特定时间应执行哪个任务。FreeRTOS 默认使用 固定优先级的抢占式调度策略,对同等优先级的任务执行时间片轮询:
高优先级任务等待资源(延时或等待信号量等)而无法执行时,调度器会选择执行其他就绪的高优先级任务。
FreeRTOS 中共 4 种任务状态:
| 状态 | 说明 |
|---|---|
| 运行态(Running) | 任务实际执行中,单核下仅一个任务处于此状态 |
| 就绪态(Ready) | 任务可执行但尚未运行,因同/更高优先级任务正在运行 |
| 阻塞态(Blocked) | 任务等待延时或外部事件(主动行为) |
| 挂起态(Suspended) | 调用 vTaskSuspend() 进入,需 vTaskResume() 恢复(被动行为——任务被"踢出局") |
阻塞 vs 挂起的本质区别:阻塞是任务主动说"我等会儿再跑"(延时/等资源),调度器还认得它;挂起是任务被被动标记为"出局",调度器完全忽略它,直到被明确恢复。就像员工自己去茶水间接水(阻塞)vs 被领导叫去面壁(挂起)。
核心规则:只有就绪态可转为运行态。其他所有状态必须先进入就绪态。运行态不维护自己的链表——"运行是最终目标,不需要排队"。
每种状态对应一个任务状态列表:
pxReadyTasksLists[x](x 为优先级数值)pxDelayedTaskListxSuspendedTaskList实现细节:就绪列表本质是一个链表数组——每个优先级对应一个链表。一个 32 位位图变量记录哪些优先级有就绪任务(bit n = 1 表示优先级 n 有任务就绪)。调度器从最高 bit 向下搜索,找到第一个置 1 的 bit 即可。运行态不维护链表——"运行是最终目标,不需要排队"。
调度器总是在所有就绪列表中选择最高优先级的任务执行。
时间片提前结束:如果任务在时间片用完前就主动让出 CPU(调用
vTaskDelay()或等信号量),切换立即发生,不会浪费剩余的时间片。就像员工提前干完活,不会非要等下班才走。
FreeRTOS 通过滴答计数变量测量时间。定时器中断(RTOS 滴答中断)以严格时间精度增加滴答数。每次滴答增加时,内核检查是否需要解除阻塞或唤醒任务。
上下文包括处理器寄存器、堆栈等任务执行资源。任务被挂起时保存上下文到任务堆栈,恢复时从堆栈还原到处理器寄存器。
切换时机:
上下文切换在 PendSV ISR 中处理。PendSV 被设置为最低中断优先级,避免影响其他 ISR。通过将 ICSR 寄存器的 bit28(PendSV 挂起位)置 1 来触发 PendSV 中断。
调度器启动时自动创建空闲任务(最低优先级),确保始终有任务可运行。空闲任务负责释放被删除任务的内存。
桶的类比:空闲任务就像没人用坑位时在坑里放一个桶占位——有人来了把桶拿走。空闲任务就是那个"桶"。
异步删除:
vTaskDelete()只是打了一个"删除标记",内存空间要到空闲任务运行时才真正清理。就像有人说"回头再打扫",但真正打扫要等没人用时才进行。空闲任务的三个作用:① 确保始终有任务可运行 ② 清理已删除任务的内存 ③ 低功耗模式的入口。
后续章节:[[05-任务创建删除与挂起恢复]]、[[06-中断管理与时间管理]]