• 1901_野火FreeRTOS教程之任务链表以及调度部分阅读


    1901_野火FreeRTOS教程之任务链表以及调度部分阅读

    全部学习汇总: g_FreeRTOS: FreeRTOS学习笔记 (gitee.com)

    这部分的内容,感觉直接对着代码工程梳理会好一些。教材基本上是看了一遍,先把这部分描述的框架整理一下。

    1. /* 初始化任务相关的列表 */
    2. void prvInitialiseTaskLists( void )
    3. {
    4.     UBaseType_t uxPriority;
    5.     for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ )
    6.     {
    7.         vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) );
    8.     }
    9. }

    首先是任务就绪链表的初始化,这个继续链表是按照优先级来分的。每一个优先级都会有一个任务调度链表。而使用之前,链表需要进行初始化。这部分主要还是之前所整理的链表部分的基本操作。通过这部分的代码分析看,其实如果是要让自己的系统资源占用更优一些,尽量按照自己真正的需求来配置优先级。

    1. int main(void)
    2. {
    3.     printf("start simulation...\n");
    4.     prvInitialiseTaskLists();
    5.     /* 创建任务 */
    6.     Task1_Handle = xTaskCreateStatic((TaskFunction_t)Task1_Entry, /* 任务入口 */
    7.                                      (char *)"Task1",             /* 任务名称,字符串形式 */
    8.                                      (uint32_t)TASK1_STACK_SIZE,  /* 任务栈大小,单位为字 */
    9.                                      (void *)NULL,                /* 任务形参 */
    10.                                      (StackType_t *)Task1Stack,   /* 任务栈起始地址 */
    11.                                      (TCB_t *)&Task1TCB);         /* 任务控制块 */
    12.     /* 将任务添加到就绪列表 */
    13.     vListInsertEnd(&(pxReadyTasksLists[1]), &(((TCB_t *)(&Task1TCB))->xStateListItem));
    14.     Task2_Handle = xTaskCreateStatic((TaskFunction_t)Task2_Entry, /* 任务入口 */
    15.                                      (char *)"Task2",             /* 任务名称,字符串形式 */
    16.                                      (uint32_t)TASK2_STACK_SIZE,  /* 任务栈大小,单位为字 */
    17.                                      (void *)NULL,                /* 任务形参 */
    18.                                      (StackType_t *)Task2Stack,   /* 任务栈起始地址 */
    19.                                      (TCB_t *)&Task2TCB);         /* 任务控制块 */
    20.     /* 将任务添加到就绪列表 */
    21.     vListInsertEnd(&(pxReadyTasksLists[2]), &(((TCB_t *)(&Task2TCB))->xStateListItem));
    22.     /* 启动调度器,开始多任务调度,启动成功则不返回 */
    23.     vTaskStartScheduler();
    24.     for (;;)
    25.     {
    26.         /* no code */
    27.     }
    28.     return 0;
    29. }

    接下来的处理,就是创建任务然后把任务关联到对应的链表中。这里是直接指定了对应的链表信息。而任务创建所实现的功能,之前已经分析过,主要是做了一个TCB的信息准备。之后,启动了调度器开始进行调度。

    这里有一个任务控制块的参数处理有一点复杂,主要是因为C语言的写法有不同的表达方式。我修改了一个自我感觉更容易读懂的版本如下:

    可以实现同样的效果,具体的运行效果可以从打印的信息看到。

    上面是运行的效果。

    代码中,我还修改了堆栈的大小。因为我在调试的时候加了一个printf,这个耗费的内存要大一些。

    任务调度的第一个任务是指定的。

    另外就是现在任务实体的形式,现在是这样子。多了一个任务切换,现在的代码堆叠这么使用也是情理之中。

    至于MCU内核相关的一些部分的整理以及分档的对应解读,后面单独拆分出来单独看。这一次的整理基本就这些。

  • 相关阅读:
    Python对数据进行分类统计
    还在问视频音频转文字软件哪个好吗?快码住这两款
    Kafka基本概念
    【数据结构与算法】初识二叉树(上)
    HTML制作一个汽车介绍网站【大学生网页制作期末作业】(汽车首页 1页 带psd)
    办学许可证申请流程,收藏起来慢慢看!
    strict模式表
    用微软拼音输入法的自定义短语功能插入“人名+当前日期”
    pix2tex - LaTeX OCR 安装使用记录
    内存利用:迟来的blindless与逃不掉的exit漏洞
  • 原文地址:https://blog.csdn.net/grey_csdn/article/details/136181806