FreeRTOS任务挂起与恢复
简介
挂起:挂起任务类似暂停,可恢复;删除任务,无法恢复,类似“人死两清”
恢复:恢复被挂起的任务
FromISR:带有FromISR后缀是在中断函数中专用的API函数
对应使用到的API函数:
顾名思义,英文翻译还是很清楚的
vTaskSuspend() 挂起任务
vTaskResume() 恢复被挂起的任务
vTaskResumeFromISR() 在中断中恢复被挂起的任务
任务挂起
任务挂起函数
void vTaskSuspend(TaskHandle_t xTaskToSuspend)
xTaskToSuspend为形参,是挂起任务的任务句柄
任务挂起函数用于挂起任务,使用时需要将将FreeRTOSConfig.h文件中宏INCLUDE_vTaskSuspend配置为1
无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复
注意:当传入的参数是NULL,则代表挂起任务自身(当前正在运行的任务)
任务挂起函数内部实现
- 获取所要挂起任务的控制块 根据任务句柄获取任务控制块,如果任务句柄为NULL,表示挂起任务本身
- 移除所在列表 (将要挂起的任务从相应的状态列表和事件列表中移除)
- 插入挂起任务列表 (将待挂起任务的任务状态列表项插入到挂起状态列表末尾)
- 判断任务调度器是否运行 (判断任务调度器是否运行,在运行,更新下一次阻塞时间,防止被挂起任务为下一个阻塞超时任务)
- 判断待挂起任务是否为当前任务 (如果挂起的是任务自身,且调度器正在运行,需要进行一次任务切换;调度器没有运行,判断挂起任务数是否等于任务总数,是:当前控制块赋值为NULL,否:寻找下一个最高优先级任务)
任务恢复
任务恢复函数
void vTaskResume(TaskHandle_t xTaskToResume)
xTaskToResume为形参,是待恢复任务的任务句柄
使用该函数时需要将FreeRTOSConfig.h文件中宏INCLUDE_vTaskSuspend配置为1
注意:任务无论被vTaskSuspend()挂起多少次,只需在任务中调用vTaskResume()恢复一次就能继续运行,且被恢复的任务会进入就绪态
任务恢复函数(任务中恢复)内部实现
- 恢复任务不能是正在运行任务
- 判断任务是否在挂起列表中 (是:就会将该任务在挂起列表中移除,将该任务添加到就绪列表中)
- 判断恢复任务优先级 (判断恢复的任务优先级是否大于当前正在运行的任务,是的话,执行任务切换)
任务恢复函数介绍(中断中恢复)
BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)
xTaskToResume为形参,是待恢复任务的任务句柄
返回值为pdTRUE,任务恢复后需要进行任务切换
返回值为pdFALSE,任务恢复后不需要进行任务切换
使用该函数注意要将FreeRTOSConfig.h文件中宏INCLUDE_vTaskSuspend和INCLUDE_xTaskResumeFromISR配置为1
该函数专用于中断服务函数中,用于解挂被挂起任务
注意:中断服务程序中要调用freeRTOS的API函数则中断优先级不能高于FreeRTOS所管理的最高优先级
任务恢复函数(中断中恢复)内部实现
- 关闭freertos可管理中断,防止被其他的中断打断,并返回关闭前basepri寄存器的值
- 判断是否有挂起任务
- 将前面保存的basepri的值,恢复回来
- 返回xYieldRequired的值 用于决定是否需要进行任务切换
中断管理
和51单片机上的中断一样,简介略,中断执行机制简单概括为三步:
- 中断请求 :外设产生中断请求(如:GPIO外部中断、定时器中断…)
- 响应中断 :CPU停止执行当前程序,转而执行中断处理程序(ISR)
- 退出中断 :执行完毕,返回被打断的程序处,继续往下执行
中断优先级分组设置
ARM Cortex-M 使用了8位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器。但STM32只用了中断优先级配置寄存器的高4位[7:4],所以STM32提供了最大16级(0~15)的中断优先等级
记得这里在之前看51时确实有点模糊,现在看了正点原子的课程后感觉讲解非常清晰,呵呵,横看成岭侧成峰,远近高低各不同,有时候感觉到困难时,不妨稍作休息换个思路,或许可以柳暗花明又一村
STM32的中断优先级可以分为抢占优先级和子优先级:
抢占优先级 :抢占优先级的中断可以打断正在执行但抢占优先级低的中断
子优先级 :当同时发生具有相同抢占优先级的两个中断时,子优先级数小的优先执行
注意 :中断优先级(抢占优先级和子优先级)数值越小,优先级越高,和任务优先级刚刚好相反,任务是数值大优先
中断优先级一共有5种配置方式,对应着中断优先级分组的5个组:
注意:FreeRTOS中为了方便管理,采用第4号(NVIC_PriorityGroup_4)分配方式
低于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断里才允许调用FreeRTOS的API函数,厂商决定,5-15
建议将所有优先级位指定为抢占优先级位,方便FreeRTOS管理
中断优先级数值越小越优先,任务优先级数值越大越优先
TBC…
1 |