二、任务的挂起和恢复
有时候我们需要暂停某个任务的运行,过一段时间以后在重新运行。这个时候要是使用任务删除和重建的方法的话 那么任务中变量保存的值肯定丢失了!FreeRTOS给我们提供了解决这种问题的方法,那就是任务挂起和恢复,当某个任务要停止运行一段时间的话就将这个任务挂起,当要重新运行这个任务的话就恢复这个任务的运行。
2.1函数vTaskSuspend
此函数用于将某个任务设置为挂起态,进入挂起态的任务永远都不会进入运行态。退出挂起态的唯一方法就是调用任务恢复函数vTaskResume或xTaskResumeFromISR,函数原型如下:
void vTaskSuspend( TaskHandle_t xTaskToSuspend);
参数:
xTaskToSuspend:要挂起的任务的任务句柄,创建任务的时候会为每个任务分配一个任务句柄。
如果使用函数xTaskCreate()创建任务的话,那么函数的参数pxCreatedTask就是此任务的任务句柄,如果使用函数 xTaskCreateStatic()创建任务的话,那么函数的返回值就是此任务的任务句柄。也可以通过函数xTaskGetHandle()来根据 任务名字来获取某个任务的任务句柄。
注意!如果参数为NULL的话表示挂起任务自己。
返回值:无
2.2 函数vTaskResume
将一个任务从挂起态恢复到就绪态,只有通过函数vTasksSuspend()设置为挂起态的任务才可以使用vTaskRexume()恢复!
函数原型如下:
void vTaskResume( TaskHandle_t xTaskToResume);
参数:
xTaskToResume:要恢复的任务的任务句柄。
返回值:无
2.3 函数vTaskResumeFromISR
此函数是vTaskResume()的中断版本,用于在中断服务函数中恢复一个任务。
函数原型如下:
BaseType_t xTaskResumeFromISR(TaskHandle t xTaskToResume);
参数:
xTaskToResume:要恢复的任务的任务句柄。
返回值:
pdTRUE:恢复运行的任务的任务优先级等于或者高于正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数以后必须进行 一次上下文切换。
pdFALSE:恢复运行的任务的任务优先级低于当前正在运行的任务(被中断打断的任务),这意味着在退出中断服务函数的以后不需要进行 上下文切换。
上下文:通俗的理解,上下文,也就是执行任务所需要的相关信息。这个任务可以是一段代码,一个线程,一个进程, 一个函数。当这个“任务”,相关信息需要保存下来,就可以使用Context来记录了。
2.4 函数vTaskSuspendAll
此函数是挂起调度器可以停止上下文切换而不用关中断。如果某个中断在调度器挂起过程中要求进行上下文切换, 则个这请求也会被挂起,直到调度器被唤醒后才会得到执行。
void vTaskSuspendAll( void )
注意:
vTaskSuspendAll被调用后,禁止调用引起任务切换相关函数(例如vTaskDelay、等待信号量/互斥锁/消息队列 等)
示例代码
static void app_task1(void* pvParameters) {
for(;;)
{ /* 挂起调度器 */
vTaskSuspendAll();
printf("app_task1 is running ...\r\n");
vTaskDelay(1000);
/* 恢复调度器 */
xTaskResumeAll();
}
}
当app_task1执行vTaskSuspendAll函数后调用vTaskDelay函数,则程序停留在configASSERT(
uxSchedulerSuspended == 0 );位置处不再运行,如下图。
![](https://i-blog.csdnimg.cn/blog_migrate/aa10de1049a88596bf1c1bd483b49076.png)
2.5 函数xTaskResumeAll
此函数是恢复调度器。在调度器挂起过程中,上下文切换请求也会被挂起,直到调度器被唤醒后才会得到执行。
BaseType_t xTaskResumeAll( void )
参数:无
返回值:如果一个挂起的上下文切换请求在xTaskResumeAll()返回前得到执行,则函数返回 pdTRUE。在其它情况下, xTaskResumeAll()返回 pdFALSE。