05.FreeRTOS任务挂起与恢复

01.初识freeRTOS
02.FreeRTOS的移植
03.FreeRTOS系统配置
04.FreeRTOS任务创建与删除
05.FreeRTOS任务挂起与恢复
06.FreeRTOS中断管理
07.FreeRTOS列表与列表项
08.FreeRTOS任务调度与任务切换
09.FreeRTOS时间片调度与任务相关函数
10.FreeRTOS队列操作
11.FreeRTOS信号量操作
12.FreeRTOS队列集和事件标志组
13.FreeRTOS任务通知
14.FreeRTOS软件定时器
15.FreeRTOS低功耗
16.FreeRTOS内存管理

05. FreeRTOS任务挂起与任务恢复

1. FreeRTOS 挂起和恢复任务相关 API 函数

函数 描述
vTaskSuspend() 挂起任务
vTaskResume() 恢复被挂起的任务
xTaskResumeFromISR() 在中断中恢复被挂起的任务
  1. 函数vTaskSuspend()

    此函数用于挂起任务,若使用此函数,需要在FreeRTOSConfig.h文件中将宏 NCLUDE_vTaskSuspend配置为1。无论优先级如何,被挂起的任务都将不再被执行,直到任务被恢复。此函数并不支持嵌套,不论使用此函数重复挂起任务多少次,只需调用一次恢复任务的函数,那么任务就不再被挂起。函数原型如下所示:

    在这里插入图片描述

  2. 函数vTaskResume()

    此函数用于在任务中恢复被挂起的任务,若使用此函数,需要在FreeRTOSConfig.h文件中将宏INCLUDE_VTaskSuspend配置为1。不论一个任务被函数vTaskSuspend()挂起多少次,只需要使用函数vTaskResume()恢复一次,就可以继续运行。函数原型如下所示:

    在这里插入图片描述

  3. 函数xTaskResumeFromISR()

    此函数用于在中断中恢复被挂起的任务,若使用此函数,需要在FreeRTOSConfig.h文件中将宏INCLUDE_xTaskResumeFromISR配置为1。不论一个任务被函数vTaskSuspend()挂起多少次,只需要使用函数vTaskResumeFromISR()恢复一次,就可以继续运行。函数原型如下所示:

    在这里插入图片描述

2. vTaskSuspend源码分析

在这里插入图片描述

  1. 需将宏INCLUDE_vTaskSuspend 配置为 1

    // 使能挂起任务 
    #define INCLUDE_vTaskSuspend                            1                       
    
  2. 根据任务句柄获取任务控制块,如果任务句柄为NULL,表示挂起任务自身

    pxTCB = prvGetTCBFromHandle( xTaskToSuspend );
    
  3. 将要挂起的任务从状态列表中移除

    //3.将要挂起的任务从状态列表中移除
    if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
    {
         
    	taskRESET_READY_PRIORITY( pxTCB->uxPriority );
    }
    else
    {
         
    	mtCOVERAGE_TEST_MARKER();
    }
    
    //3.将要挂起的任务从事件列表中移除
    if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
    {
         
    	( void ) uxListRemove( &( pxTCB->xEventListItem ) );
    }
    else
    {
         
    	mtCOVERAGE_TEST_MARKER();
    }
    
  4. 将待挂起任务的任务状态列表插入挂起任务列表末尾

    vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );
    
    #if ( configUSE_TASK_NOTIFICATIONS == 1 )
    {
         
         BaseType_t x;
    
         for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ )
         {
         
    			//如果待挂起任务在等待,停止等待,直接赋值为0
                if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION )
                 {
           
                      pxTCB->ucNotifyState[ x ] = taskNOT_WAITING_NOTIFICATION;
                 }
         }
    }
    #endif 
    
  5. 判断任务调度器是否在运行

    //如果在运行,则更新下一次阻塞时间,防止被挂起任务为下一次阻塞超时任务
    if(xSchedulerRunning != pdFALSE)
    {
         
         taskENTER_CRITICAL();
         {
         
              prvResetNextTaskUnblockTime();
         }
         taskEXIT_CRITICAL();
    }
    else
    {
         
         mtCOVERAGE_TEST_MARKER();
    }
    
  6. 如果挂起的是当前任务,且调度器正在运行,需要进行一次任务切换,否则判断挂起任务数

    if( pxTCB == pxCurrentTCB )
    {
         
    	//且调度器正在运行,需要进行一次任务切换
    	if( xSchedulerRunning != pdFALSE )
    	{
         
    		configASSERT( uxSchedulerSuspended == 0 );
    		portYIELD_WITHIN_API();
    	}
    	//若没有运行,判断挂起任务数是否等于任务总数
    	//若相等,当前控制块赋值为NULL
    	//若不相等,寻找下一个最高优先级任务
    	else
    	{
         
    		if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) 
    		{
         
    			pxCurrentTCB = NULL;
    		}
    		else
    		{
         
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值