FreeRTOS操作系统学习——任务通知

任务通知介绍

所谓任务通知,也可以反过来通知任务。在以往使用队列,信号量,事件组等等方法时,我们并不知道对方是谁,而在使用任务通知时,可以明确指定通知哪个任务。使用任务通知时,任务结构体的TCB就包含了内部对象,可以直接接收到别人发来的通知。

FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能,每个任务都有一个 32位的通知值,在大多数情况下,任务通知可以替代二值信号量、计数信号量、事件组,也可以替代长度为 1的队列(可以保存一个32位整数或指针值)。相对于以前使用 FreeRTOS内核通信的资源,必须创建队列、二进制信号量、计数信号量或事件组的情况,使用任务通知显然更灵活。

优势
  • 效率更高:使用任务通知来发送事件、数据给某个任务时,效率更高。比队列、信号量、事件组都有大的优势。
  • 更节省内存:使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体。
限制
  • 不能发送数据给 ISR:
    ISR 并没有任务结构体,所以无法使用任务通知的功能给 ISR 发送数据。但是
    ISR 可以使用任务通知的功能,发数据给任务。

  • 数据只能给该任务独享
    使用队列、信号量、事件组时,数据保存在这些结构体中,其他任务、 ISR 都可以访问这些数据。使用任务通知时,数据存放入目标任务中,只有它可以访问这些数据。在日常工作中,这个限制影响不大。因为很多场合是从多个数据源把数据发给某个任务,而不是把一个数据源的数据发给多个任务。

  • 无法缓冲数据
    使用队列时,假设队列深度为 N,那么它可以保持 N 个数据。
    使用任务通知时,任务结构体中只有一个任务通知值,只能保持一个数据。

  • 无法广播给多个任务
    使用事件组可以同时给多个任务发送事件。
    使用任务通知,只能发个一个任务。

  • 如果发送受阻,发送方无法进入阻塞状态等待
    假设队列已经满了,使用 xQueueSendToBack()给队列发送数据时,任务可以进入阻塞状态等待发送完成。使用任务通知时,即使对方无法接收数据,发送方也无法阻塞等待,只能即刻返回错误

任务通知使用

任务结构体

每个任务都有一个结构体: TCB(Task Control Block),里面有 2 个成员:

  • 一个是 uint8_t 类型,用来表示通知状态
  • 一个是 uint32_t 类型,用来表示通知值
typedef struct tskTaskControlBlock
{
......
/* configTASK_NOTIFICATION_ARRAY_ENTRIES = 1 */
volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];
}tskTCB;

通知状态有3种取值:

  • taskNOT_WAITING_NOTIFICATION:任务没有在等待通知
  • taskWAITING_NOTIFICATION:任务在等待通知
  • taskNOTIFICATION_RECEIVED:任务接收到了通知,也被称为 pending(有数据了,待处理)

通知值可以有很多种类型:

  • 计数值
  • 位(类似事件组)
  • 任意数值
操作函数

任务通知有 2 套函数,简化版、专业版,列表如下:

  • 简化版函数的使用比较简单,它实际上也是使用专业版函数实现的
  • 专业版函数支持很多参数,可以实现很多功能
    在这里插入图片描述
    xTaskNotifyGive
    在任务中使用 xTaskNotifyGive 函数,在 ISR 中使用 vTaskNotifyGiveFromISR 函数,都是直接给其他任务发送通知。使得通知值加一,并且使得通知状态变为“pending”,也就是taskNOTIFICATION_RECEIVED。
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );

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

ulTaskNotifyTake
可以使用ulTaskNotifyTake函数来取出通知值,如果通知值等于 0,则阻塞(可以指定超时时间),当通知值大于 0 时,任务从阻塞态进入就绪态。在 ulTaskNotifyTake 返回之前,还可以做些清理工作:把通知值减一,或者把通知值清零。

uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );

在这里插入图片描述
xTaskNotify
xTaskNotify 与 xTaskNotifyGive 函数功能类似,但是功能更强大,可以使用不同参数实现各类功能,比如:

  • 让接收任务的通知值加一:这时 xTaskNotify()等同于 xTaskNotifyGive()
  • 设置接收任务的通知值的某一位、某些位,这就是一个轻量级的、更高效的事件组
  • 把一个新值写入接收任务的通知值:上一次的通知值被读走后,写入才成功。这就是轻量级的、长度为 1 的队列
  • 用一个新值覆盖接收任务的通知值:无论上一次的通知值是否被读走,覆盖都成功。 类似
    xQueueOverwrite()函数,这就是轻量级的邮箱。
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );

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

BaseType_t xTaskNotifyFromISR
( 
TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
BaseType_t *pxHigherPriorityTaskWoken 
);

xTaskNotifyFromISR 函 数 跟 xTaskNotify 很 类 似 , 就 多 了 最 后 一 个 参 数
pxHigherPriorityTaskWoken。在很多ISR函数中,这个参数的作用都是类似的,使用场景如下:
在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/536587.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员的三重境界:码农,高级码农、程序员!

见字如面,我是军哥! 掐指一算,我在 IT 行业摸爬滚打 19 年了,见过的程序员至少大好几千,然后真正能称上程序员不到 10% ,绝大部分都是高级码农而已。 今天和你聊聊程序员的三个境界的差异,文章不…

未来已来:科技驱动的教育变革

我们的基础教育数百年来一成不变。学生们齐聚在一个物理空间,听老师现场授课。每节课时长和节奏几乎一致,严格按照课表进行。老师就像“讲台上的圣人”。这种模式千篇一律,并不适用于所有人。学生遇到不懂的问题,只能自己摸索或者…

【数据结构】详解时间复杂度和空间复杂度的计算

一、时间复杂度(执行的次数) 1.1时间复杂度的概念 1.2时间复杂度的表示方法 1.3算法复杂度的几种情况 1.4简单时间复杂度的计算 例一 例二 例三 1.5复杂时间复杂度的计算 例一:未优化冒泡排序时间复杂度 例二:经过优化…

JAVA初阶数据结构链表(2)双向链表( +专栏数据结构练习是完整版)

1.双向链表的结构(双向不带头不循环链表) 需要注意的一点就是,在jdk中的链表就是双向链表 一个节点有三个域 val(数值域) next(地址域) prev(前驱记录前一个节点的地址&#xff09…

Express学习(四)

使用Express写接口 创建基本的服务器 创建API路由模块 编写GET接口 编写POST接口 CORS跨域资源共享 什么是CORS CORS由一系列HTTP响应头组成,这些HTTP响应头决定浏览器是否阻止前端JS代码跨域获取资源。浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如…

yum安装mysql 数据库tab自动补全

centos7上面没有mysql,它的数据库名字叫做mariadb [rootlocalhost ~]#yum install mariadb-server -y [rootlocalhost ~]#systemctl start mariadb.service [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]#setenforce 0 [rootlocalhost ~]#ss -na…

Three.js点线几何空间图形代码

Three.js点线几何空间图形代码。效果如下 下载地址 Three.js点线几何空间图形代码

docker部署springboot jar包项目

docker部署springboot jar包项目 前提,服务器环境是docker环境,如果服务器没有安装docker,可以先安装docker环境。 各个环境安装docker: Ubuntu上安装Docker: ubuntu离线安装docker: CentOS7离线安装Docker&#xff1…

Python语言基础与应用-北京大学-陈斌-P40-39-基本扩展模块/上机练习:计时和文件处理-给算法计时-上机代码

Python语言基础与应用-北京大学-陈斌-P40-39-基本扩展模块/上机练习:计时和文件处理-给算法计时-上机代码 上机代码: # 基本扩展模块训练 给算法计时 def factorial(number): # 自定义一个计算阶乘的函数i 1result 1 # 变量 result 用来存储每个数的阶…

【论文阅读】Natural Adversarial Examples 自然对抗的例子

文章目录 一、文章概览(一)摘要(二)导论(三)相关工作 二、IMAGENET-A 和 IMAGENET-O(一)数据集构造方式(二)数据收集过程 三、模型的故障模式四、实验&#x…

Docker自建蜜罐系统【失陷检测、外网威胁感知、威胁情报】

项目地址: https://hfish.net Hfish是一款基于Docker的网络钓鱼平台,它能够帮助安全团队模拟各种网络钓鱼攻击,以测试和提高组织的安全防御能力。 Hfish的优点 为什么选择Hfish? 蜜罐通常被定义为具有轻量级检测能力、低误报率…

Qt中QCheckBox的三种状态设置

首先启用QCheckbox的tristate属性 //启用QCheckBox的tristate属性,使checkbox有三种状态。例: questionCheckBox->setTristate(true);//使用setCheckState(Qt::CheckState state)函数设置checkbox当前的状态。例: //Qt::CheckState是枚举…