1901_野火FreeRTOS教程之任务链表以及调度部分阅读
全部学习汇总: g_FreeRTOS: FreeRTOS学习笔记 (gitee.com)
这部分的内容,感觉直接对着代码工程梳理会好一些。教材基本上是看了一遍,先把这部分描述的框架整理一下。
/* 初始化任务相关的列表 */
void prvInitialiseTaskLists( void )
{
UBaseType_t uxPriority;
for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
{
vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
}
}
首先是任务就绪链表的初始化,这个继续链表是按照优先级来分的。每一个优先级都会有一个任务调度链表。而使用之前,链表需要进行初始化。这部分主要还是之前所整理的链表部分的基本操作。通过这部分的代码分析看,其实如果是要让自己的系统资源占用更优一些,尽量按照自己真正的需求来配置优先级。
int main(void)
{
printf("start simulation...\n");
prvInitialiseTaskLists();
/* 创建任务 */
Task1_Handle = xTaskCreateStatic((TaskFunction_t)Task1_Entry, /* 任务入口 */
(char *)"Task1", /* 任务名称,字符串形式 */
(uint32_t)TASK1_STACK_SIZE, /* 任务栈大小,单位为字 */
(void *)NULL, /* 任务形参 */
(StackType_t *)Task1Stack, /* 任务栈起始地址 */
(TCB_t *)&Task1TCB); /* 任务控制块 */
/* 将任务添加到就绪列表 */
vListInsertEnd(&(pxReadyTasksLists[1]), &(((TCB_t *)(&Task1TCB))->xStateListItem));
Task2_Handle = xTaskCreateStatic((TaskFunction_t)Task2_Entry, /* 任务入口 */
(char *)"Task2", /* 任务名称,字符串形式 */
(uint32_t)TASK2_STACK_SIZE, /* 任务栈大小,单位为字 */
(void *)NULL, /* 任务形参 */
(StackType_t *)Task2Stack, /* 任务栈起始地址 */
(TCB_t *)&Task2TCB); /* 任务控制块 */
/* 将任务添加到就绪列表 */
vListInsertEnd(&(pxReadyTasksLists[2]), &(((TCB_t *)(&Task2TCB))->xStateListItem));
/* 启动调度器,开始多任务调度,启动成功则不返回 */
vTaskStartScheduler();
for (;;)
{
/* no code */
}
return 0;
}
接下来的处理,就是创建任务然后把任务关联到对应的链表中。这里是直接指定了对应的链表信息。而任务创建所实现的功能,之前已经分析过,主要是做了一个TCB的信息准备。之后,启动了调度器开始进行调度。
这里有一个任务控制块的参数处理有一点复杂,主要是因为C语言的写法有不同的表达方式。我修改了一个自我感觉更容易读懂的版本如下:
可以实现同样的效果,具体的运行效果可以从打印的信息看到。
上面是运行的效果。
代码中,我还修改了堆栈的大小。因为我在调试的时候加了一个printf,这个耗费的内存要大一些。
任务调度的第一个任务是指定的。
另外就是现在任务实体的形式,现在是这样子。多了一个任务切换,现在的代码堆叠这么使用也是情理之中。
至于MCU内核相关的一些部分的整理以及分档的对应解读,后面单独拆分出来单独看。这一次的整理基本就这些。