重点:
一、FreeRtos任务的API调用
1.创建任务(静态、动态创建)
动态创建:
①先写任务函数
②定义函数的handle指针
③调用动态创建任务的API:xTaskCreate(任务函数,任务名称,栈深度,参数,优先级,handle指针)
静态创建:
①事先分配好任务控制块
事先提供好栈
②调用APIxTaskStaticCreate();
配置项
实现函数
2.删除任务
vTaskDelete(xHandlerTask1); //在任务中杀死其他任务
vTaskDelete(NULL); //在任务中自杀
vTaskDelete不会释放TCB和栈,而是在空闲任务中进行清理。不断创建和删除会导致内存耗光。
TASK1的栈,TASK2的栈
malloc在分配的时候,头部+buffer;
内存增长方向:
超出的话会破坏掉头部和TCB;
二、任务状态
任务切换的基础:tick中断
有哪些任务状态?
一共有四个状态:
①创建完任务之后,任务处于Ready状态;
②当启动调度器的时候,会挑一个任务进行运行Running;
③任务可以主动休息也可以让别的任务休息,调用vTaskSuspend(NULL / Task_handler)
④任务也可以等待某些事情:时间事情或者同步事件 在等到之前处于阻塞状态;
时间事情:可以等待一段时间
同步事件:这事件由别的任务,或者是中断程序产生
同步事件的来源有很多:队列,信号量,互斥量,事件组等等等(后面章节会讲解)
怎么管理不同状态的任务?放入不同的链表
三、Delay函数
vTaskDelayUntil:等待到指定的绝对时刻,才能变为就绪态。
四、空闲任务和钩子函数
1.空闲任务优先级为 0 :它不能阻碍用户任务运行2.空闲任务要么处于就绪态,要么处于运行态,永远不会阻塞
空闲任务(Idle 任务)的另一个作用:释放被删除的任务的内存;
作用:1.执行一些低优先级的、后台的、需要连续执行的函数2.测量系统的空闲时间:空闲任务能被执行就意味着所有的高优先级任务都停止了,所以测量空闲任务占据的时间,就可以算出处理器占用率。3.让系统进入省电模式:空闲任务能被执行就意味着没有重要的事情要做,当然可以进入省电模式了。
五、调度算法
正常来说是:高优先级先运行,同优先级交替运行,但还有一些细节需要确认;
三个配置项
configUSE_PREEMPTION:是否抢占configUSE_TIME_SLICING:是否时间片轮转configIDLE_SHOULD_YIELD:空闲任务是否让步
可否抢占?
可抢占:高优先级任务就绪了马上就运行
不可抢占:高优先级任务也不能马上运行,只能等待任务主动让出cpu资源;
轮转执行?
是:同优先级交替执行
否:当前任务一直执行,直到主动放弃、被高优先级任务抢占
空闲任务是否让步?
是:空闲任务低人一等,每循环执行一次,就主动让步给用户任务
否:跟用户任务一样,大家轮流执行,没有谁更特殊;
Idle_Task()
{
while(1)
{
xxx;
钩子函数();
if(YIELD)//循环一次之后就会调度,让步给用户任务
调度
endif
}
}
六、内部细节
创建任务
从上到下是:任务函数,任务名称,栈深度,参数,优先级,handle指针
TCB结构体
请回答下列三个问题:
①任务函数去哪了? ②栈去哪了? ③参数又去哪了?
调度机制
高优先级先运行,同优先级交替运行;
那怎么取出要运行的任务呢?
找到最高优先级的运行态/就绪态任务,运行它;
如果大家平级,轮流执行:排队,前面的先运行,运行一个tick后到链表尾部排队