当前位置:网站首页>【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的通知:
好了,本节的内容就到这里了。
如果觉得有用可以关注作者微信号“小白白学电子”,在公众号可以找到代码和资料下载地址:
边栏推荐
猜你喜欢
BOM学习
Research Notes (6) Indoor Path Planning Method Based on Environment Perception
吴恩达机器学习系列课程笔记——第十六章:推荐系统(Recommender Systems)
深蓝学院-手写VIO作业-第二章
ESP32-C5 简介:乐鑫首款双频 Wi-Fi 6 MCU
科研笔记(七) 基于路径规划和WiFi指纹定位的多目的地室内导航
科研笔记(八) 深度学习及其在 WiFi 人体感知中的应用(下)
复制延迟案例(2)-读己之写
日本痴汉打赏女主播1.5亿,结果。。。
Deep Blue Academy - Visual SLAM Lecture Fourteen - Chapter 5 Homework
随机推荐
吴恩达机器学习系列课程笔记——第十六章:推荐系统(Recommender Systems)
深蓝学院-视觉SLAM十四讲-第五章作业
多主复制下处理写冲突(1)-同步与异步冲突检测及避免冲突
节流阀和本地存储
Scalar value for argument ‘color‘ is not numeric错误处理
ClickHouse的客户端命令行参数
深蓝学院-视觉SLAM十四讲-第七章作业
多主复制的适用场景(2)-需离线操作的客户端和协作编辑
论人生自动化
最后写入胜利(丢弃并发写入)
ESP32-C5 简介:乐鑫首款双频 Wi-Fi 6 MCU
Deep Blue Academy - Visual SLAM Lecture Fourteen - Chapter 5 Homework
复制延迟案例(2)-读己之写
深度学习基础之batch_size
asyncawait和promise的区别
从事功能测试1年,裸辞1个月,找不到工作的“我”怎么办?
关于XDR的这些问题你都了解吗?
树莓派上QT连接海康相机
面试官:大量请求 Redis 不存在的数据,从而打倒数据库,有什么方案?
多数据中心操作和检测并发写入