【声明】本博客所有内容均为个人业余时间创作所述技术案例均来自公开开源项目如GithubApache基金会不涉及任何企业机密或未公开技术如有侵权请联系删除背景上篇 blog【OS】【Nuttx】【栈溢出】up_initial_stateIPSREPSR分析了 IPSR 中存放着正在处理的异常编号以及 IPSR 为 0 时表示 Thread Mode非异常状态也就是普通任务模式然后分析了 EPSREPSR 中除了有 Thumb 位之外还有个 ITIf-Then状态位用来支持 Thumb-2 的条件执行语句并详细分析了 APSR 中的 Z 标志Z 1 表示的是上一次比较时或运算结果为 0也就是相等下面继续分析栈溢出检测OK之前 blog 分析了up_initial_state中关于xPSR寄存器的设置主要设置的就是 Thumb 位下面继续看剩余 CPU 寄存器的设置可选设置rBSR10用于栈检查#ifdefCONFIG_ARMV7M_STACKCHECKxcp-regs[REG_R10]tcb-stack_alloc_ptr64;#endif这里 64 字节之前解释过就是为了留出安全距离OK之前 blog 【OS】【Nuttx】【最小系统】任务跳转 介绍了在 SIM 仿真环境下的任务跳转下面再看下经过up_initial_state任务初始化完成后Cortex-M 架构的任务跳转以及上下文切换先回顾下之前 SIM 环境下的任务跳转首先是up_switch_context首先是函数名up_是 Nuttx 中表示与体系结构相关的前缀与底层芯片架构区分开表示平台层switch_context表示平台功能即切换上下文所以up_switch_context作用是在不同任务线程之间自由切换 CPU 上下文然后是up_switch_context函数的注释从描述上看当有一个任务位于就绪队列ready-to-run list中并且已经被调度器选中准备运行那么就可以通过up_switch_context恢复准备要执行任务的上下文比如寄存器状态程序计数器等并开始执行接下来是参数说明up_switch_context涉及到两个参数struct tcb_s* tcb指向下一个要运行的任务也就是即将被调度上 CPU 的任务该任务是就绪队列的头部head of ready-to-run liststruct tcb_s* rtcb指向当前正在运行的任务running task这个任务即将被暂停比如因为时间片用完主动让出 CPU或被更高优先级的任务抢占注意tcb_s是 Task Control Block任务控制块的结构体类型其中保存了任务的所有信息包括栈指针寄存器状态优先级任务状态运行/就绪/阻塞等up_switch_context函数会完成任务切换的核心操作具体包括保存当前运行任务rtcb的上下文把 CPU 寄存器如 PCSP通用寄存器等保存到rtcb的栈或 TCB 中恢复下一个任务tcb的上下文从tcb的栈或 TCB 中加载之前保存的寄存器值跳转到新任务的执行位置继续运行通过修改栈指针 SP 和程序计数器 PC 实现最终跳转到新任务的代码处举个简单例子方便理解假设系统中有两个任务 A 和 B当前 CPU 正在运行任务 Artcb A调度器决定切换到任务 Btcb B调用up_switch_context(B, A)保存 A 的现场寄存器等恢复 B 的现场CPU 开始执行 B好像 B 从未中断过OK本篇先到这里如有疑问欢迎评论区留言讨论祝各位功力大涨技术更上一层楼更多内容见下篇 blog【OS】【Nuttx】【ARMV7M】任务跳转上下文切换二