FreeRTOS学习(1)-- FreeRTOS任务创建、调度、任务间通信

FreeRTOS学习(1)-- FreeRTOS任务创建、调度、任务间通信



前言

初学FreeRTOS, 记录一下自己记的笔记。
参考文章:
1) freeRTOS任务调度及其通信 - 知乎 (zhihu.com)
2) FreeRTOS源码探析之——任务调度相关 - 知乎 (zhihu.com)
3) 4、FreeRTOS的任务创建和启动流程 - 孤情剑客 - 博客园 (cnblogs.com)


一、 FreeRTOS任务状态

在裸机系统中, 系统的主体就是 main 函数里面顺序执行的无限循环,这个无限循环里面 CPU 按照顺序完成各种事情。在多任务系统中,我们根据功能的不同,把整个系统分割成一个个独立的无限循环不带返回值的 C 函数,这个函数我们称为任务

FreeRTOS的任务被动态创建或者静态创建后,若不进行删除,则一共有四个状态分别为:
Running态Ready态Blocked态Suspended态(挂起)

在这里插入图片描述

二、FreeRTOS任务创建

FreeRTOS调用xTaskCreate(动态创建)或者 xTaskCreateStatic(静态创建)API进行任务的创建。

1.静态创建任务流程【ref.3】

在这里插入图片描述

1) 任务函数。

要点:任务一般都是死循环并且无返回值的,所以实际功能通常都实现在一个死循环中。
任务里面的延时函数必须使用 FreeRTOS 里面提供的延时函数vTaskDelay(),FreeRTOS 里面的延时是阻塞延时,调用 vTaskDelay()函数的时候,当前任务会被挂起,调度器会切换到其它就绪的任务,从而实现多任务。

安全起见,为了防止程序由于异常执行到死循环外,可在循环外添加删除当前任务语句vTaskDelete( NULL );

2) 任务栈。

要点:在多任务系统中,每个任务都是独立的,互不干扰的,所以要为每个任务都分配独立的栈空间,这个栈空间通常是一个预先定义好的全局数组(静态), 也可以是动态分配的一段内存空间(动态),但它们都存在于 RAM 中。

3) 任务控制块。

要点:在 C 代码上,任务控制块就是一个结构体,里面有非常多的成员,这些成员共同描述了任务的全部信息,类似于任务的身份证

4) 静态任务创建函数 xTaskCreateStatic()

代码如下(示例):

在这里插入图片描述
在这里插入图片描述

参数说明:
(1)任务函数,即任务函数的名称,需要我们自己定义并且实现。
(2)任务名字,字符串形式, 最大长度由FreeRTOSConfig.h 中定义的configMAX_TASK_NAME_LEN 宏指定其默认为16,多余部分会被自动截掉,这里任务名字最好要与任务函数入口名字一致,方便进行调试。
(3)任务堆栈大小,单位为字,在 32 位的处理器下(STM32),一个字等于4个字节,那么任务大小就为 128*4 字节。
(4)指向任务函数参数的指针,不用的时候配置为0或者NULL即可。
(5)任务的优先级。优先级范围根据 FreeRTOSConfig.h 中的宏configMAX_PRIORITIES 决定,如果使能 configUSE_PORT_OPTIMISED_TASK_SELECTION这个宏定义,则最多支持 32 个优先级。在 FreeRTOS 中,数值越大优先级越高,0 代表最低优先级。
(6)任务栈指针,指向起始地址,只有在使用静态内存的时候才需要提供,在使用动态内存的时候会根据提供的任务栈大小自动创建。
(7)任务控制块指针,在使用静态内存的时候,需要给任务初始化函数 xTaskCreateStatic()传递预先定义好的任务控制块的指针。在使用动态内存的时候,任务创建函数 xTaskCreate()会返回一个指针指向任务控制块。


2.动态创建任务【ref.3】

区别于静态
1) 任务使用的栈和任务控制块是在创建任务的时候FreeRTOS 动态分配的,并不是预先定义好的全局变量
2) 任务创建函数会返回一个指针,用于指向任务控制块,所以要预先为任务栈定义一个任务控制块指针,也是我们常说的任务句柄

代码如下(示例):
在这里插入图片描述
在这里插入图片描述


3. FreeRTOS任务调度流程【ref.1、2】

当任务创建好后,是处于任务就绪等待任务调度器启动。任务调度器只启动一次,之后就不会再次执行了, FreeRTOS 中启动任务调度器的函数是 vTaskStartScheduler(),并且启动任务调度器的时候就不会返回,从此任务管理都由FreeRTOS 管理,此时才是真正进入实时操作系统中的第一步。在任一时刻,CPU只能处理某一个任务

vTaskStartScheduler函数内部操作流程:
在这里插入图片描述
调度器的工作模式:
FreeRTOS中提供的任务调度器是基于优先级的抢占式调度:在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统的其他部分都是可以抢占的。

调度器就是使用相关的调度算法来决定当前需要执行的任务。

  • 调度器可以区分就绪态任务挂起态任务(由于延迟,信号量等待,事件组等待等原因而使得任务被挂起)。
  • 调度器可以选择就绪态中的一个任务,然后激活它(通过执行这个任务)使其成为运行态的任务。

FreeRTOS 主要有两种调度方式:

  • 抢占式调度:每个任务都有不同的优先级,任务会一直运行直到被高优先级任务抢占或者遇到阻塞式的 API 函数,如 vTaskDelay。
  • 时间片调度:每个任务都有相同的优先级,任务会运行固定的时间片个数或者遇到阻塞式的 API 函数,比如vTaskDelay,才会执行同优先级任务之间的任务切换

Tips: vTaskDelay()的延时参数是以tick为单位的,而tick一下具体是多少是在配置里写好的,当然也可以修改。


4. FreeRTOS任务间通信

FreeRTOS具有一般操作系统都具备的几种任务之间的通信方式,提供给用户的常用的通信方式有:消息队列、信号量、互斥锁(互斥信号量)、事件标志组以及任务通知等。

参考:
FreeRTOS消息队列_不秃也很强的博客-CSDN博客_freertos 消息队列

累了。。。。。下次再整理

加油呀一起学习的兄弟们~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值