freeRTOS--任务通知

一、什么是任务通知

使用任务通知可以替换二值信号量、计数信号量、事件标志组,可以替代长度为1的队列,任务通知速度更快、使用的RAM更少。

任务通知值的更新方式:

  1. 发消息给任务,如果有通知未读,不覆盖通知值。
  2. 发消息给任务,直接覆盖通知值。
  3. 发消息给任务,设置通知值的一个或多个 位
  4. 发送消息给任务,递增通知值

任务通知的相关API函数:

1.发送通知

1.发送通知
函数描述
xTaskNotify()
发送通知,带有通知值
xTaskNotifyAndQuery()
发送通知,带有通知值并且保留接收任务的原通知值
xTaskNotifyGive()

发送通知,不带通知值

xTaskNotifyFromISR()
在中断中发送任务通知
vTaskNotifyGiveFromISR()
在中断中发送任务通知

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

 

xTaskToNotify:需要接收通知的任务句柄;
ulValue:用于更新接收任务通知值, 具体如何更新由形参 eAction 决定;
eAction:一个枚举,代表如何使用任务通知的值;

枚举
枚举值描述
eNoAction
发送通知,但不更新值(参数 ulValue 未使用)
eSetBits
被通知任务的通知值按位或 ulValue 。(某些场景下可代替事件组,效率更高)

 

eSetValueWithOverWrite
被通知任务的通知值设置为 ulValue 。(某些场景下可代替 xQueueOverwrite ,效率更高)
eSetValueWithoutOverwrite
如果被通知的任务当前没有通知,则被通知的任务的通知值 设为ulValue
如果被通知任务没有取走上一个通知,又接收到了一个通 知,则这次通知值丢弃,在这种情况下视为调用失败并返回 pdFALSE (某些场景下可代替 xQueueSend ,效率更高)

返回值:如果被通知任务还没取走上一个通知,又接收了一个通知,则这次通知值未能更新并返回
pdFALSE, 而其他情况均返回pdPASS。

BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify,
uint32_t ulValue,
eNotifyAction eAction,
uint32_t *pulPreviousNotifyValue );
参数:
xTaskToNotify:需要接收通知的任务句柄; 
ulValue:用于更新接收任务通知值, 具体如何更新由形参 eAction 决定; 
eAction:一个枚举,代表如何使用任务通知的值;
pulPreviousNotifyValue:对象任务的上一个任务通知值,如果为 NULL, 则不需要回传, 这个时
候就等价于函数 xTaskNotify()。返回值:
如果被通知任务还没取走上一个通知,又接收了一个通知,则这次通知值未能更新并返回pdFALSE, 而其他情况均返回pdPASS。
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );//参数:xTaskToNotify:接收通知的任务句柄, 并让其自身的任务通知值加 1。
//返回值:总是返回pdPASS。

2.等待通知

等待通知 API 函数只能用在任务,不可应用于中断中!

等待通知

函数描述
ulTaskNotifyTake()
获取任务通知,可以设置在退出此函数的时候将任务通知值清零或者减 一。当任务通知用作二值信号量或者计数信号量的时候,使用此函数来 获取信号量。
xTaskNotifyWait()
获取任务通知,比  ulTaskNotifyTak() 更为复杂,可获取通知值和清除通 知值的指定位

 

uint32_t ulTaskNotifyTake ( BaseType_t xClearCountOnExit , TickType_t xTicksToWait );

参数:xClearCountOnExit:指定在成功接收通知后,将通知值清零或减 1pdTRUE:把通知值清零(二 值信号量);pdFALSE:把通知值减一(计数型信号量); xTicksToWait:阻塞等待任务通知值 的最大时间;

返回值:0:接收失败 非0:接收成功,返回任务通知的通知值

BaseType_t xTaskNotifyWait ( uint32_t ulBitsToClearOnEntry ,
uint32_t ulBitsToClearOnExit ,
uint32_t * pulNotificationValue ,
TickType_t xTicksToWait );
ulBitsToClearOnEntry :函数执行前清零任务通知值那些位 。
ulBitsToClearOnExit :表示在函数退出前,清零任务通知值那些位,在清 0 前,接收到的任务通知值会先被保存到形参 *pulNotificationValue 中。
pulNotificationValue :用于保存接收到的任务通知值。 如果 不需要使 用,则设置为 NULL 即可 。
xTicksToWait :等待消息通知的最大等待时间。

 二、实验

1.模拟二值信号量和计数型信号量

void StartTaskSend(void const * argument)
{for(;;){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET){xTaskNotifyGive(TaskReceiveHandle);//printf("任务通知:模拟二值信号量发送成功 !\r\n");printf("任务通知:模拟计数型信号量发送成功 !\r\n");}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET);}osDelay(1);}
}
void StartTaskReceive(void const * argument)
{uint32_t rev;for(;;){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == RESET){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == RESET){//rev = ulTaskNotifyTake(pdTRUE,portMAX_DELAY);//当为pdTRUE的时候,模拟的为二值信号量rev = ulTaskNotifyTake(pdFALSE,portMAX_DELAY);//当为pdFALSE的时候,模拟的是计数型信号量if(rev != 0)//printf("任务通知:模拟二值信号量接收成功 !\r\n");printf("任务通知:模拟计数型信号量接收成功 ! rev=%d \r\n",rev);}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == RESET);}osDelay(1);}}

模拟计数型信号量实验结果:

模拟二值信号量结果:

2.模拟事件标志组和模拟邮箱

2.1模拟事件标志组

void StartTaskSend(void const * argument)
{uint16_t buf = 100;BaseType_t status;for(;;){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){osDelay(20);if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){	printf("将bit0位置为1\r\n");xTaskNotify(taskReceiveHandle,0x01,eSetBits);}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET);}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET){osDelay(20);if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET){	printf("将bit1位置为1\r\n");xTaskNotify(taskReceiveHandle,0x02,eSetBits);}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET);}osDelay(10);}}
void StartTaskRecive(void const * argument)
{uint32_t notify_val = 0, event_bit = 0;for(;;){	xTaskNotifyWait(0,0XFFFFFFFF,&notify_val,portMAX_DELAY);if(notify_val & 0x01)event_bit |= 0x01;if(notify_val & 0x02)event_bit |= 0x02;if(event_bit == (0x01 | 0x02)){printf("任务通知模拟事件标志组接收成功!\r\n");event_bit = 0; }osDelay(1);}}

实验结果:

 2.2 模拟邮箱

StartTaskSend:

void StartTaskSend(void const * argument)
{uint16_t buf = 100;BaseType_t status;for(;;){if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){osDelay(20);if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){	printf("按键1按下\r\n");xTaskNotify(taskReceiveHandle,1,eSetValueWithOverwrite);//相比于事件标志组,改为了eSetValuewithOverwrit,ulValue变成了1}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET);}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET){osDelay(20);if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET){	printf("按键2按下\r\n");xTaskNotify(taskReceiveHandle,2,eSetValueWithOverwrite);//eSetValueWithoutOverwrite相比于eSetValueWithOverwrite会复写,不影响最终实验结果}while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1)==GPIO_PIN_RESET);}osDelay(10);}}

StartTaskRecive:

void StartTaskRecive(void const * argument)
{uint32_t notify_val = 0, event_bit = 0;for(;;){	xTaskNotifyWait(0,0XFFFFFFFF,&notify_val,portMAX_DELAY);printf("接收到的通知值为:%d\r\n",notify_val);osDelay(1);}}

实验结果:

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

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

相关文章

疑似openAI的BUG

Chat gpt 4.0 『最新数据2023年』 Chat gpt 3.5 智商不在线『最近数据2021年9月左右』 发现了疑似openAI的一个bug 通过固定连接访问就可以用chatgpt4.0 4.0版本的费用为20美金一个月 https://chat.openai.com/?modelgpt-4-gizmo

【深度学习】吴恩达课程笔记(五)——超参数调试、batch norm、Softmax 回归

笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ 【吴恩达课程笔记专栏】 【深度学习】吴恩达课程笔记(一)——深度学习概论、神经网络基础 【深度学习】吴恩达课程笔记(二)——浅层神经网络、深层神经网络 【深度学习】吴恩达课程笔记(三)——参数VS超参数、深度…

基于JAVA SpringBoot和HTML美食网站博客程序设计

摘要 美食网站是一个提供各种美食信息和食谱的网站,旨在帮助用户发现、学习和分享美食。旨在探讨美食网站在现代社会中的重要性和影响。随着互联网的普及,越来越多的人开始使用美食网站来获取各种美食信息和食谱。这些网站不仅提供了方便快捷的搜索功能&…

SpringBoot配置数据库密码加密的方法

由于系统安全的考虑,配置文件中不能出现明文密码的问题,本文就给大家详细介绍下springboot配置数据库密码加密的方法,下面话不多说了,来一起看看详细的介绍吧,需要的朋友可以参考下 1.导入依赖 <!--数据库密码加密--> <dependency><groupId>com.github.uli…

17. Series.dt.month-提取日期数据中的月份信息

【目录】 文章目录 17. Series.dt.month-提取日期数据中的月份信息1. 知识回顾-创建一个Series对象2. 知识回顾-pd.to_datetime()将数据转换为pandas中的日期时间格式3. 实例化类相关知识4. Series.dt.month是什么&#xff1f;5. 如何使用Series.dt.month&#xff1f;6. Series…

iApp祁天社区UI成品源码 功能齐全的社区应用

iApp祁天社区UI成品源码是一个非常实用的资源&#xff0c;提供了完整的源代码&#xff0c;可以帮助您快速搭建一个功能齐全的社区应用。 这个源码具有丰富的UI设计&#xff0c;经过精心调整和优化&#xff0c;确保用户体验流畅而舒适。它不仅具备基本的社区功能&#xff0c;如…

轮播图(多个一起轮播)

效果图 class MainActivity : Activity(), Runnable {private lateinit var viewPager: ViewPagerprivate lateinit var bannerAdapter: BannerAdapterprivate val images ArrayList<Int>() // 存储图片资源的列表private val handler Handler() // 用于定时发送消息…

基于 selenium 实现网站图片采集

写在前面 有小伙伴选题&#xff0c;简单整理理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是人的逃避方式&#xff0c;是对…

基于SSM的学生疫情信息管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Ubuntu 22.04 LTS ffmpeg mp4 gif 添加图片水印

ffmpeg编译安装6.0.1&#xff0c;参考 Ubuntu 20.04 LTS ffmpeg gif mp4 互转 许编译安装ffmpeg &#xff1b;解决gif转mp4转换后无法播放问题-CSDN博客 准备一个logo MP4添加水印 ffmpeg -i 2.mp4 -vf "movielogo.png[watermark];[in][watermark]overlayx10:y10[out]&…

大功率电源芯片WD5030L

电源管理芯片作为现代电子设备中最关键的元件之一&#xff0c;直接影响着设备的性能和效率。而大功率电源芯片作为电源管理芯片中的一种&#xff0c;其性能和应用领域更加广泛。本文将介绍一款具有宽VIN输入范围、高效率和多种优良性能的大功率电源芯片WD5030L&#xff0c;并探…

通付盾Web3专题 | KYT/AML:Web3合规展业的必要条件

与传统证券一样&#xff0c;基于区块链技术发展出来的虚拟资产交易所经历了快速发展而缺乏有效监管的行业早期。除了科技光环加持的各种区块链项目方、造富神话之外&#xff0c;交易所遭到黑客攻击、内部偷窃作恶、甚至经营主体异常而致使投资人血本无归的案例亦令人触目惊心。…

STM32 I2C详解

STM32 I2C详解 I2C简介 I2C&#xff08;Inter IC Bus&#xff09;是由Philips公司开发的一种通用数据总线 两根通信线&#xff1a; SCL&#xff08;Serial Clock&#xff09;串行时钟线&#xff0c;使用同步的时序&#xff0c;降低对硬件的依赖&#xff0c;同时同步的时序稳定…

udp多点通信-广播-组播

单播 每次只有两个实体相互通信&#xff0c;发送端和接收端都是唯一确定的。 广播 主机之间的一对多的通信所有的主机都可以接收到广播消息(不管你是否需要)广播禁止穿过路由器&#xff08;只能做局域网通信&#xff09;只有UDP可以广播广播地址 有效网络号全是1的主机号 192.1…

酷开系统 酷开科技,将家庭娱乐推向新高潮

在当今数字化时代&#xff0c;家庭娱乐已经成为人们日常生活中不可或缺的一部分。如果你厌倦了传统的家庭娱乐方式&#xff0c;想要一种全新的、充满惊喜的娱乐体验&#xff0c;那么&#xff0c;不妨进入到酷开科技的世界&#xff0c;作为智能电视行业领军企业&#xff0c;酷开…

Dubbo协议详解

前言特点应用场景Dubbo协议示例Dubbo协议的不足拓展 前言 Dubbo协议是一种高性能、轻量级的开源RPC框架&#xff0c;主要设计目的是解决分布式系统中服务调用的一些常见问题&#xff0c;例如服务负载均衡、服务注册中心、服务的远程调用等。它支持多种语言&#xff0c;例如Jav…

Day10—SQL那些事(特殊场景的查询)

文章目录 1、只想查一个字段却不得不左连接好多张表2、左连接的时候只想取最后一条数据 1、只想查一个字段却不得不左连接好多张表 只想查一个字段却不得不左连接好多张表&#xff0c;而且因为左连接的表太多还导致查出来的数据重复 原先的sql SELECTsph.po_num,chh.visa_ex…

向量以及矩阵

0.前言 好了那我们新的征程也即将开始&#xff0c;那么在此呢我也先啰嗦两句&#xff0c;本篇文章介绍数学基础的部分&#xff0c;因为个人精力有限我不可能没一字一句都讲得非常清楚明白&#xff0c;像矩阵乘法之类的一些基础知识我都是默认你会了&#xff08;还不会的同学推…

Nas搭建webdav服务器并同步Zotero科研文献

无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器 文章目录 无需云盘&#xff0c;不限流量实现Zotero跨平台同步&#xff1a;内网穿透私有WebDAV服务器一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zote…

认识Tomcat

文章目录 什么是tomcat&#xff1f;tomcat的使用tomcat的下载tomcat的目录结构tomcat的启动在tomcat上部署页面通过浏览器访问部署的页面 学习servlet的原因 什么是tomcat&#xff1f; 盖棺定论&#xff1a;Tomcat是一个HTTP服务器。 我们接下来要长期学习的东西都是关于前后…