【FreeRTOS基础入门】任务通知

文章目录

  • 前言
  • 一、任务通知介绍
    • 1.1 任务通知怎么通信
    • 1.2 任务通知与其他通信方式的区别
    • 1.3 优势及限制
      • 任务通知的优势
      • 任务通知的限制
    • 1.4 内部原理
  • 二、任务通知的使用
    • 2.1 发出与接收通知简化版
    • 2.1 发出与接收通知专业版
  • 总结


前言

FreeRTOS 提供了丰富而灵活的任务通知机制,为多任务协作提供了一种有效的方式。任务通知允许任务之间进行轻量级的信息传递,从而实现更加紧密的协同工作。在本篇文章中,我们将深入了解 FreeRTOS 中的任务通知,探索其基础概念和简单用法,帮助读者更好地理解和应用这一关键特性。


一、任务通知介绍

1.1 任务通知怎么通信

在任务通知中,我们可以直接把需要通知的东西发给对方就行了:
在这里插入图片描述

1.2 任务通知与其他通信方式的区别

使用队列、信号量、事件组时,我们都要事先创建对应的结构体,双方通过中间的结构体通信:
在这里插入图片描述
但我们的任务通知只需要对方的TCB结构体即可任务结构体 TCB 中就包含了内部对象,可以直接接收别人发过来的"通知":
在这里插入图片描述

1.3 优势及限制

任务通知的优势

 效率更高:使用任务通知来发送事件、数据给某个任务时,效率更高。比队列、信号量、事件组都有大的优势。
 更节省内存:使用其他方法时都要先创建对应的结构体,使用任务通知时无需额外创建结构体。

任务通知的限制

 不能发送数据给 ISR:
ISR 并没有任务结构体,所以无法使用任务通知的功能给 ISR 发送数据。但是 ISR可以使用任务通知的功能,发数据给任务。
 数据只能给该任务独享
使用队列、信号量、事件组时,数据保存在这些结构体中,其他任务、ISR 都可以访问这些数据。使用任务通知时,数据存放入目标任务中,只有它可以访问这些数据。
在日常工作中,这个限制影响不大。因为很多场合是从多个数据源把数据发给某个任务,而不是把一个数据源的数据发给多个任务。
 无法缓冲数据
使用队列时,假设队列深度为 N,那么它可以保持 N 个数据。使用任务通知时,任务结构体中只有一个任务通知值,只能保持一个数据。
 无法广播给多个任务
使用事件组可以同时给多个任务发送事件。使用任务通知,只能发个一个任务。
 如果发送受阻,发送方无法进入阻塞状态等待假设队列已经满了,使用 xQueueSendToBack()给队列发送数据时,任务可以进入阻塞状态等待发送完成。使用任务通知时,即使对方无法接收数据,发送方也无法阻塞等待,只能即刻返回错误

1.4 内部原理

在TCB_t里面,存储着这两个成员:ulNotifiedValueucNotifyState他们分别表示通知的数据和通知的状态,如下图所示:
在这里插入图片描述
通知状态有 3 种取值:
 taskNOT_WAITING_NOTIFICATION:任务没有在等待通知
 taskWAITING_NOTIFICATION:任务在等待通知
 taskNOTIFICATION_RECEIVED:任务接收到了通知,也被称为 pending(有数据了,待处理)

通知值可以有很多种类型:
 计数值
 位(类似事件组)
 任意数值

二、任务通知的使用

如果你想使用任务通知,应该加上:configUSE_TASK_NOTIFICATIONS这个宏

任务通知有 2 套函数,简化版、专业版,列表如下:
 简化版函数的使用比较简单,它实际上也是使用专业版函数实现的
 专业版函数支持很多参数,可以实现很多功能

2.1 发出与接收通知简化版

在任务中发送通知可以使用下面这个函数:

BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );

他的参数是任务的handle。他会使对方任务的通知值加1,并使得通知状态变为"pending",也就是 taskNOTIFICATION_RECEIVED,表示有数据了、待处理

在中断中发送通知可以使用下面这个函数:

void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );

我们可以使用下面这个函数来等待接收通知:

uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );

参数1为是否清除值,在退出此函数之后.参数2为等待时间

 如果通知值等于 0,则阻塞(可以指定超时时间)
 当通知值大于 0 时,任务从阻塞态进入就绪态

2.1 发出与接收通知专业版

在任务中发送通知可以使用下面这个函数:

BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );

参数2为你要为那个任务的TCB的value设置为多少。
eNotifyAction 参数说明:

  1. eNoAction 仅仅是更新通知状态为"pending",未使用 ulValue。这个选项相当于轻量级的、更高效的二进制信号量。
  2. eSetBits 通知值 = 原来的通知值 | ulValue,按位或。相当于轻量级的、更高效的事件组。
  3. eIncrement 通知值 = 原来的通知值 + 1,未使用 ulValue。相当于轻量级的、更高效的二进制信号量、计数型信号量。相当于 xTaskNotifyGive()函数。eSetValueWithoutOverwrite 不覆盖。如果通知状态为"pending"(表示有数据未读),则此次调用 xTaskNotify 不做任何事,返回 pdFAIL。如果通知状态不是"pending"(表示没有新数据),则:通知值 = ulValue。
  4. eSetValueWithOverwrite 覆盖。无论如何,不管通知状态是否为"pendng",通知值 = ulValue。

在中断中发送通知可以使用下面这个函数:

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

我们可以使用下面这个函数来等待通知:

BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, 
uint32_t *pulNotificationValue, TickType_t xTicksToWait );

参数1为:在 xTaskNotifyWait 入口处,要清除通知值的哪些位?通知状态不是"pending"的情况下,才会清除。
参数2为:在 xTaskNotifyWait 出口处,如果不是因为超时推出,而是因为得到了数据而退出时:通知值 = 通知值 & ~(ulBitsToClearOnExit)。
参数3用来取得对应的值
参数4为等待时间


总结

任务通知是 FreeRTOS 中一个强大的工具,为多任务系统中的任务间通信提供了高效可靠的机制。通过任务通知,任务可以在不同的优先级下进行快速的同步和信息传递,避免了使用更为复杂的信号量和队列时可能引入的开销。了解和善用任务通知,可以让我们更好地设计和优化 FreeRTOS 应用程序,提高系统的效率和可维护性。

在使用任务通知时,需要注意合理规划任务间的通信和同步需求,避免过度使用通知,以确保系统的可靠性。通过深入学习 FreeRTOS 的任务通知机制,我们可以更加灵活地掌握多任务编程的技巧,提高嵌入式系统的性能和响应能力。

在日益复杂的嵌入式应用中,任务通知作为 FreeRTOS 提供的重要特性,为开发者提供了更多处理任务间协作的选择。通过深入理解和应用任务通知,我们能够更加高效地构建稳定可靠的嵌入式系统。希望本文能够为初学者提供一个简明易懂的入门指南,帮助读者更好地利用 FreeRTOS 的任务通知功能。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于51单片机的婴儿看护监测系统[proteus仿真]

基于51单片机的婴儿看护监测系统[proteus仿真] 婴儿看护检测系统这个题目算是课程设计和毕业设计中少见的题目,本期是一个基于51单片机的婴儿看护监测系统[proteus仿真] 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】,赞赏任意文章 2&a…

openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制

文章目录 openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制226.1 适用场景226.2 非适用场景 openGauss学习笔记-226 openGauss性能调优-系统调优-配置LLVM-LLVM适用场景与限制 226.1 适用场景 支持LLVM的表达式 查询语句中存在以下的表达式支持…

优化设备维修流程:易点易动设备管理系统的设备维修管理策略

在现代企业中,设备是生产运营的核心要素之一。然而,设备故障和维修常常给企业带来诸多困扰和成本。为了提高设备维修的效率和质量,许多企业开始采用先进的设备管理系统。在这方面,易点易动设备管理系统以其卓越的设备维修管理策略…

2023年Q4,SSD出货量下降5%,但存储容量增长9.6%

2023年第四季度(4Q23)的SSD市场表现呈现出单位出货量下降,但存储容量增长的趋势。具体数据显示,该季度SSD总出货量下降5%,降至8820万台; 而存储容量则增长9.6%,达到85.1EB。预计2023全年SSD总容…

前端基于Verdaccio搭建私有npm仓库,上传npm插件包,及下载使用自己的npm插件包

文章目录 一、原理二、常用的仓库地址三、优势四、准备环境六、使用verdaccio搭建私有npm服务1、安装2、运行3、配置config.yaml,使局域网下能共享访问,否则只能本机访问。4、重新运行 七、npm常见操作查看当前用户信息查看源地址切换源地址删除源地址创…

【Linux】Linux调试器-gdb使用

1. 背景 程序的发布方式有两种,debug模式和release模式 Linux gcc/g出来的二进制程序,默认是release模式 要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项 2. 开始使用 gdb binFile 退出: ctrl d 或 quit 调…

【C语言】注释

🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:C语言 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步&…

校园公寓管理系统

校园公寓管理系统是一种专为提升高校住宿管理效率而设计的综合性智能解决方案。这一系统利用现代信息技术优化和简化了传统的住宿管理流程,极大地提高了管理工作的透明度和学生的住宿体验。 一、系统组成 校园公寓管理系统一般包括住宿分配、安全监控、费用管理、维…

java面试题之SpringMVC篇

Spring MVC的工作原理 Spring MVC的工作原理如下: DispatcherServlet 接收用户的请求找到用于处理request的 handler 和 Interceptors,构造成 HandlerExecutionChain 执行链找到 handler 相对应的 HandlerAdapter执行所有注册拦截器的preHandler方法调…

树莓派E: You don t have enough free space in /var/cache/apt/archives/.

在树莓派实际使用当中,我们会发现SD卡的存储并没有得到充分的利用,是否有办法让可用空间变的更大,毫无疑问肯定是有的,不然我就不在这里废话了。 使用raspi-config扩容 一、df -h查看可用空间 首先输入"df -h"命令可…

typescrip接口 interface详解,以及ts实现多态

ts 接口 当一个对象类型被多次使用时,一般会使用接口(interface)来描述对象的类型,达到复用的目的 示例如下 当一个对象类型被多次使用时,可以看到,很明显代码有大量的冗余 let personTom: { name: string, age?: number, sayHi(name: string): void } {name: Tom,sayHi(n…

Java Web(七)__Tomcat(二)

Tomcat工作模式 Tomcat作为Servlet容器,有以下三种工作模式。 1)独立的Servlet容器,由Java虚拟机进程来运行 Tomcat作为独立的Web服务器来单独运行,Servlet容器组件作为Web服务器中的一部分而存在。这是Tomcat的默认工作模式。…

一文弄明白KeyedProcessFunction函数

引言 KeyedProcessFunction是Flink用于处理KeyedStream的数据集合,它比ProcessFunction拥有更多特性,例如状态处理和定时器功能等。接下来就一起来了解下这个函数吧 正文 了解一个函数怎么用最权威的地方就是 官方文档 以及注解,KeyedProc…

Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型

作者: 来自 Elastic David Hope ChatGPT 现在非常火爆,甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员,我对这项技术的可能性感到非常兴奋。 我看到的情况是,基于 ChatGPT 的解决方案将会呈指数级…

C++实现归并排序题目

目录 例1 例2 例3 例4 例1 912. 排序数组 参考代码 class Solution { public:vector<int> tmpnums;vector<int> sortArray(vector<int>& nums) {tmpnums.resize(nums.size());mergeSort(nums, 0, nums.size() - 1);return nums;}void mergeSort(vector…

如何使用rocketmq实现分布式事务?

什么是rocketmq事务消息 事务消息是 Apache RocketMQ 提供的一种高级消息类型&#xff0c;支持在分布式场景下保障消息生产和本地事务的最终一致性。 RocketMQ的分布式事务又称为“半消息事务”。 事务消息处理流程 RocketMQ是靠半消息机制实现分布式事务 事务消息&#x…

OpenAI 的 GPTs 提示词泄露攻击与防护实战:防御卷(一)

前面的OpenAI DevDay活动上&#xff0c;GPTs技术的亮相引起了广泛关注。随着GPTs的创建权限开放给Plus用户&#xff0c;社区里迅速涌现了各种有趣的GPT应用&#xff0c;这些都是利用了Prompt提示词的灵活性。这不仅展示了技术的创新潜力&#xff0c;也让人们开始思考如何获取他…

C++学习Day09之系统标准异常

目录 一、程序及输出1.1 系统标准异常示例1.2 标准异常表格 二、分析与总结 一、程序及输出 1.1 系统标准异常示例 #include<iostream> using namespace std; #include <stdexcept> // std 标准 except 异常class Person { public:Person(int age){if (age <…

短小精悍的npm入门级保姆教程,一篇包会

npm是什么&#xff1f; npm是一个强大的包管理工具&#xff0c;它使开发人员能够轻松地安装、更新和管理项目依赖的包。通过初始化一个package.json 文件&#xff0c;我们可以描述你的项目并记录其依赖关系。使用npm install命令&#xff0c;我们可以安装和管理包。使用npm pu…

SQL注入漏洞解析

什么是SQL注入 原理&#xff1a; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服…