IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FreeRTOS操作系统——任务通知模拟信号量(十七) -> 正文阅读

[嵌入式]FreeRTOS操作系统——任务通知模拟信号量(十七)

FreeRTOS操作系统学习

前言

在FreeRTOS中可以使用任务通知来代替信号量、消息队列、事件标志组等这些东西。使用任务通知的话效率会更高

一、任务通知简介

任务通知在 FreeRTOS 中是一个可选的功能,要使用任务通知的话就需要将宏configUSE_TASK_NOTIFICATIONS 定义为 1。FreeRTOS 的每个任务都有一个 32 位的通知值,任务控制块中的成员变量 ulNotifiedValue就是这个通知值。任务通知是一个事件,假如某个任务通知的接收任务因为等待任务通知而阻塞的话,向这个接收任务发送任务通知以后就会解除这个任务的阻塞状态。
也可以更新接收任务的任务通知值。

任务通知可以通过如下方法更新接收任务的通知值:

● 不覆盖接收任务的通知值(如果上次发送给接收任务的通知还没被处理)。
● 覆盖接收任务的通知值。
● 更新接收任务通知值的一个或多个 bit。
● 增加接收任务的通知值。

合理、灵活的使用上面这些更改任务通知值的方法可以在一些场合中替代队列、二值信号量、计数型信号量和事件标志组。使用任务通知来实现二值信号量功能的时候,解除任务阻塞的时间比直接使用二值信号量要快 45%。
虽然FreeRTOS任务通知速度更快并且占用内存更少,但它也有一些限制:
只能有一个任务接收通知事件。(只能给一个任务发送,消息队列可以多任务)
接收通知的任务可以因为等待通知而进入阻塞状态,但是发送通知的任务即便不能立即完成通知发送也不能进入阻塞状态。

每个RTOS任务都有一个32位的通知值,任务创建时,这个值被初始化为0。FreeRTOS任务通知相当于直接向任务发送一个事件,接收到通知的任务可以解除阻塞状态,前提是这个阻塞事件是因等待通知而引起的。发送通知的同时,也可以可选的改变接收任务的通知值。

二、相关API函数

1.发送任务通知函数

xTaskNotify()
发送通知,带有通知值并且不保留接收任务原通知值,用在任务中。

xTaskNotifyFromISR() 发送通知,函数 xTaskNotify()的中断版本。

xTaskNotifyGive()
发送通知,不带通知值并且不保留接收任务的通知值,此函数会将接收任务的通知值加一,用于任务中。

vTaskNotifyGiveFromISR() 发送通知,函数 xTaskNotifyGive()的中断版本。

xTaskNotifyAndQuery()
发送通知,带有通知值并且保留接收任务的原通知值,用在任务中。

xTaskNotiryAndQueryFromISR()
发送通知,函数 xTaskNotifyAndQuery()的中断版本,用在中断服务函数中

1、函数 xTaskNotify()

函数原型

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

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
ulValue: 任务通知值。
eAction: 任务通知更新的方法,eNotifyAction 是个枚举类型
返回值:
pdFAIL: 当参数 eAction 设置为 eSetValueWithoutOverwrite 的时候,如果任务通知值没有更新成功就返回 pdFAIL。
pdPASS: eAction 设置为其他选项的时候统一返回 pdPASS。
在这里插入图片描述

向指定任务发送指定的通知值。如果打算使用RTOS任务通知实现轻量级的二进制或计数信号量,推荐使用API函数xTaskNotifyGive()来代替本函数。

2、函数 xTaskNotifyFromISR()

发送任务通知,是函数 xTaskNotify()的中断版本

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

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
ulValue: 任务通知值。
eAction: 任务通知更新的方法。
pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换,这个变量的值函数会自动设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。

返回值:
pdFAIL: 当参数 eAction 设置为 eSetValueWithoutOverwrite 的时候,如果任务通知值没有
更新成功就返回 pdFAIL。
pdPASS: eAction 设置为其他选项的时候统一返回 pdPASS。

3、函数 xTaskNotifyGive()

发送任务通知,相对于函数 xTaskNotify(),此函数发送任务通知的时候不带有通知值。此
函数只是将任务通知值简单的加一

BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
返回值:
pdPASS: 此函数只会返回 pdPASS。
4、函数 vTaskNotifyGiveFromISR()
此函数为 xTaskNotifyGive()的中断版本,用在中断服务函数中,函数原型如下:

void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, 
BaseType_t * pxHigherPriorityTaskWoken );

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换,这个变量的值函数会自动设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。

4、函数 vTaskNotifyGiveFromISR()

此函数为 xTaskNotifyGive()的中断版本

void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, 
BaseType_t * pxHigherPriorityTaskWoken );

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换,这个变量的值函数会自动设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。

5、函数 xTaskNotifyAndQuery()

此函数和 xTaskNotify()很类似,此函数比 xTaskNotify()多一个参数,此参数用来保存更新
前的通知值。

BaseType_t xTaskNotifyAndQuery ( TaskHandle_t xTaskToNotify, 
uint32_t ulValue, 
eNotifyAction eAction 
uint32_t * pulPreviousNotificationValue);

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的
ulValue: 任务通知值。
eAction: 任务通知更新的方法。
pulPreviousNotificationValue:用来保存更新前的任务通知值。
返回值:
pdFAIL: 当参数 eAction 设置为 eSetValueWithoutOverwrite 的时候,如果任务通知值没有更新成功就返回 pdFAIL。
pdPASS: eAction 设置为其他选项的时候统一返回 pdPASS

6、函数 xTaskNotifyAndQueryFromISR()

此函数为 xTaskNorityAndQuery()的中断版本

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

参数:
xTaskToNotify: 任务句柄,指定任务通知是发送给哪个任务的。
ulValue: 任务通知值。
eAction: 任务通知更新的方法。
pulPreviousNotificationValue:用来保存更新前的任务通知值。
pxHigherPriorityTaskWoken: 记退出此函数以后是否进行任务切换,这个变量的值函数会自动设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为 pdTRUE 的时候在退出中断服务函数之前一定要进行一次任务切换。
返回值:
pdFAIL: 当参数 eAction 设置为 eSetValueWithoutOverwrite 的时候,如果任务通知值没有更新成功就返回 pdFAIL。
pdPASS: eAction 设置为其他选项的时候统一返回 pdPASS。

2.获取任务通知

ulTaskNotifyTake()
获取任务通知,可以设置在退出此函数的时候将任务通知值清零或者减一。当任务通知用作二值信号量或者计数信号量的时候使用此函数来获取信号量。
xTaskNotifyWait()
等待任务通知,比 ulTaskNotifyTak()更为强大,全功能版任务通知获取函数。

1、函数 ulTaskNotifyTake()

此函数为获取任务通知函数,当任务通知用作二值信号量或者计数型信号量的时候可以使
用此函数来获取信号量

uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, 
TickType_t xTicksToWait );

参数:
xClearCountOnExit: 参数为 pdFALSE 的话在退出函数 ulTaskNotifyTake()的时候任务通知值减一,类似计数型信号量。当此参数为 pdTRUE 的话在退出函数的时候任务任务通知值清零,类似二值信号量。

xTickToWait: 阻塞时间。

2、函数 xTaskNotifyWait()

此函数也是用来获取任务通知的,不过此函数比 ulTaskNotifyTake()更为强大,不管任务通知用作二值信号量、计数型信号量、队列和事件标志组中的哪一种,都可以使用此函数来获取任务通知。但是当任务通知用作位置信号量和计数型信号量的时候推荐使用函数ulTaskNotifyTake()。

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

参数:
ulBitsToClearOnEntry:当没有接收到任务通知的时候将任务通知值与此参数的取反值进行按位与运算,当此参数为 0xffffffff 或者 ULONG_MAX 的时候就会将任务通知值清零。
ulBitsToClearOnExit:如果接收到了任务通知,在做完相应的处理退出函数之前将任务通知值与此参数的取反值进行按位与运算,当此参数为 0xffffffff 或者ULONG_MAX 的时候就会将任务通知值清零。
pulNotificationValue:此参数用来保存任务通知值。
xTickToWait: 阻塞时间
返回值:
pdTRUE: 获取到了任务通知。
pdFALSE: 任务通知获取失败。

3.任务通知模拟二值信号量实验

在这里插入图片描述
(1)、调用函数 vTaskNotifyGiveFromISR()向任务 DataProcess_task 发送任务通知,此处取代
的是二值信号量发送函数。
在这里插入图片描述
使用任务通知替代二值信号量的过程还是非常简单的,只需要替换掉几个API函数。

4、任务通知模拟计数型信号量实验

计数型信号量通常用于资源管理和事件计数,在使用资源管理时不可用任务通知,只能用计数型信号量,在事件计数时,可以使用任务通知
在这里插入图片描述
在这里插入图片描述
(1)、调用函数 xTaskNotify()发送任务通知,任务通知值为按键值,发送方式采用覆写的方式。
(2)、调用函数 xTaskNotifyWait()获取任务通知,获取到的任务通知其实就是(1)中发送的按键值,然后根据不同的按键值做不同的处理。

总结

任务通知很简单,就是将原有的信号量通知函数变成任务通知函数,注意计数型信号量用于资源管理时不可以使用任务通知。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-02-01 20:46:36  更:2022-02-01 20:47:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:30:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码