Freertos3(事件标志组 任务通知 软件定时器 )

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)。

任务通知值的优势及劣势

  • 任务通知的优势

    • 效率更高:使用任务通知向任务发送事件或数据比使用队列、事件标志组或信号量快得多。
    • 使用内存更小:使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体。
  • 任务通知的劣势

    • 无法发送数据给ISRISR没有任务结构体,所以无法给ISR发送数据 。但是ISR可以使用任务通知的功能,发数据给任务。(不能给ISR发送数据,但是可以接收ISR发送的通知

    • 无法广播给多个任务 :任务通知只能是被指定的一个任务接收并处理 。(但是多个任务可以给一个任务发送任务通知,因为每个任务都有一个任务通知组只有xTaskNotifyindexed才有)

    • 无法缓存多个数据:任务通知是通过更新任务通知值来发送数据的,任务结构体中只有一个任务通知值,只能保持一个数据。

    • 发送受阻不支持阻塞 :发送方无法进入阻塞状态等待。(但是接收可以进入阻塞

3. 软件定时器

介绍

  • 是指具有定时功能的软件,可设置定时周期 ,当指定时间到达后要调用回调函数 (也称超时函数),用户在回调函数中处理信息。从定时器启动到其回调函数执行之间 的时间被称为定时器的周期。(缺点:精度不高)
  • 软件定时器服务任务 是任务调度器中的一个特殊任务,专门用于管理和维护软件定时器的正常运行如果configUSE_TIMERS 设置为1,
    • 在开启任务调度器的时候,会自动创建软件定时器服务的任务。
    • 它主要负责软件定时器超时的逻辑判断、
    • 调用超时软件定时器的超时回调函数、
    • 处理软件定时器命令队列。
    • 软件定时器的超时回调函数是由软件定时器服务任务调用的,软件定时器的超时回调函数本身不是任务,因此不能在该回调函数中使用可能会导致任务阻塞的 API 函数。

注意 :软件定时器的超时回调函数是在软件定时器服务任务中被调用的,服务任务不是专为某个定时器服务 的,它还要处理其他定时器。(类似于中断回调函数

  • 因此定时器的回调函数不要影响其他"人":
  1. 回调函数要尽快实行,不能进入阻塞状态,即不能调用那些会阻塞任务的 API 函数,如:vTaskDelay() 。(队列,信号量)
  2. 访问队列或者信号量的非零阻塞时间的 API 函数也不能调用

软件定时器的相关配置

  • 当FreeRTOS 的配置项configUSE_TIMERS 设置为1,在启动任务调度器时,会自动创建软件定时器的服务/守护任务prvTimerTask( )
  • l软件定时器服务任务的优先级为configTIMER_TASK_PRIORITY = 31
  • 定时器的命令队列长度为configTIMER_QUEUE_LENGTH = 5

软件定时器服务任务作用(prvTimerTask())

    1. 负责软件定时器超时逻辑判断
    1. 调用 超时软件定时器的超时回调函数
    1. 处理软件定时器命令队列

软件定时器的命令队列

  • FreeRTOS 提供了许多软件定时器相关的 API 函数,这些 API 函数大多都是往定时器的队列中写入消息 (发送命令),这个队列叫做软件定时器命令队列 ,是提供给 FreeRTOS 中的软件定时器使用的,用户是不能直接访问的。

实现逻辑图解

定时器状态

  • 休眠态:软件定时器可以通过其句柄被引用,但因为没有运行,所以其定时超时回调函数不会被执行。
  • 运行态:运行态的定时器,当指定时间到达之后,它的超时回调函数会被调用。
  • 如何让软件定时器从休眠态转变为运行态

    • 答:发送命令队列。
  • 单次回调函数

  • 周期回调函数

相关推荐
写代码的小球11 分钟前
求模运算符c
算法
大千AI助手4 小时前
DTW模版匹配:弹性对齐的时间序列相似度度量算法
人工智能·算法·机器学习·数据挖掘·模版匹配·dtw模版匹配
YuTaoShao5 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
生态遥感监测笔记5 小时前
GEE利用已有土地利用数据选取样本点并进行分类
人工智能·算法·机器学习·分类·数据挖掘
Tony沈哲6 小时前
macOS 上为 Compose Desktop 构建跨架构图像处理 dylib:OpenCV + libraw + libheif 实践指南
opencv·算法
刘海东刘海东6 小时前
结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
人工智能·算法·机器学习
pumpkin845147 小时前
Rust 调用 C 函数的 FFI
c语言·算法·rust
挺菜的7 小时前
【算法刷题记录(简单题)003】统计大写字母个数(java代码实现)
java·数据结构·算法
mit6.8247 小时前
7.6 优先队列| dijkstra | hash | rust
算法