使用说明:先自测「判别规则速查表」,遮住右列自答;再做「综合练习题」,最后对答案。 面试前只翻本目录,不背题。
| # | 主题 | 一句话判别规则 |
|---|---|---|
| 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 |
| 有超时吗 | 有 | 无 |
| 抢占 | 时间片 | |
|---|---|---|
| 触发 | 更高优先级就绪 | tick 到点(同优先级) |
| 作用 | 跨优先级 | 同优先级内部 |
| 目的 | 最高优先级先跑 | 公平轮流 |
| 二值信号量 | 互斥量 | |
|---|---|---|
| 优先级继承 | ❌ | ✅ |
| 所有权 | 任何人可释放 | 只能获取者释放 |
| 用途 | 事件通知/同步 | 保护共享资源 |
| 反转风险 | 有 | 继承缓解 |
| 优先级继承 | 优先级天花板 | |
|---|---|---|
| 机制 | 持锁者动态提到当前等待者水平 | 持锁者静态提到所有使用者最高级 |
| 优点 | 灵活、不过度 | 简单可靠 |
| 缺点 | 实现复杂、链式继承开销 | 过度提升,可能降整体实时性 |
| 关中断(临界区) | 挂起调度器 | 互斥量 | |
|---|---|---|---|
| 挡什么 | 中断+任务 | 只挡任务 | 只挡任务(等待者阻塞) |
| 中断响应 | 不能 | 能 | 能 |
| 适用 | 中断也碰的数据 | 只有任务碰 | 只有任务碰、要等锁 |
| 代价 | 中断延迟大 | 小 | 切换开销 |
| 工具 | 传什么 | 适用 | 成本 |
|---|---|---|---|
| 队列 | 数据 | 数据流、命令 | 中(复制) |
| 信号量 | 事件/计数 | 通知、计数 | 低 |
| 互斥量 | 无(锁) | 资源独占 | 低+继承 |
| 事件组 | 事件组合 | 多事件与/或 | 低 |
| 任务通知 | 简单信号 | 一对一唤醒 | 最低 |
| 普通版 | FromISR 版 | |
|---|---|---|
| 阻塞吗 | 会(带超时) | 不会(失败即返) |
| 唤醒高优先级 | 立即切换 | 置pxHigherPriorityTaskWoken,中断返回后才切换 |
| 适用 | 任务上下文 | 中断/任务都可用 |
| 栈 | 堆 | |
|---|---|---|
| 存放 | 局部变量/调用帧/保存寄存器 | malloc 动态内存 |
| 谁管 | 系统自动 | 程序员 |
| 溢出后果 | 踩坏相邻内存/任务 | 分配失败/碎片 |
vTaskDelay(100) 之后,任务进入 Suspended 状态。答:错,是阻塞状态vTaskDelay(10) 会正常工作,只是慢一点。答:错,临界区的本质是关闭中断,在临界区内的动作必须是微秒级别,一旦达到毫秒就会发生跑飞、死锁等, 调用vTaskDelay(10)进入阻塞,但计时器定时中断没正常工作,会发生错误。xQueueSend。答:错,临界区的本质是关闭中断,在临界区内的动作必须是微秒级别,一旦达到毫秒就会发生跑飞、死锁等。uxTaskGetStackHighWaterMark 返回的值越大,表示栈越接近溢出。答:错,返回值表示占历史最低空闲资源,越大代表空闲的资源越多,越不接近溢出。void ISR(void) { xQueueSend(&q, &data, 10); }答:在中断中,ISR不能够使这个带阻塞的xQueueSendtaskENTER_CRITICAL(); vTaskDelay(10); taskEXIT_CRITICAL();答:临界区的本质是关闭中断,在临界区内的动作必须是微秒级别,一旦达到毫秒就会发生跑飞、死锁等, 调用vTaskDelay(10)进入阻塞,但计时器定时中断没正常工作,会发生错误。uxTaskGetStackHighWaterMark 返回 20——栈要不要加大?答:用,余量系数计算得128*0.2=25.6,可知够,但任务功能需求加载时可能需要加答案解析已单独存放,避免自测时不小心看到答案:
第二批复习总结-答案.md(同目录)——完成全部 26 题后再翻开对照。
复习目标:每条规则能自己讲出"为什么",不只记住结论。