1.事件标志组
- FreeRTOS中的事件标志组(Event Flags Group)提供了一种轻量级的机制,用于在任务之间传递信息和同步操作。
- 如果 configUSE_16_BIT_TICKS 设置为 1,则事件组内实现的位数(或标志数)为 8; 如果 configUSE_16_BIT_TICKS 设置为 0,则为 24。
- 事件标志组和时间标志位区别
-
事件标志位:用一个位,来表示事件是否发生。
-
事件标志组:是一组事件标志位的合集。可以简单的理解事件标志组,就是一个整数。
-
事件标志组的标志变量
- 一个事件组就包含了一个EventBits_t数据类型的变量,变量类型EventBits_t数据类型的定义如下所示
arduino
typedef TickType_t EventBits_t;
#if ( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#else
typedef uint32_t TickType_t;
#endif
#define configUSE_16_BIT_TICKS 0
-
因此,EventBits_t 实际上是一个 16 位或 32 位无符号的数据类型
-
注意:虽然使用了32为/16位无符号的数据类型变量来存储事件标志,但其中的高8为作用是存储事件标志组的控制信息 ,低24位/8位的作用才是存储事件标志,所以说一个事件标志组最多可以存储24个事件标志!
-
信号量和事件标志组的区别(感觉没好比,其实感觉像寄存器)
2.任务通知
- 任务通知 :用来通知任务的,任务控制块 中的结构体成员变量ulNotifiedValue就是这个通知值。
区别(相比于其他任务消息通知)
- 使用队列、信号量、事件标志组时都需要另外创建一个结构体,通过中间的结构体进行间接通信
-
使用任务通知时,任务结构体TCB中就包含了内部对象 ,可以直接接收别人发过来的"通知"。
-
每个 RTOS 任务都有一个任务通知组,每条通知均独立运行,都有"挂起"或"非挂起"的通知状态,以及一个 32 位通知值。常量 configTASK_NOTIFICATION_ARRAY_ENTRIES 可设置任务通知组中的索引数量。在 FreeRTOS V10.4.0 版本前,任务只有单条任务通知(即只能一对一),没有任务通知组。
任务通知值的更新方式
- 不覆盖接收任务的通知值
- 覆盖接收任务的通知值
- 更新接收任务通知值的一位或多位
- 对值进行增量(添加 1)。
任务通知值的优势及劣势
-
任务通知的优势:
- 效率更高:使用任务通知向任务发送事件或数据比使用队列、事件标志组或信号量快得多。
- 使用内存更小:使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体。
-
任务通知的劣势:
-
无法发送数据给ISR :ISR没有任务结构体,所以无法给ISR发送数据 。但是ISR可以使用任务通知的功能,发数据给任务。(不能给ISR发送数据,但是可以接收ISR发送的通知)
-
无法广播给多个任务 :任务通知只能是被指定的一个任务接收并处理 。(但是多个任务可以给一个任务发送任务通知,因为每个任务都有一个任务通知组只有xTaskNotifyindexed才有)
-
无法缓存多个数据:任务通知是通过更新任务通知值来发送数据的,任务结构体中只有一个任务通知值,只能保持一个数据。
-
发送受阻不支持阻塞 :发送方无法进入阻塞状态等待。(但是接收可以进入阻塞)
-
3. 软件定时器
介绍
- 是指具有定时功能的软件,可设置定时周期 ,当指定时间到达后要调用回调函数 (也称超时函数),用户在回调函数中处理信息。从定时器启动到其回调函数执行之间 的时间被称为定时器的周期。(缺点:精度不高)
- 软件定时器服务任务 是任务调度器中的一个特殊任务,专门用于管理和维护软件定时器的正常运行如果configUSE_TIMERS 设置为1,
- 在开启任务调度器的时候,会自动创建软件定时器服务的任务。
- 它主要负责软件定时器超时的逻辑判断、
- 调用超时软件定时器的超时回调函数、
- 处理软件定时器命令队列。
- 软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的 API 函数。
注意 :软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专为某个定时器服务 的,它还要处理其他定时器。(类似于中断回调函数)
- 因此定时器的回调函数不要影响其他"人":
- 回调函数要尽快实行,不能进入阻塞状态,即不能调用那些会阻塞任务的 API 函数,如:vTaskDelay() 。(队列,信号量)
- 访问队列或者信号量的非零阻塞时间的 API 函数也不能调用。
软件定时器的相关配置
- 当FreeRTOS 的配置项configUSE_TIMERS 设置为1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask( )。
- l软件定时器服务任务的优先级为configTIMER_TASK_PRIORITY = 31。
- 定时器的命令队列长度为configTIMER_QUEUE_LENGTH = 5。
软件定时器服务任务作用(prvTimerTask())
-
- 负责软件定时器超时逻辑判断。
-
- 调用 超时软件定时器的超时回调函数。
-
- 处理软件定时器命令队列。
软件定时器的命令队列
- FreeRTOS 提供了许多软件定时器相关的 API 函数,这些 API 函数大多都是往定时器的队列中写入消息 (发送命令),这个队列叫做软件定时器命令队列 ,是提供给 FreeRTOS 中的软件定时器使用的,用户是不能直接访问的。
实现逻辑图解
定时器状态
- 休眠态:软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行。
- 运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用。
-
如何让软件定时器从休眠态转变为运行态?
- 答:发送命令队列。
-
单次回调函数
-
周期回调函数