明珠的个人博客

是谁告诉你,你是赤裸的?

0%

FreeRTOS之三-任务挂起与恢复及中断管理

FreeRTOS任务挂起与恢复

简介

挂起:挂起任务类似暂停,可恢复;删除任务,无法恢复,类似“人死两清”
恢复:恢复被挂起的任务
FromISR:带有FromISR后缀是在中断函数中专用的API函数

对应使用到的API函数:

顾名思义,英文翻译还是很清楚的

vTaskSuspend() 挂起任务
vTaskResume() 恢复被挂起的任务
vTaskResumeFromISR() 在中断中恢复被挂起的任务

任务挂起

任务挂起函数

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

xTaskToSuspend为形参,是挂起任务的任务句柄

任务挂起函数用于挂起任务,使用时需要将将FreeRTOSConfig.h文件中宏INCLUDE_vTaskSuspend配置为1

无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复

注意:当传入的参数是NULL,则代表挂起任务自身(当前正在运行的任务)

任务挂起函数内部实现

  1. 获取所要挂起任务的控制块 根据任务句柄获取任务控制块,如果任务句柄为NULL,表示挂起任务本身
  2. 移除所在列表 (将要挂起的任务从相应的状态列表和事件列表中移除)
  3. 插入挂起任务列表 (将待挂起任务的任务状态列表项插入到挂起状态列表末尾)
  4. 判断任务调度器是否运行 (判断任务调度器是否运行,在运行,更新下一次阻塞时间,防止被挂起任务为下一个阻塞超时任务)
  5. 判断待挂起任务是否为当前任务 (如果挂起的是任务自身,且调度器正在运行,需要进行一次任务切换;调度器没有运行,判断挂起任务数是否等于任务总数,是:当前控制块赋值为NULL,否:寻找下一个最高优先级任务)

任务恢复

任务恢复函数

void vTaskResume(TaskHandle_t xTaskToResume)

xTaskToResume为形参,是待恢复任务的任务句柄

使用该函数时需要将FreeRTOSConfig.h文件中宏INCLUDE_vTaskSuspend配置为1

注意:任务无论被vTaskSuspend()挂起多少次,只需在任务中调用vTaskResume()恢复一次就能继续运行,且被恢复的任务会进入就绪态

任务恢复函数(任务中恢复)内部实现

  1. 恢复任务不能是正在运行任务
  2. 判断任务是否在挂起列表中 (是:就会将该任务在挂起列表中移除,将该任务添加到就绪列表中)
  3. 判断恢复任务优先级 (判断恢复的任务优先级是否大于当前正在运行的任务,是的话,执行任务切换)

任务恢复函数介绍(中断中恢复)

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)

xTaskToResume为形参,是待恢复任务的任务句柄
返回值为pdTRUE,任务恢复后需要进行任务切换
返回值为pdFALSE,任务恢复后不需要进行任务切换

使用该函数注意要将FreeRTOSConfig.h文件中宏INCLUDE_vTaskSuspend和INCLUDE_xTaskResumeFromISR配置为1

该函数专用于中断服务函数中,用于解挂被挂起任务

注意:中断服务程序中要调用freeRTOS的API函数则中断优先级不能高于FreeRTOS所管理的最高优先级

任务恢复函数(中断中恢复)内部实现

  1. 关闭freertos可管理中断,防止被其他的中断打断,并返回关闭前basepri寄存器的值
  2. 判断是否有挂起任务
  3. 将前面保存的basepri的值,恢复回来
  4. 返回xYieldRequired的值 用于决定是否需要进行任务切换

中断管理

和51单片机上的中断一样,简介略,中断执行机制简单概括为三步:

  1. 中断请求 :外设产生中断请求(如:GPIO外部中断、定时器中断…)
  2. 响应中断 :CPU停止执行当前程序,转而执行中断处理程序(ISR)
  3. 退出中断 :执行完毕,返回被打断的程序处,继续往下执行

中断优先级分组设置

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
2