×

FreeRTOS学习之旅(五) -----任务

zxjy辉 zxjy辉 发表于2022-09-05 14:06:30 浏览239 评论0

抢沙发发表评论


贵阳百花湖.jpeg

任务相关的笔记


  1. 任务:指一个方法或者说是一个函数

    1. 这是一个任务,是准备执行的具体的功能,每个任务都是一个不断执行的,系统依靠“优先级”来切换不同的任务
      图片.png

  2. 栈空间

    1. 这个空间或者说是一个数组,就是决定了能够存放的变量、方法等相关数据的上限,多少个任务就对应多少个的任务栈

      图片.png

  3. 任务句柄

    1. 是一个空指针,在初始化完成之后,就指向了任务控制块

  4. 任务控制块

    1. 是一个结构体,包含了任务相关的成员

      图片.png

  5. 创建任务:使得任务与任务控制块产生联系,有两类创建方法

    1. 静态创建 ( xTaskCreateStatic ):无法释放内存


    2. 动态创建( xTaskCreate ):内存可以释放

      1. xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &xHandleTask1);

        对应的形参是:任务入口、任务名称、任务栈大小、任务形参、优先级、任务句柄(任务控制块);数值越大,优先级越高,0表示空闲任务的优先级

  6. 就绪列表:在任务创建的时候,就是已经被添加到就绪列表中了

    1. 就是一个List_t类型的一个数组,数组的大小由configMax_PRIORITIES决定,数组的下标就代表了优先级,默认情况下,最大值为5,能用的优先级是(0~4)

    2. 就绪列表初始化

      1. 由于实质上是一个链表,所以他的初始化,就是将链表的首尾都指向自己,就是一个链表根节点的初始化

    3. 将任务添加到就绪列表里

      1. 目的:因为他是一个链表,所以它可以通过这个链表,快速的删减任务

      2. 实质:将一个节点添加到一个链表中,任务是任务控制块中的一个成员变量(任务入口),而任务控制块中有一个成员变量是节点(xStateListItem),可以说是任务控制块将任务和就绪列表联系起来了

  7. 任务调度器:实现任务的切换,即从就绪列表中,找到最高优先级的开始执行

    1. 实现原理:利用stm32中的一个异常:Pendsv(可悬挂异常)

      1. Pendsv:如果当前没有更高级的异常或者是中断需要执行,那么就执行Pendsv的异常服务函数

    2. 具体的实现过程

      1. 在FreeRTOS中,先往Pendsv的寄存器里写1,然后就等所有的的任务或者是异常结束后,在响应Pendsv的异常服务函数,也就是切换任务(切换任务的这个过程在服务函数里写,官方已经提供(修改了的,并重定义的)Pendsv的异常服务函数,只需要在FreeRTOSConfig.h中重申明),记得屏蔽原本的stm32自带的中断服务函数

        图片.png

    3. 对应的切换函数:taskYIELD------>xPortPendscHandle------->vTaskSwitchContext

  8. 实现一个任务的创建过程

    1. 任务实体(功能方法)

    2. 任务句柄             TaskHandle_t Task1_Handle;

    3. 任务堆栈大小      #define Task1_Stack_Size 128

    4. 任务栈                StackType_t Task1_Stack[Task1_Stack_Size];

    5. 创建任务             xTaskCreate(Task1Function, "Task1", 100, NULL, 1, &Task1_Handle);

    6. 启动任务调度器   vTaskStartScheduler();


#好好学习!

群贤毕至

访客