FreeRTOS任务通知实验

本文介绍了FreeRTOS从V8.2.0版本开始引入的任务通知功能,作为替代信号量、消息队列和事件组的高效机制。任务通知提供了xTaskNotifyGive()、vTaskNotifyGiveFromISR()、xTaskNotify()和xTaskNotifyFromISR()等API函数,用于发送任务通知,并有ulTaskNotifyTake()和xTaskNotifyWait()用于接收和等待通知。通过实例展示了如何使用任务通知实现消息队列、二值信号量和计数信号量等功能。
摘要由CSDN通过智能技术生成

从 V8.2.0 版本开始,FreeRTOS 新增了任务通知这个功能,可以使用任务通 知来代替信号量、消息队列、事件组等这些东西。使用任务通知的话效率会更高。 本章要实现的功能是:使用任务通知方式实现消息队列、二值信号量、计数信号 量、事件标记功能实验。本章分为如下几部分内容: 11.1 任务通知简介 11.2 常用任务通知 API 函数 11.3 硬件设计 11.4 软件设计 11.5 实验现象

11.1 任务通知简介

FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能,每个任务都有一个 32 位的通知值,在大多数情况下,任务通知可以替代二值信号量、计数信号量、 事件组,也可以替代长度为 1 的队列(可以保存一个 32 位整数或指针值)。 相对于以前使用 FreeRTOS 内核通信的资源,必须创建队列、二进制信号量、 计数信号量或事件组的情况,使用任务通知显然更灵活。按照 FreeRTOS 官方的 说法,使用任务通知比通过信号量等 IPC 通信方式解除阻塞的任务要快 45%, 并且更加省 RAM 内存空间(使用 GCC 编译器,-o2 优化级别),任务通知的使 用无需创建队列。想要使用任务通知,必须将 FreeRTOSConfig.h 中的宏定义 configUSE_TASK_NOTIFICATIONS 设置为 1,其实 FreeRTOS 默认是为 1 的,所 以任务通知是默认使能的。 FreeRTOS 提供以下几种方式发送通知给任务 : ●发送通知给任务,如果有通知未读,不覆盖通知值。 ●发送通知给任务,直接覆盖通知值。 ●发送通知给任务,设置通知值的一个或者多个位,可以当做事件组来使用。 ●发送通知给任务,递增通知值,可以当做计数信号量使用。 通过对以上任务通知方式的合理使用,可以在一定场合下替代 FreeRTOS 的 信号量,队列、事件组等。 当然,凡是都有利弊,不然的话 FreeRTOS 还要内核的 IPC 通信机制干嘛, 消息通知虽然处理更快,RAM 开销更小,但也有以下限制 : ●只能有一个任务接收通知消息,因为必须指定接收通知的任务。 ●只有等待通知的任务可以被阻塞,发送通知的任务,在任何情况下都不会 因为发送失败而进入阻塞态

11.2 常用任务通知 API 函 数

11.2.1.1 xTaskNotifyGive()

xTaskNotifyGive()是一个宏,宏展开是调用函数 xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement ,NULL),即向 一个任务发送通知,并将对方的任务通知值加 1。该函数可以作为二值信号量和 计数信号量的一种轻量型的实现,速度更快,在这种情况下对象任务在等待任务 通知的时候应该是使用函数 ulTaskNotifyTake() 而不是 xTaskNotifyWait()。 xTaskNotifyGive()不能在中断里面使用,而是使用具有中断保护功能的 vTaskNotifyGiveFromISR()来代替。该函数的具体说明如下

11.2.1.2 vTaskNotifyGiveFromISR()

vTaskNotifyGiveFromISR()是 vTaskNotifyGive()的中断保护版本。用于在 中断中向指定任务发送任务通知,并更新对方的任务通知值(加 1 操作),在 某些场景中可以替代信号量操作,因为这两个通知都是不带有通知值的。该函数 的具体说明如下

从上面的函数说明我们大概知道 vTaskNotifyGiveFromISR()函数作用,每 次调用该函数都会增加任务的通知值,任务通过接收函数返回值是否大于零,判 断是否获取到了通知,任务通知值初始化为 0,(如果与信号量做对比)则对应 为信号量无效。当中断调用 vTaskNotifyGiveFromISR()通知函数给任务的时候, 任务的通知值增加,使其大于零,使其表示的通知值变为有效,任务获取有效的 通知值将会被恢复

11.2.1.3 xTaskNotify()

FreeRTOS 每个任务都有一个 32 位的变量用于实现任务通知,在任务创建 的时候初始化为 0。这个 32 位的通知值在任务控制块 TCB 里面定义。 xTaskNotify()用于在任务中直接向另外一个任务发送一个事件,接收到该任务 通知的任务有可能解锁。如果你想使用任务通知来实现二值信号量和计数信号 量,那么应该使用更加简单的函数 xTaskNotifyGive(),而不是使用 xTaskNotify(),xTaskNotify()函数在发送任务通知的时候会指定一个通知值, 并且用户可以指定通知值发送的方式。 注意:该函数不能在中断里面使用,而是使用具体中断保护功能的版本函数 xTaskNotifyFromISR()。xTaskNotify()函数的具体说明如下

11.2.1.4 xTaskNotifyFromISR( )

用于在中断中向指定的任务发送一个任务通知,该任务通知是带有通知值并 且用户可以指定通知的发送方式,不返回上一个任务在的通知值。函数的具体说 明如下

11.2.2.1 xTaskNotifyAndQuery()

xTaskNotifyAndQuery()与 xTaskNotify()很像,都是调用通用的任务通知 发送函数 xTaskGenericNotify() 来实现通知的发送,不同的是多了一个附加的 参数 pulPreviousNotifyValue 用于回传接收任务的上一个通知值,函数原型具 体见代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值