Toriyung

导航

空闲任务

freertos是通过调度任务实现实时任务的,而通过阻塞延时这一章(参考:https://www.cnblogs.com/toriyung/p/16905193.html),我们可以知道,当其他任务都进入阻塞时,空闲任务则执行。

空闲任务主要负责一些清理的工作,它不用我们手动创建,在调度器启动调度时则创建完成,现在就来了解下其内核。

 

创建任务,主要就是初始化任务的栈等,而我们手动创建任务是将这些参数作为形参传入创建函数,但是由于创建函数是内嵌在任务调度中,没办法直接调用到,所以需要定义另外一个函数,该函数对外部变量和任务调度内部变量联系起来,任务调度内部的创建空闲任务函数再直接调用内部变量。显然,这个函数我们就可以进行自定义其内容。这个函数就是vApplicationGetIdleTaskMemory,它以各参数的二级指针作为输入。

完整代码如下

void vApplicationGetIdleTaskMemory(TCB_t **ppxIdleTaskTCBBuffer,StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
{
    /* 空闲任务是启动调度器时内核自动创建的,所以需要预先定好几个内核创建空闲任务时的参数,用户自行对该函数的赋值等进行编写 */

    
    *ppxIdleTaskTCBBuffer = &IdleTaskTCB;
    *ppxIdleTaskStackBuffer = IdleTaskStack;
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

void prvIdleTask(void)
{
    /*目前暂时不进行有意义的空闲任务定义*/
    for(;;);
}

void vTaskStartScheduler(void)
{
    /* 启动任务调度(含有空闲任务创建) */
    TaskHandle_t xIdleTaskHandle;                                            //空闲任务句柄
    TCB_t *pxIdleTaskTCBBuffer = NULL;                                //空闲任务TCB的指针
    StackType_t *pxIdleTaskStackBuffer = NULL;                //空闲任务栈指针
    uint32_t ulIdleTaskStackSize;                                            //空闲任务栈大小
    
    vApplicationGetIdleTaskMemory(&pxIdleTaskTCBBuffer,&pxIdleTaskStackBuffer,&ulIdleTaskStackSize);        //获取空闲任务信息,注意用二重指针
    
    //创建空闲任务
    xIdleTaskHandle = xTaskCreateStatic((TaskFunction_t)prvIdleTask,(char *)"IDLE", (uint32_t)ulIdleTaskStackSize,(void *)NULL,(StackType_t *)pxIdleTaskStackBuffer,(TCB_t *)pxIdleTaskTCBBuffer);
    
    vListInsertEnd(&(pxReadyTasksLists[0]),&(((TCB_t *)pxIdleTaskTCBBuffer)->xStateListItem));  //换成(*xIdleTaskHandle)->xStateListItem呢?

    /* 原本调度器的调度部分 */
    
    pxCurrentTCB = &Task1TCB;    //指定第一个任务
    
    if(xPortStartScheduler() != pdFALSE)
    {
        //调度器启动失败则进入这里
    }
}

 

posted on 2022-11-19 15:16  Toriyung  阅读(48)  评论(0编辑  收藏  举报