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) { //调度器启动失败则进入这里 } }
标签:创建,void,调度,任务,TCB,空闲 From: https://www.cnblogs.com/toriyung/p/16906189.html