任务分静态任务和动态任务,静态任务需要自定义栈空间,还需要包括任务栈,以及定时器的栈,软件定时器是依靠一个叫做定时器任务来维持的,因此需要一个栈空间。
在调用创建静态任务函数后,实际这个函数内层已经初始化了任务栈,空闲任务栈,以及定时器任务栈,并且把任务加入了就绪列表。
在开启调度的时候,配置Systick初始化,然后新建空闲任务并且加入就绪列表。开启调度之后是去执行的SVC 中断。在SVC中断中去把pxCurrentTCB相关的信息加载入寄存器
那么在哪里确定pxCurrentTCB是哪个任务的呢?
打开静态任务创建函数下的这个函数 prvAddNewTaskToReadyList()
可以看到:pxCurrentTCB为空的时候,表示这还是第一次创建任务,就把这个传入的TCB赋给这个pxCurrentTCB,而如果pxCurrentTCB 不为空,且调度器还没有开始运行,即(xSchedulerRunning=pdFalse), 说明这是第二次创建任务,或者第三次,反正不是第一次,并且还没开始调度。如果这个传入的任务的优先级更高,那么把这个新传入的任务的TCB给pxCurrentTCB。至此,就确定好了最先执行的任务。
动态任务的创建只需要预先定义好一个任务句柄,在调用xTaskCreate()创建任务时候手动把任务栈大小,优先级这些传入,在底层会帮我们向堆申请一块内存。