真实面经题目 · 原创解析
FreeRTOS 每个任务为什么需要自己的栈,任务切换时要保存哪些上下文?
这题考任务隔离和上下文切换基础,回答要说明每个任务必须有独立调用栈,切换时保存寄存器、栈指针和调度状态。
真实面经题目 · 原创解析
这题考任务隔离和上下文切换基础,回答要说明每个任务必须有独立调用栈,切换时保存寄存器、栈指针和调度状态。
每个任务需要自己的栈,因为任务被切走时,它的函数调用链、局部变量、返回地址和中断返回现场都要保留。如果所有任务共用一个栈,任务 A 阻塞在某个函数深处后,任务 B 继续调用函数会覆盖 A 的局部变量和返回地址,A 再恢复就无法从原位置正确执行。FreeRTOS 的 TCB 会保存任务的栈顶指针、优先级、状态等信息。上下文切换时,硬件和软件一起保存当前任务的寄存器现场:Cortex-M 异常进入会自动压入 R0-R3、R12、LR、PC、xPSR 等,PendSV 再保存 R4-R11,必要时保存 FPU 上下文;然后把当前 PSP 存入 TCB,选下一个任务,恢复它的栈指针和寄存器。上下文还包括任务状态、临界区嵌套、通知值或 TLS 等内核管理信息。
函数调用的返回地址、局部变量、保存寄存器和参数临时空间都在栈上。任务被阻塞时,这些内容必须保持不变,才能恢复到阻塞前的执行点。
多任务不是简单轮流调用函数。任务可能在任意嵌套深度被切出,如果另一个任务继续使用同一栈空间,原任务的调用链就被破坏。
任务控制块保存当前栈顶、优先级、状态、链表节点和其他调度信息。调度器通过切换 TCB 中的栈指针实现从一个任务切到另一个任务。
Cortex-M 异常机制自动保存一部分寄存器,移植层保存剩余 callee-saved 寄存器和可选 FPU 上下文。恢复时按相反顺序弹出,任务就像从未被打断一样继续执行。
不是。全局和静态变量在全局数据区,任务栈主要放局部自动变量、调用现场和部分上下文。
任务使用浮点且端口启用 FPU 支持时需要保存或延迟保存浮点寄存器,否则任务切换后浮点计算会互相污染。
要看最坏响应时间、任务优先级、栈水位、队列积压、临界区时长和中断延迟,用压力用例和日志证明正常路径、阻塞路径、异常恢复路径都在预算内。