FreeRTOS-03_任务挂起和恢复
注意事项
在中断服务函数中恢复任务时,特别要注意中断的主优先级不能高过configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY所设置的最高优先级,也不能低于设置这个宏configLIBRARY_LOWEST_INTERRUPT_PRIORITY的最低优先级,一般为5和15,即中断分组设置时选择第四分组,将四个位都给主优先级,所以主优先级的范围在0-16,子优先级不用管,设置主优先级时不能低于5和高于15,虽然编译不会报错,但是通过串口可以看到警告信息
1、相关API函数
1.1、vTaskSuspend()
任务挂起函数
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
功能 :通过传入任务句柄获取任务控制块,然后将任务挂起
返回值:None
参数 :
- xTaskToSuspend:任务句柄
1.2、vTaskResume()
任务恢复函数(中断中不能用)
void vTaskResume( TaskHandle_t xTaskToResume )
功能 :通过传入任务句柄获取任务控制块,然后将任务恢复
返回值:None
参数 :
- xTaskToResume:任务句柄
1.3、xTaskResumeFromISR()
任务恢复函数(中断中使用)
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
功能 :通过传入任务句柄获取任务控制块,然后将任务恢复
返回值:BaseType_t 类型{
pdTRUE:表示要恢复的任务优先级高于当前运行的任务,需要进行任务切换
pdFALSE:表示任务优先级低于当前运行任务,无需进行任务切换
}
参数 :
- xTaskToResume:任务句柄
1.4、portYIELD_FROM_IS()
任务切换函数
portYIELD_FROM_ISR( x )
功能 :进行任务切换,将需要切换的任务句柄传入,即可与当前运行的任务进行切换,该函数在portmacro.h中通过宏定义指向了别处
返回值:None
参数 :
- **x **:任务句柄
2、操作流程
2.1、相应宏设置开启
- INCLUDE_vTaskSuspend 1
功能:要使用任务挂起函数需要将该宏置一 - INCLUDE_xResumeFromISR 1
功能:要使用xTaskResumeFromISR函数需要将该宏置一,才能在中断恢复任务
- configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
功能:该宏是系统可管理的最高中断主优先级 - configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
功能:该宏是系统可管理的最低中断主优先级
2.2、任务中恢复和挂起
用法非常简单,直接在任务中调用相关函数即可进行任务挂起和恢复了,主要是在中断中进行任务挂起需要调用另外的任务恢复函数
void task3(void * pvParameters)
{
while(1)
{
switch(Key_Scan(0))
{
case K1:
vTaskSuspend(task1_handler);
break;
case K2:
vTaskResume(task1_handler);
break;
case K3:
break;
default:break;
}
vTaskDelay(10);
}
}
2.3、在中断服务函数中进行任务恢复
本次实验使用了外部中断线12,在外部接了一个按键,当按键按下后触发外部中断进入中断服务函数,在中断服务函数中进行任务恢复需要使用xTaskResumeFromISR()而不能使用vTaskResume(),且中断的优先级注意设置时不能超过系统可管理的最高和最低优先级范围,任务恢复后要根据返回值对任务进行相应的切换操作,如果返回值为pdFALSE就不需要进行任务切换,pdTRUE就需要调用portYIELD_FROM_ISR()进行任务切换
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12) == SET)
{
BaseType_t xYieldRequired;
xYieldRequired = xTaskResumeFromISR(task1_handler);
if(xYieldRequired == pdTRUE)
{
portYIELD_FROM_ISR( xYieldRequired );
}
}
EXTI_ClearITPendingBit(EXTI_Line12);
}