FreeRTOS之事件组

概述

  • 事件组的每一位表示一个事件
  • 每一位事件的含义由我们决定,比如:Bit0 表示用来串口是否就绪,Bit1表示按键是否被按下
  • 值为 1 表示事件发生了,值为 0 表示事件没发生
  • 一个或多个任务、ISR 都可以去写这些位;一个或多个任务、ISR 都可以去读这些位
  • 可以等待某一位、某些位中的任意一个,也可以等待多位
  • 的高8位留给内核使用,只能用其他的位来表示事件
  • 如果 configUSE_16_BIT_TICKS 是 1,那么这个整数就是 16 位的,低 8 位用来表示事件 如果 configUSE_16_BIT_TICKS 是 0,那么这个整数就是 32 位的,低 24 位用来表示事件
  • 队列、信号量:事件发生时,只会唤醒一个任务,而事件组:事件发生时,会唤醒所有符号条件的任务
  • 队列、信号量:是消耗型的资源,队列的数据被读走就没了;信号量被获取后就减少了,而事件组:被唤醒的任务有两个选择,可以让事件保留不动,也可以清除事件
    在这里插入图片描述

函数

创建

/* 创建一个事件组,返回它的句柄。
* 此函数内部会分配事件组结构体
* 返回值: 返回句柄,非 NULL 表示成功
*/
EventGroupHandle_t xEventGroupCreate( void );
/* 创建一个事件组,返回它的句柄。
* 此函数无需动态分配内存,所以需要先有一个 StaticEventGroup_t 结构体,并传入它的
指针
* 返回值: 返回句柄,非 NULL 表示成功
*/
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer
);

删除

对于动态创建的事件组,不再需要它们时,可以删除它们以回收内存

/*
* xEventGroup: 事件组句柄,你要删除哪个事件组
*/
void vEventGroupDelete( EventGroupHandle_t xEventGroup )

设置事件

可以设置事件组的某个位、某些位
有一个或多个任务在等待事件,如果这些事件符合这些任务的期望,那么任务还会被唤醒

/* 设置事件组中的位
* xEventGroup: 哪个事件组
* uxBitsToSet: 设置哪些位?
* 如果 uxBitsToSet 的 bitX, bitY 为 1, 那么事件组中的 bitX, bitY 被设置为 1
* 可以用来设置多个位,比如 0x15 就表示设置 bit4, bit2, bit0
* 返回值: 返回原来的事件值(没什么意义, 因为很可能已经被其他任务修改了) */
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
/* 设置事件组中的位
* xEventGroup: 哪个事件组
* uxBitsToSet: 设置哪些位?
* 如果 uxBitsToSet 的 bitX, bitY 为 1, 那么事件组中的 bitX, bitY 被设置为 1
* 可以用来设置多个位,比如 0x15 就表示设置 bit4, bit2, bit0
* pxHigherPriorityTaskWoken: 有没有导致更高优先级的任务进入就绪态? pdTRUE-有, p
dFALSE-没有
* 返回值: pdPASS-成功, pdFALSE-失败
*/
BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t * pxHigherPriorityTaskWoken );
  • 值得注意的是,ISR中的函数,比如队列函数xQueueSendToBackFromISR、信号量函数xSemaphoreGiveFromISR,它们会唤醒某个任务,最多只会唤醒1个任务。
  • 但是设置事件组时,有可能导致多个任务被唤醒,这会带来很大的不确定性。所以
    xEventGroupSetBitsFromISR函数不是直接去设置事件组,而是给一个FreeRTOS后台任务
    (daemon task)发送队列数据,由这个任务来设置事件组。
  • 如果后台任务的优先级比当前被中断的任务优先级高,xEventGroupSetBitsFromISR会设置*pxHigherPriorityTaskWoken为pdTRUE。
  • 如 果 daemon task 成 功 地 把 队 列 数 据 发 送 给 了 后 台 任 务 , 那 么
    xEventGroupSetBitsFromISR的返回值就是pdPASS

等待事件

可以等待某一位、某些位中的任意一个,也可以等待多位;等到期望的事件后,还可以清除某些位。

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait );
参数说明
xEventGroup等待哪个事件组
uxBitsToWaitFor等待哪些位?哪些位要被测试
xWaitForAllBits怎么测试?是“AND”还是“OR”
pdTRUE:等待的位,全部为 1;
pdFALSE:等待的位,某一个为 1 即可
xClearOnExit函数退出前是否要清除事件(该位置0)?
pdTRUE:清除 uxBitsToWaitFor 指定的位;
pdFALSE:不清除
xTicksToWait如果期待的事件未发生,阻塞多久。
可设置为 0:判断后即刻返回;
可设置为 portMAX_DELAY:一定等到成功才返回;
可设置为期望的 Tick Count,一般用 pdMS_TO_TICKS() 把 ms 转换为 Tick Count
返回值返回的是事件值。
如果期待的事件发生了,返回的是“非阻塞条件成立”时的事件值;
如果是超时退出,返回的是超时时刻的事件值

同步点

EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
参数说明
xEventGroup指定是哪个事件组
uxBitsToSet用于确定要设置哪些事件,即表明完成了哪些事件。例如0x05(二进制为0101),会使事件组的bit0bit2被设置为1
uxBitsToWaitFor明确等待哪些位。比如0x15(二进制10101),表示要等待bit0bit2bit4都为1
xTicksToWait若期待的事件未发生,设置阻塞时长。可设为0,判断后立即返回;可设为portMAX_DELAY,一直等到成功才返回;也可设为期望的Tick Count,通常用pdMS_TO_TICKS()将ms转换为Tick Count
返回值返回事件值。若期待事件发生,返回“非阻塞条件成立”时的事件值;若因超时而退出,返回超时时刻的事件值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值