FreeRTOS-任务通知

概述

不同于队列、信号量、互斥量,有一个额外的空间(结构体)作为通信的纽带,任务通知只需借助任务TCB中的相关变量,无需另外创建;

下面是TCB中有关任务通知的变量:

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;

其中,ulNotifiedValue是通知值,ucNotifyState是通知状态。由此定义可知通知值、通知状态在同一时刻都只能存储一个数据/状态。(configTASK_NOTIFICATION_ARRAY_ENTRIES = 1)

通知状态具体包含以下几种:

##define taskNOT_WAITING_NOTIFICATION          ( ( uint8_t ) 0 )//也是初始状态 
##define taskWAITING_NOTIFICATION              ( ( uint8_t ) 1 )   
##define taskNOTIFICATION_RECEIVED             ( ( uint8_t ) 2 )

可见,通知状态是站在接收者的角度,即当任务作为通知的接收者时的状态。其中taskNOTIFICATION_RECEIVED也被称作pending(待处理的)。

函数

任务通知的函数有简化版和专业版:

1. 简化版

发出通知

BseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
/*中断过程中使用*/
void vTaskNotifyGiveFromISR( TaskHandle_t  xTaskHandle, BseType_t *pxHigherPriorityTaskWoken );

xTaskNotifyGive函数必定返回pdPASS;
xTaskToNotify、xTaskHandle:通知给哪个任务;
pxHigherPriorityTaskWoken:有更高优先级被唤醒时会被设置为pdTRUE,是提示需要进行上下文切换的标志位;

取出通知

uint32_t ulTaskNotifyTask( BaseType_t xClearCountOnExit, TickType_t xTicksToWait);

返回值为清零/减一前接收到的通知值;但如果超出阻塞时间(不为0),则返回0;
xClearCountOnExit:是否清零,如果pdTRUE,则清零;若 pdFALSE且通知值>0,则通知值减一;
xTicksToWait:阻塞时长;

2. 专业版

发出通知

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

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

(xTaskNotify的返回值包含pdPASS和pdFAIL)
xTaskToNotify:接收通知的任务的句柄
ulValue:一个参数,如何使用取决于eAction;
eAction:

  1. eNoAction:更新接收者任务的通知状态为pending,未使用ulValue
  2. eSetBits:接收通知者的通知值 = 原来的通知值 | ulValue(按位或)
  3. eIncrement:接收通知者的通知值 = 原来的通知值 + 1;
  4. eSetValueWithoutOverWrite:接收通知者的通知值 = ulVaule;由于是不覆盖,当接收者通知状态为“pending”(有待处理的数据),通知失败,函数返回pdFAIL;
  5. eSetValueWithOverWrite:接收通知者的通知值 = ulVaule,且能覆盖原有数据,不会失败;

前面的简化版发出通知就是基于xTaskNotify:

#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL )

取出通知

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

ulBitsToClearOnEntry:入口处清除,将原本的通知值某些位清零(&~ulBitsToClearOnEntry);
ulBitsToClearOnExit:出口处清除(不包括超时退出),将通知值某些位清零(&~ulBitsToClearOnExit);
pulNotificationValue:取出通知值(TCB中的通知值并不对外展示1,要另外传入一个变量接收)
xTicksToWait :阻塞时长;

之所以需要ulBitsToClearOnEntry对某些位做操作,是因为eAction中有对位的操作命令。假如需要像事件组那样根据某一位(事件)来做出决策,就需要将以前的遗留的位数据清零;

练习

创建一个发送通知任务和一个接收通知任务(接收的优先级设置得更高)。发送者会在计数值为奇数时候发送0x01,偶数时候发送0x02,并采用eSetBits。接收者接收0x01即将第一位置1,接收0x02即将第二位置1;

【全局变量】:

TaskHandle_t SetTask_Handle;
TaskHandle_t ReceiveTask_Handle;

【创建任务】:略

【发送通知任务函数】:

void Set_Task(void* argument){
	uint16_t cnt = 0;
	while(1){
		printf("%d\r\n", cnt);
		if(cnt%2 == 0){
			//一开始错写成SetTask,才导致Receive_Task一直没被唤醒
			xTaskNotify(ReceiveTask_Handle, 0x02, eSetBits);	//让通知值的第二位置1
		}
		else
			xTaskNotify(ReceiveTask_Handle, 0x01, eSetBits);	//让通知值的第一位置1
		cnt++;
	}
}

【接收通知任务函数】:

void Receive_Task(void* argument){
	uint32_t pulNotificationValue = 0x00;
	while(1){
		xTaskNotifyWait(0x03, 0x00, &pulNotificationValue, portMAX_DELAY);
		printf("Waiting End\r\n");
		if(pulNotificationValue == 0x01 || pulNotificationValue == 0x02){		//判断通知值第二位是否为1
			printf("%d\r\n", pulNotificationValue);
		}
		else
			printf("No\r\n");
		printf("----------------\r\n");
	}
}

【最终结果】:

在这里插入图片描述


  1. (GPT生成)通知值在 FreeRTOS 中是被设计为私有的,即不会对外部公开。这是为了确保任务间通信的安全性和一致性,同时防止意外访问或篡改通知值导致系统出现问题。 ↩︎

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

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

相关文章

告别繁琐!Xinstall助力,二维码推广监测从此高效无忧

在数字化营销时代,二维码推广已成为App获取新用户的重要途径之一。然而,如何精准监测二维码推广效果,成为了许多企业面临的难题。今天,我们为大家介绍一款强大的二维码推广监测工具——Xinstall,它将助您轻松解决推广监…

SonarQube安全扫描常见问题

目录 一、SonarQube质量报告 二、SonarQube扫描常见问题和修复方法 三、SonarQube质量配置 最近小编在使用SonarQube工具进行代码扫描,检查代码异味,系统漏洞等,实际过程中也遇到了不少问题,这篇文章主要列举我遇到的常见问题和…

账号密码无错误,xshell可以连接,但是WindTerm连接失败

xshell可以连接,但是WindTerm却连接失败 报错提示内容: 连接WindTerm是,账号密码是正确的,但是一输入账号,就报The remote host closed the connection错误,或者是Unknown error错误 解决方法 在新建…

Perfectly Clear Workbench: 智能图像清晰修复软件

Perfectly Clear Workbench 是由 EyeQ 公司开发的一款先进的智能图像清晰修复软件,适用于 Mac 和 Windows 平台。该软件旨在通过自动化和高效的图像处理工具,帮助摄影师、设计师以及影像爱好者轻松实现图像优化和修复。无论是专业摄影工作室还是个人用户…

揭秘ASA归因统计的奥秘,Xinstall带您轻松上手!

在移动互联网时代,App推广已成为企业获取用户、提升品牌知名度的重要手段。然而,如何准确衡量推广效果,如何精准定位目标用户,一直是困扰着众多App运营者的难题。今天,我们就来谈谈ASA(Apple Search Ads&am…

【Ardiuno】使用ESP32单片机创建web服务通过网页控制小灯开关的实验(图文)

经过实验测试ESP32单片机的网络连接还是很方便的,这里小飞鱼按照程序实例的代码亲自实验一下使用Esp32生成的网页服务来实现远程无线控制小灯开关功能,这样真的是离物联网开发越来越近了,哈哈! 连接好开发板和电路,将…

采用PHP语言(医院安全不良事件上报系统源码)医院不良事件 各类事件分析、分类、处理流程

医疗安全不容忽视! 医疗安全(不良)事件是指在临床诊疗活动中以及医院运行过程中,任何可能影响患者的诊疗结果、增加患者的痛苦和负担并可能引发医疗纠纷或医疗事故,以及影响医疗工作的正常运行和医务人员人身安全的因…

CVE-2024-4577:PHP CGI Windows平台远程代码执行漏洞

文章目录 0x01 前言0x02 漏洞描述0x03 影响范围0x04 资产测绘0x05 漏洞复现0x06 漏洞修复0x01 前言 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后…

如何在Visual Studio Code中禁用Less文件保存时自动编译为CSS的功能

第一步:点击扩展,搜索Easy Less,并找到对应的扩展设置 第二步:点击在setting.json中编辑 第三步:将此段代码复制粘贴 "compress": false, // 是否压缩"sourceMap": false, // 是否生成map文件&am…

洗地机是智商税吗?家用洗地机哪个牌子好?2024年多功能洗地机推荐

洗地机是智商税吗?肯定不是!!!洗地机因为其功能集成了扫地、吸尘、拖地、烘干和消毒的功能,仅需一步操作即可完成所有清洁任务,大大的提升了人们的清洁效率,节省了人们清洁的时间和精力。那么&a…

RocketMQ查询出重复数据,两条MessageID一样的解决办法如下

问题描述 在使用RocketMQ的可视化工具dashboard-1.0.0时,首先生产了10条数据,但是查询时却查出来了14条,有四条数据重复,重复数据MessageID和key相同,但是通过key单独查询却只能查出一条 测试代码 package com.fdw.rocketmq.producer;import org.apache.rocketmq.client…

设计模式学习(二)工厂模式——工厂方法模式

设计模式学习(二)工厂模式——工厂方法模式 前言工厂方法模式简介示例优点缺点使用场景 前言 前一篇文章介绍了简单工厂模式,提到了简单工厂模式的缺点(违反开闭原则,扩展困难),本文要介绍的工…

WordPress 站点 Wp-Login.Php 登录页面,防止被机器扫描爆破终极方法

最近好像不少的 WordPress 站点又迎来了一波疯狂的 wp-login.php 登录页面暴力破解,明月使用的 Dragon 主题也迅速的做出了安全防范响应,第一时间就增强了代码上的安全防御能力。明月代运维的几个站点也在这方面加强了防范措施,基本上实现了永久解决这一顽疾的目标,今天明月…

CAN总线协议教程

系列文章目录 文章目录 系列文章目录前言1.简介:CAN总线什么是CAN?我们将涵盖的内容 2.CAN报文数据框架远程框架错误帧重载框架标准与扩展 CAN基本CAN与全CAN总线仲裁和消息优先级邮件寻址和识别有关标识符值的说明 3.CAN物理层CAN总线不同的物理层最大总…

报错 Import declaration conflicts with local declaration of Policy

今天我新建了个页面 ,并将其进入到主页面是报了错 报错原因是:我在代码中有一个命名冲突。具体来说,我再在同一作用域内同时定义和导入了名为 Policy 的东西,导致冲突。 import React from react; import Policy from /pages/Pol…

Parallels Desktop 19虚拟机助你一机多用

Parallels Desktop 19 mac虚拟机是一款功能强大且易于使用的虚拟化软件,它允许用户在Mac电脑上同时运行Windows、Linux和其他多种操作系统,为用户提供了极大的灵活性和兼容性。 Parallels Desktop 19获取 这款虚拟机软件具有直观易用的界面,…

物联网TCP、UDP、CoAP、LwM2M、MQTT协议简单对比

一、前言 目前物联网行业有TCP、UDP、CoAP、LwM2M、MQTT、Modbus系列、JT808、HTTP、TLINK、ISAPI等协议,本文先对其中的几款协议进行介绍。具体关系见下图: 传输层协议:TCP、UDP;应用层协议:CoAP、LwM2M、MQTT、Modbu…

AI产品经理的转行之路,如何迈向年薪80w的职业高峰?

前言 在当今科技日新月异的时代,AI产品经理作为一个炙手可热的职业,吸引了众多向往高薪与前沿领域结合的求职者的目光。年薪80万的诱惑力无疑是巨大的,但不少自学中的朋友发现,即便涉猎广泛的产品知识,想要顺利转型成…

基于FreeRTOS+STM32CubeMX+LCD1602+MCP6S26(SPI接口)的6通道模拟可编程增益放大器Proteus仿真

一、简介: MCP6S26是模拟可 编程增益放大器(Programmable Gain Amplifiers, PGA)。它们可配置为输出 +1 V/V 到 +32 V/V 之间的增 益,输入复用器可通过 SPI 端口选择最多 6 个通道中的 一个。串行接口也可以将 PGA 置为关断模式,以降低 功耗。这些 PGA 针对高速度、低失调…

100TOPS算力!16GB内存顶配NVIDIA Jetson Orin NX 16GB 开箱

观前提醒:你以为我斥资6600买了一个NX玩?我其实买了三个NX NVIDIA Jetson Orin NX 简介: NVIDIA Jetson Orin NX是NVIDIA推出的一款高性能边缘计算平台,其设计目标是提供卓越的计算能力以支持各种复杂的人工智能(AI&am…