FreeRTOS任务切换笔记
1.PendSV异常PendSV 的中断由中断控制状态寄存器ICSR 中PENDSVSET为置1触发。PendSV 的中断是非实时的。PendSV 的中断服务函数就会在其他所有中断处理完成后才执行。优先级最低OS 内核的执行可以有两种触发方式SVC 指令触发及SysTick周期性的中断。任务切换导致中断请求延迟处理中断请求IRQ在SysTick中断产生之前产生FreeRTOS的任务切换就是在PendSV中完成的。2.PendSV中断服务函数PendSV 的中断服务函数定义成函数 xPortPendSVHandler()。在进行任务切换的时候 还需考虑是否保护和恢复浮点寄存器的值。在 PendSV 中断服务函数中 主要要做的事情就是 保存硬件不会自动入栈的 CPU 信息 已经确定写一个要运行的任务 并将 pxCurrentTCB 指向该任务的任务控制块 然后更新PSP 指针为该任务的任务堆栈指针。3.FreeRTOS确定下一个要运行的任务vTaskSwitchContext()调用了函数 taskSELECT_HIGHEST_PRIORITY_TASK() 来将pxCurrentTCB 设置为指向优先级最高的就绪态任务。uxSchedulerSuspended变量用于在系统运行的任意时刻标记需要进行任务切换会在 SysTick 的中断服务函数中统一处理。将 pxCurrentTCB 指向优先级最高的就绪态任务有两种方法滴答定时器、portYIELD()---本质是向中断控制和状态寄存器ICSR的bit28写入1挂起PendSV来启动PendSV中断 由 FreeRTOSConfig.h 文件配置决定。taskSELECT_HIGHEST_PRIORITY_TASK()用于将 pcCurrentTCB 设置为优先级最高的就绪态任务 因此该函数会使用位图的方式在任务优先级记录中查找优先级最高任务优先等级 然后根据这个优先等级 到对应的就绪态任务列表在中取任务。taskSELECT_HIGHEST_PRIORITY_TASK()全局变量 uxTopReadyPriority 以位图方式记录了系统中存在任务的优先级将遍历的起始优先级设置为这个全局变量而无需从系统支持优先级的最大值开始遍历可以节约一定的遍历时间。限制了系统最大优先级数量不能超过32个。依靠特定硬件指令实现的函数 taskSELECT_HIGHEST_PRIORITY_TASK()是一个宏定义。4.PendSV异常何时触发PendSV 异常用于进行任务切换portYIELD()设置中断控制状态寄存器以触发PendSV异常。5.FreeRTOS时间片调度CPU 轮流运行优先级相同的任务 每个任务运行的时间就是一个系统时钟节拍。临界区是指那些必须完整运行的区域 在临界区中的代码必须完整运行 不能被打断。FreeRTOS 在进出临界区的时候 通过关闭和打开受 FreeRTOS 管理的中断 以保护临界区中的代码。