【FreeRTOS】10 事件标志组

本节我们来讲讲freeRTOS的事件标志组。它也是一种用于任务间通信和同步的机制,和信号量有一些相似的功能,但也有自己的特点。

1)什么是事件标志组

一个事件标志组有多个事件位,每个事件位表示了一个事件的标志。

比如我们用事件标志组的bit0表示事件A、bit1表示事件B、bit2表示事件C,那么这个事件标志组至少可以表示3个事件是否发生。

之前我们讲过信号量,它用作信号同步时,只能表示一个资源的有无;而事件标志组,它可以同时表示多个资源的有无。

上述的例子,相当于这个事件标志组实现了等效于3个二值信号量的功能,任务可以在一个事件标志组上同时等待A、B、C三个事件。

任务在等待事件标志组的事件时,可以选等待该组中的一个或某几个事件位。比如上述例子中,虽然事件标志组表示了A、B、C三个事件,但是用户可以设置为只等待A和B。

此外,事件标志组与信号量不同的另一点,是它可以选择在等待到某个事件位时是否对该事件位清零。而使用信号量时,获取到一个信号量时,信号量的计数会自动减1。

2)FreeRTOS的事件标志组

freeRTOS提供的事件标志组,由数据类型EventGroupHandle_t定义。使用前需要确认FreeRTOSConfig.h文件中configUSE_16_BIT_TICKS这个宏的定义,如果定义为1,则一个事件标志组可以最多存储8个事件位,如果定义位0,则可以存储24个事件位。

下面讲解一下freeRTOS中操作事件标志组常用的一些函数。

创建事件标志组:

EventGroupHandle_t xEventGroupCreate( void );//创建一个事件标志组,返回的是创建成功的事件标准组句柄

这个函数实际上是动态创建的事件标志组,如果想使用静态创建,需要用xEventGroupCreateStatic()函数。

设置事件位:

最主要是xEventGroupSetBits()、xEventGroupClearBits()两个函数,作用是把事件位置1或清0。函数原型为:

EventBits_t xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear); //清0事件标志组,xEventGroup为要操作的事件标准组句柄,uxBitsToClear为要清的事件位,可以同时清多个位

EventBits_t xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ); //设置事件标志组指定位为1,xEventGroup为要操作的事件标准组句柄,uxBitsToClear为要置1的事件位

上述两个函数只能用在任务中,如果要在中断中设置事件标志组,要使用后缀为ISR的一套函数:xEventGroupSetBitsFromISR()和xEventGroupClearBitsFromISR()。

等待事件位:

EventBits_t xEventGroupWaitBits(

EventGroupHandle_t xEventGroup,  /*要等待的事件标志组*/

const EventBits_t uxBitsToWaitFor, /*要等待的事件位*/

const BaseType_t xClearOnExit,  /*所等待的事件位是否清零,pdTRUE为清零,pdFALSE不变*/

const BaseType_t xWaitForAllBits,  /*是否等待所有位,pdTRUE为等待uxBitsToWaitFor指定的所有位,pfFALSE只要uxBitsToWaitFor指定的其中一位置1就返回 */

const TickType_t xTicksToWait );  /*等待超时时间*/

获取事件标志组的值:

EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );//获取事件标准组的值(不会改变它的值)

在中断中需要使用xEventGroupGetBitsFromISR这个函数。

3)编程试验

下面我们以一个例子来演示事件标志组的使用。

和前几期的例子一样,我们还是使用cubemx建立三个任务,优先级各不相同。

生成keil工程:

编写代码如下,首先是事件标志组的创建:

我们先编写在最低优先级的任务DefaultTask中发送事件,第1s发送事件位bit0,第2s发生事件位bit1,如此循环:

在中等优先级任务Task02中,等待事件位bit0和bit1,都等到后,清零,并发送事件位bit3:

在高优先级任务Task03中,等待事件位bit3,等到后不清零:

这个程序运行结果如下图:

初始时,优先级较高的两个任务都在等待事件,只有最低优先级任务DefaultTask可以运行;

第1s时DefaultTask发送了事件bit0,第2s时DefaultTask发送了事件bit1;

由于Task02设置的是同时等待bit0和bit1,所以,到DefaultTask发完bit1时,Task02才等到了它需要的所有事件位,等到之后事件位清0;

然后,Task02发送了事件位bit3;

Task03等待到bit3后,由于设置的是不清零,该bit3事件位它是一直有效的;所以Task03之后循环运行到等待事件位bit3时不会再被阻塞,而是立即返回执行。会不停地打印输出Task03 has waited event bit3。

好了,本节的内容就到这里了。

如果觉得有用可以关注作者微信号“小白白学电子”,在公众号可以找到代码和资料下载地址:

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值