首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FreeRTOS任务切换解析(2)

FreeRTOS任务切换解析(2)

二:利用宏实现任务切换  portYIELD_WITHIN_API();
#define portYIELD_WITHIN_API portYIELD
#defineportYIELD()     vPortYieldFromISR()
利用PendSV异常实现任务切换
void vPortYieldFromISR( void )
{

*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;
}
出现portYIELD_WITHIN_API的地方有以下几处:
2.1:任务创建,如果创建的任务优先级比正在运行的高,进行切换
if( xSchedulerRunning != pdFALSE )
  {
   
   if(pxCurrentTCB->uxPriority < uxPriority)
   {
    portYIELD_WITHIN_API();
   }
  }
2.2:任务删除(删除自己)

  if( xSchedulerRunning !=pdFALSE )
  {
   if( ( void *) pxTaskToDelete == NULL )
   {
    portYIELD_WITHIN_API();
   }
  }
2.3:任务延时vTaskDelayUntil  vTaskDelay

如果延时时间没有到,强迫切换
  if( !xAlreadyYielded )
  {
   portYIELD_WITHIN_API();
  }
2.4:任务优先级设置vTaskPrioritySet
2.4.1:
   The priority of another task is being raised,
     其他某个任务优先级变高.
   
      xYieldRequired= pdTRUE;标志变量。

2.4.2: 设置自己的优先级变低。

     xYieldRequired= pdTRUE; 标志变量

判断标志变量的数值:
if( xYieldRequired == pdTRUE )
    {
     portYIELD_WITHIN_API();
    }
2.5:任务挂起 vTaskSuspend 只能挂起自己
if( pxTaskToSuspend == pxCurrentTCB )
   {
    pxTaskToSuspend= NULL;
   }

  if( ( void * ) pxTaskToSuspend== NULL )
  {
   portYIELD_WITHIN_API();
  }
2.6:任务唤醒  只能唤醒其他任务 vTaskResume

     if(pxTCB->uxPriority >=pxCurrentTCB->uxPriority )
     {
      
      portYIELD_WITHIN_API();
     }
2.7:xTaskResumeAll

    while(( pxTCB = ( tskTCB * )listGET_OWNER_OF_HEAD_ENTRY(  ( ( xList * )&xPendingReadyList ) ) ) != NULL )
    {
     vListRemove(&( pxTCB->xEventListItem ) );
     vListRemove(&( pxTCB->xGenericListItem ));
     prvAddTaskToReadyQueue(pxTCB );
     
     if(pxTCB->uxPriority >=pxCurrentTCB->uxPriority )
     {
      xYieldRequired= pdTRUE;
     }
    }
   
    if(uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )
    {
     while(uxMissedTicks > ( unsigned portBASE_TYPE ) 0 )
     {
      vTaskIncrementTick();
      --uxMissedTicks;
     }
     
     #ifconfigUSE_PREEMPTION == 1
     {
      xYieldRequired= pdTRUE;
     }
     #endif
    }
    if(( xYieldRequired == pdTRUE ) || ( xMissedYield == pdTRUE ) )
    {
     xAlreadyYielded= pdTRUE;
     xMissedYield= pdFALSE;
     portYIELD_WITHIN_API();
    }
   }
  }
继承事业,薪火相传
返回列表