# 第二批 FreeRTOS / RTOS 八股 · 复习总结(8 主题) > 使用说明:先自测「判别规则速查表」,遮住右列自答;再做「综合练习题」,最后对答案。 > 面试前只翻本目录,不背题。 --- ## 一、判别规则速查表(遮右自测) | # | 主题 | 一句话判别规则 | | --- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | | 24 | 任务状态机 | 在跑=**Running**;排队等 CPU=**Ready**;主动等事件/延时=**Blocked**(自动醒、有超时);被外部挂起=**Suspended**(手动醒、无超时) | | 25 | 抢占 vs 时间片 | **高优先级就绪→抢占**(跨级);**同优先级 tick 到点→时间片**;低优先级就绪→永不切换 | | 26 | 优先级反转 | **高等待 + 低持有 + 中插队**(三者齐)= 反转;解决=**互斥量**(优先级继承),别拿二值信号量当锁 | | 27 | 临界区 | 数据被**中断/硬件**碰→关中断(临界区);只被任务碰→互斥量/挂起调度器;临界区**禁阻塞、要短、多核只关本核** | | 28 | IPC 选型 | 数据→**队列**;事件→**信号量**;资源→**互斥量**;多事件组合→**事件组**;一对一简单→**任务通知** | | 29 | RTOS 任务同步方式 | 一对一→**任务通知**;多条件组合(AND/OR)→**事件组**;计数/资源/多接收者→**信号量** | | 30 | ISR 通信 | **会阻塞或要任务身份(互斥量)→ ISR 禁用**;其余发送/通知一律 **FromISR 版** | | 31 | 栈估算 | 栈 =**最坏路径峰值(局部+调用帧+库函数+中断嵌套)× 1.5~2**;HighWaterMark 留 **20%+** 余量 | --- ## 二、易混对比集中营(高频考点串讲) ### 任务四种状态 | | Blocked | Suspended | | -------- | -------------------------------- | -------------------- | | 原因 | 主动等待事件(延时/信号量/队列) | 被外部挂起 | | 恢复 | 事件来了**自动**回 Ready | **必须 vTaskResume** | | 有超时吗 | 有 | 无 | ### 抢占 vs 时间片 | | 抢占 | 时间片 | | ---- | -------------- | --------------------- | | 触发 | 更高优先级就绪 | tick 到点(同优先级) | | 作用 | 跨优先级 | 同优先级内部 | | 目的 | 最高优先级先跑 | 公平轮流 | ### 二值信号量 vs 互斥量 | | 二值信号量 | 互斥量 | | ---------- | ------------- | -------------- | | 优先级继承 | ❌ | ✅ | | 所有权 | 任何人可释放 | 只能获取者释放 | | 用途 | 事件通知/同步 | 保护共享资源 | | 反转风险 | 有 | 继承缓解 | ### 优先级继承 vs 优先级天花板 | | 优先级继承 | 优先级天花板 | | ---- | -------------------------------- | ---------------------------------- | | 机制 | 持锁者**动态**提到当前等待者水平 | 持锁者**静态**提到所有使用者最高级 | | 优点 | 灵活、不过度 | 简单可靠 | | 缺点 | 实现复杂、链式继承开销 | 过度提升,可能降整体实时性 | ### 临界区三件套 | | 关中断(临界区) | 挂起调度器 | 互斥量 | | -------- | ------------------ | ---------- | ---------------------- | | 挡什么 | 中断+任务 | 只挡任务 | 只挡任务(等待者阻塞) | | 中断响应 | 不能 | 能 | 能 | | 适用 | **中断也碰**的数据 | 只有任务碰 | 只有任务碰、要等锁 | | 代价 | 中断延迟大 | 小 | 切换开销 | ### IPC 五工具选型总表 | 工具 | 传什么 | 适用 | 成本 | | -------- | --------- | ------------ | ---------- | | 队列 | 数据 | 数据流、命令 | 中(复制) | | 信号量 | 事件/计数 | 通知、计数 | 低 | | 互斥量 | 无(锁) | 资源独占 | 低+继承 | | 事件组 | 事件组合 | 多事件与/或 | 低 | | 任务通知 | 简单信号 | 一对一唤醒 | 最低 | ### 普通 API vs FromISR 版 | | 普通版 | FromISR 版 | | ------------ | ------------ | ----------------------------------------------- | | 阻塞吗 | 会(带超时) | 不会(失败即返) | | 唤醒高优先级 | 立即切换 | 置`pxHigherPriorityTaskWoken`,中断返回后才切换 | | 适用 | 任务上下文 | 中断/任务都可用 | ### 栈 vs 堆 | | 栈 | 堆 | | -------- | -------------------------- | --------------- | | 存放 | 局部变量/调用帧/保存寄存器 | malloc 动态内存 | | 谁管 | 系统自动 | 程序员 | | 溢出后果 | 踩坏相邻内存/任务 | 分配失败/碎片 | --- ## 三、综合练习题(答完再对答案) ### 判断题(对/错 + 一句话理由) 1. `vTaskDelay(100)` 之后,任务进入 Suspended 状态。答:错,是阻塞状态 2. 一个任务被更高优先级任务抢占后,先进入 Ready 状态排队,不会直接回 Running。答:对,任务被更高优先级任务抢占后,先进入 Ready 状态排队,而不是阻塞和悬挂和运行。 3. 两个同优先级任务轮流执行,一个的 tick 时间片用完换另一个跑——这叫抢占。答:错,是时间片轮换 4. 任务 H(8) 等信号量 S,任务 L(2) 持有 S,任务 M(4) 就绪长跑 → 发生优先级反转。答:对,高优先级任务等待资源,低优先级任务持有资源,中优先级任务是就绪状态,不等待也不持有资源,发生优先级反转 5. 任务 A(8) 等互斥量,B(2) 持互斥量,C(1) 就绪 → 发生优先级反转。答:错,高优先级任务等待资源,低优先级任务持有资源,中优先级任务是就绪状态,不等待也不持有资源,发生优先级反转 6. 临界区里调用 `vTaskDelay(10)` 会正常工作,只是慢一点。答:错,临界区的本质是关闭中断,在临界区内的动作必须是微秒级别,一旦达到毫秒就会发生跑飞、死锁等, 调用`vTaskDelay(10)`进入阻塞,但计时器定时中断没正常工作,会发生错误。 7. 数据同时被任务和中断访问时,用互斥量保护就够了。答:错,中断也要碰的数据,尽量还是要使用关中断(临界区)。 8. 信号量可以把具体的数据值传给接收任务。答:错,不能,除非是计数任务等 9. 经典版任务通知可以一次通知多个任务。答:错,不能,一般只能1对1通知 10. ISR 里可以用带超时参数的 `xQueueSend`。答:错,临界区的本质是关闭中断,在临界区内的动作必须是微秒级别,一旦达到毫秒就会发生跑飞、死锁等。 11. ISR 里可以给互斥量 give。答:错,互斥量要进行优先级继承,这会包含任务上下文。而在 ISR 里面只有中断上下文,不能够正常恢复现场,导致会跑飞。 12. 任务栈开得越大越好,4096 words 保证永不溢出。答:错,会浪费资源 13. `uxTaskGetStackHighWaterMark` 返回的值越大,表示栈越接近溢出。答:错,返回值表示占历史最低空闲资源,越大代表空闲的资源越多,越不接近溢出。 14. RTOS 里任务正跑时被中断打断,异常帧会压进当前任务自己的栈。答:对,RTOS 任务跑在 PSP(任务自己的栈),中断异常帧压进当前任务栈——这就是估算要算中断嵌套的原因。 ### 填空题 15. 任务等待一个永不发生的事件,会永久处于 ____ 状态(RTOS 经典 bug)。答:饥饿 16. 需要固定周期执行(硬实时周期任务),用 ____ 而非 vTaskDelay。答:vTaskDelayUnit 17. 解决优先级反转的两个机制:____(FreeRTOS 默认)和 ____。答:优先级继承,优先级天花板 18. 保护共享资源用 ____;事件通知用 ____(0/1 信号)。答:互斥量,任务通知 19. ISR 里通知任务必须用 ____ 结尾的 API,通过 ____ 标志在中断返回后切换。答:FromISR,pxHigherPriorityTaskWoken(本质是pdTrue) 20. 任务栈估算 = ____ × 余量系数(经验 1.5~2)。答:最坏路径峰值(局部变量+调用帧+库函数+中断嵌套) 21. 串口收到一个字节的数据要交给另一个任务处理 → 用 ____。答:队列 22. 等"按键按下 OR 定时器到点"任一事件 → 用 ____。答:事件组 ### 场景 / 代码判断v 23. 场景:高优先级任务被中优先级任务拖住,持有资源的低优先级任务一直抢不到 CPU。识别这是什么问题,并给出解决方案。答:优先级翻转,使用互斥量的优先级继承方案或者优先级天花板方案,一般而言采用优先级继承。 24. 代码错在哪:`void ISR(void) { xQueueSend(&q, &data, 10); }`答:在中断中,ISR不能够使这个带阻塞的`xQueueSend` 25. 代码会怎样:`taskENTER_CRITICAL(); vTaskDelay(10); taskEXIT_CRITICAL();`答:临界区的本质是关闭中断,在临界区内的动作必须是微秒级别,一旦达到毫秒就会发生跑飞、死锁等, 调用`vTaskDelay(10)`进入阻塞,但计时器定时中断没正常工作,会发生错误。 26. 任务栈 128 words,`uxTaskGetStackHighWaterMark` 返回 20——栈要不要加大?答:用,余量系数计算得128*0.2=25.6,可知够,但任务功能需求加载时可能需要加 --- ## 四、答案(已分离) 答案解析已单独存放,避免自测时不小心看到答案: > **`第二批复习总结-答案.md`**(同目录)——完成全部 26 题后再翻开对照。 --- _复习目标:每条规则能自己讲出"为什么",不只记住结论。_