当前位置:网站首页>【FreeRTOS】12 任务通知——更省资源的同步方式
【FreeRTOS】12 任务通知——更省资源的同步方式
2022-08-02 03:37:00 【xiaobaibai_2021】
我们之前讲过信号量、消息队列、事件标志组,它们都可以实现任务间的通信和同步。本节我们讲解任务通知(Task Notifications),它是freeRTOS中实现的另一种通信和同步的方法,在一定程度上可以代替信号量、消息队列、事件标志组的功能;而且任务通知所需要的资源更少、执行速度更快。
1)freeRTOS中的任务通知
freeRTOS的任务通知,和信号量、消息队列、事件标准组一样,也是一种可以阻塞任务的事件。
每个任务对应有一个任务通知,任务可以在等待自己对应的任务通知时被阻塞,向该任务通知发送通知可以唤醒该任务;
任务通知的值,就是任务控制块结构体中的变量ulNotifiedValue,32bit;这也说明了任务通知是和任务一一对应的;
更新任务通知的值ulNotifiedValue,可以有多种方式:覆盖旧通知值、(如果上次未处理则)不覆盖旧通知值、更新任务通知的某几个bit、增加任务通知值。
灵活运用更新任务通知值的方法,可以使任务通知实现信号量、消息队列、事件标志组等的功能。
例如:向某个任务发送一个信号量,可以通过将该任务的通知值加1实现;获取信号量,可以将该任务的通知值减1实现;
向某个任务的通知值中写入一个数据,相对于向该任务发送了一个长度为1的消息;
设置某个任务通知值的bit0~bit31,可以实现事件标志组。
任务通知实现的信号量、消息队列、事件标志组,比之前讲过的实现方法占用内存更少、执行速度更快;但是,正是由于任务通知是和任务一一对应的,而且它只有一个32bit的变量ulNotifiedValue来传递信息,使用时有一些限制:
a) 不能同时使用任务通知来传递多个信息,也就是说同一时间对于某个任务,只能实现一个“信号量”或“消息队列”或“事件标志组”的作用;
b) 使用任务通知时,不支持发送信息的超时等待(这一点和之前讲过的信号量、消息队列、事件标志组不同,它们是可以支持超时等待的)。
使用任务通知功能,需要在FreeRTOS.h文件中,将configUSE_TASK_NOTIFICATIONS宏定义为1。
2)常用的任务通知函数
任务通知的值ulNotifiedValue是每个任务在创建时,任务控制块中就生成的,所以不需用户定义(这和信号量、消息队列、事件标志组等是不同的,它们都需要定义后再使用)。
几个常用的任务通知函数如下:
发送通知:
BaseType_t xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction ); //三个参数依次为:任务句柄、任务通知值、任务通知值更新方法;
其中,最后一个参数,任务通知值更新方法,是一个枚举值,在task.h文件中定义:
typedef enum
{
eNoAction = 0, //未使用,不更新
eSetBits, //更新指定的bit为1
eIncrement, //通知值加1
eSetValueWithOverwrite, //覆写的方式更新通知值
eSetValueWithoutOverwrite //不覆写通知值
} eNotifyAction;
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); //发送通知,参数为任务句柄,对应任务通知值加1
BaseType_t xTaskNotifyAndQuery( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t * ulPreviousNotificationValue); //该函数和xTaskNotify很相似,多一个最后的参数,用来返回更新前的通知值
上述几个发送任务通知的函数都是在任务中使用的,如果需要在中断中使用,需要用带后缀ISR的一套函数。
获取通知:
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
/*获任务通知;xClearCountOnExit参数为pdFALSE时任务通知值减1(类似计数信号量),参数为pdTRUE时任务通知值清零(类似二值信号量);该函数更适用于任务通知用作信号量时*/
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t * pulNotificationValue, TickType_t xTicksToWait );
/*获取任务通知,函数在执行前,将ulBitsToClearOnEntry的值取反后,和通知值相与来改变通知值;在函数退出前,将ulBitsToClearOnExit的值取反后,和通知值相与来改变通知值;参数pulNotificationValue用来保存任务通知值,参数xTicksToWait为等待时间;该函数更适用于任务通知作为消息队列或者事件标志组时*/
3)编程试验1——任务通知模拟信号量
我们先来编程试验使用任务通知模拟信号量的功能。
在cubemx中配置时,使能任务通知功能:

也可以在keil工程里自己创建宏定义:

创建三个任务:

任务的实现如下:
Task02每1s发送一个任务通知,Task03则循环等待任务通知,defaultTask没有使用:

这个程序的输出如下所示:
尽管Task03的优先级最高,但是由于任务通知的阻塞作用,起到了信号量的作用,task02每发送一次任务通知,task03才能打印一次输出:

4)编程试验2——任务通知模拟事件标志组
我们仍然在上一个例子的基础上改写,如下图所示:
Task02每隔1s发送一个任务通知,先置bit0为1,再置bit1为1:

Task03循环等待通知,等待函数中,进入时不改变通知值,退出时将通知值清零;等到通知时,将当前的通知值打印输出:

这个程序运行结果如下所示,task03按预期打印出了1和2的通知:

好了,本节的内容就到这里了。
如果觉得有用可以关注作者微信号“小白白学电子”,在公众号可以找到代码和资料下载地址:

边栏推荐
- 剩余参数、数组对象的方法和字符串扩展的方法
- 吴恩达机器学习系列课程笔记——第六章:逻辑回归(Logistic Regression)
- 今天突然下雨
- 七分钟深入理解——卷积神经网络(CNN)
- el-select和el-tree结合使用-树形结构多选框
- GO Module的依赖管理(二)
- 深蓝学院-视觉SLAM十四讲-第四章作业
- VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tupl
- Deep Blue Academy-Visual SLAM Lecture 14-Chapter 6 Homework
- Research Notes (8) Deep Learning and Its Application in WiFi Human Perception (Part 1)
猜你喜欢

samba,nfs,iscsi网络文件系统

Research Notes (8) Deep Learning and Its Application in WiFi Human Perception (Part 2)

吴恩达机器学习系列课程笔记——第十四章:降维(Dimensionality Reduction)

CaDDN代码调试

STM32/TMS320F2812+W5500硬软件调试总结

Qt编写物联网管理平台49-设备模拟工具

ftp服务的部署和优化

吴恩达机器学习系列课程笔记——第十五章:异常检测(Anomaly Detection)

从事功能测试1年,裸辞1个月,找不到工作的“我”怎么办?

吴恩达机器学习系列课程笔记——第七章:正则化(Regularization)
随机推荐
吴恩达机器学习系列课程笔记——第十四章:降维(Dimensionality Reduction)
shell中常用的基础命令
SCI writing strategy - with common English writing sentence patterns
v-bind动态绑定
吴恩达机器学习系列课程笔记——第七章:正则化(Regularization)
无主复制系统(3)-Quorum一致性的局限性
BOM学习
其他语法和模块的导出导入
ICMP timestamp请求响应漏洞
samba,nfs,iscsi网络文件系统
CaDDN代码调试
基于sysbench工具的压力测试---MyCat2.0+MySql架构
The CCF brush topic tour - the first topic
ansible的安装与部署
复制延迟案例(3)-单调读
树莓派4B安装OPENCV遇到ffmpeg库版本太高的问题【后续更新】
Excel skills daquan
深蓝学院-视觉SLAM十四讲-第六章作业
Excel操作技巧大全
g++编译添加头文件路径,设置库路径,包路径,找文件