1.总结任务调度算法之间的区别,重新实现一遍任务调度算法的代码。
一,抢占式调度:高优先级的任务可以打断低优先级任务的执行。
抢占式调度适用于任务优先级不同的任务。使用默认的任务去创建一个优先级比他高的任务,观察抢占式调度的现象。
//创建比默认任务优先级高的参数
osThreadId_t Task2Handle;
const osThreadAttr_t Task2_attributes = {.name = "Task2",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityNormal,
};//声名入口函数void Task2(void *argument);void StartDefaultTask(void *argument)
{for(;;){printf("StartDefaultTask is start\r\n");//创建一个任务优先级比StartDefailtTa要高的任务sKif(Task2Handle == NULL){//判断任务2的id是否存在,不存在说明没有创建任务2,此时可以创建它Task2Handle = osThreadNew(Task2,NULL,&Task2_attributes);}printf("StarDefaultTask is end\r\n");osDelay(500);}
}//实现任务2入口函数
void Task2(void *argument)
{for(;;){printf("Task2 is running\r\n");osDelay(500);}
}
可以看出任务2先被创建优先级更高.
2..时间片轮转:相同优先级的任务有相同的时间片(1ms),当时间片耗尽,任务必须退出
创建两个优先级相同的任务,其中一个消耗全部时间片,观察现象。
//创建一个同等级任务
osThreadId_t myTask02Handle;
const osThreadAttr_t myTask02_attributes = {.name = "myTask02",.stack_size = 128 * 4,.priority = (osPriority_t) osPriorityNormal,
};void StartDefaultTask(void *argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */int i = 0;for(;;){
//任务1消耗时间片printf("StartDefaultTask is start\r\n");for(i=0;i<9000000;i++){; //执行消耗时间}printf("StarDefaultTask is end\r\n");osDelay(500);}
}void StartTask02(void *argument)
{/* USER CODE BEGIN StartTask02 *//* Infinite loop */for(;;){printf("StartTask02\r\n");osDelay(500);}/* USER CODE END StartTask02 */
}
时间片到了,会自动退出。。
1.3.协作式调度:一般使用osDelay实现,两个任务协商运行。
2.总结静态创建任务和动态创建任务的区别,以及动态创建任务和静态创建任务的源码分析步骤。
2.1静态创建
-
1.在静态创建任务时,会创建一个数组,数组太大会导致内存不足
-
2.静态创建使用xTaskCreateStatic函数创建。
-
3.静态创建任务需要具体的栈(通过数组来指定),还需要提供栈的大小。
-
4.静态创建适用于任务数量确定的情况下
创建时数组太大会导致内存空间不足
2.2动态创建
-
1.动态创建使用的是xTaskCreate函数创建
-
.2.动态创建不需要指定具体的栈只需要指定栈的大小,栈会通过pvPortMalloc动态创建出来
-
3.动态创建需要消耗的系统资源会比静态创建任务要多。
-
4.动态创建任务适用于需要随时申请和随时释放的场景
最后,静态任务创建和动态任务创建在任务的生命周期管理上也存在差异。静态任务的生命周期通常与应用程序的生命周期相同,而动态任务的生命周期则可以根据需要动态调整。
3.总结任务的状态,以及任务状态之间的转换关系。
-
1.Ready:就绪态,当任务被创建后就会进入到就绪态
-
2.Running:运行态,任务的代码正在执行。
-
3.Blocked:阻塞态,当任务在等待时间,或者是信号量,互斥量的时候进入阻塞态。
-
4.Suspended:挂起态,当任务被挂起后任务还存在但是不运行。
1.程序首先创建就绪态 Ready
2.当调度器选择了当前任务,让当前任务的代码执行Ready--->Running。
3.Running->Ready:当任务执行结束后,重新进入就绪态
4.运行态可以调用Blocking API进入阻塞等待.
5..Running->Suspeded:Blocked->Suspeded:Ready->Suspeded:使用vTaskSuspend函数可以让任务运行态,阻塞态和就绪态进入或进入挂起态, 。。。
Suspeded->Ready:使用vTaskResume函数让任务重新进入就绪态.