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 中的软件定时器使用的,用户是不能直接访问的。

实现逻辑图解

定时器状态

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

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

  • 周期回调函数

相关推荐
不吃元西几秒前
leetcode 118. 杨辉三角
算法·leetcode·职场和发展
wen__xvn7 分钟前
每日一题洛谷P8716 [蓝桥杯 2020 省 AB2] 回文日期c++
c++·算法·蓝桥杯
梭七y11 分钟前
【力扣hot100题】(027)两数相加
算法·leetcode·职场和发展
破东风15 分钟前
leetcode每日一题:向字符串添加空格
算法·leetcode·模拟
rigidwill66617 分钟前
LeetCode hot 100—二叉搜索树中第K小的元素
数据结构·c++·算法·leetcode·职场和发展
银河小铁骑plus21 分钟前
力扣hot100_贪心算法
算法·leetcode·贪心算法
小郝 小郝24 分钟前
(C语言)指针运算 习题练习1.2(压轴难题)
java·开发语言·算法
welkin37 分钟前
算法区间合并问题
前端·算法
星途码客1 小时前
C++位运算精要:高效解题的利器
java·c++·算法
东雁西飞1 小时前
MATLAB 控制系统设计与仿真 - 33
开发语言·算法·matlab·机器人·自动控制