FreeRTOS事件组之事件组等待位(xEventGroupWaitBits)

1.函数说明(xEventGroupWaitBits)

函数原型:

EventBits_t xEventGroupWaitBits(
                                const EventGroupHandle_t xEventGroup,
                                const EventBits_t        uxBitsToWaitFor,
                                const BaseType_t         xClearOnExit,
                                const BaseType_t         xWaitForAllBits,
                                      TickType_t         xTicksToWait );
函数参数:

(1)xEventGroup:

(2) uxBitsToWaitFor:

(3)xClearOnExit:

(4)xWaitForAllBits:

(5)xTicksToWai:

返回值:

2.执行过程分析

(1)情况1(不满足事件发生条件)

#define BIT_0 ( 1 << 0 )
#define BIT_4 ( 1 << 4 )
xEventGroup =xEventGroupCreate();
uxBits = xEventGroupWaitBits(
                             xEventGroup,    /* The event group being tested. */
                             BIT_0 | BIT_4,  /* The bits within the event group to wait for. */
                             pdTRUE,         /* BIT_0 & BIT_4 should be cleared before returning. 
                                               在返回之前需要将第0位和第4位清楚*/
                             pdFALSE,        /* Don't wait for both bits, either bit will do. 不是等待所有都要置位,
							                   只要有一个满足条件就好*/
                             xTicksToWait ); /* Wait a maximum of 100ms for either bit to be set. */

执行xEventGroupWaitBits之前内存状态如下:



         首先要提取xEventGroup中的uxEventBits(其值和传入xEventGroupWaitBits的函数参数uxBitsToWaitFor进行比较来确定是否满足事件发生条件)的值,由于刚刚建立,所以uxEventBits=0。之后要检查是否事件发生条件,本例中设置的是判断部分位是否满足(xWaitForAllBits是pdFALSE),即uxEventBits中只要BIT_0 或BIT_4有一个位为1就可以。因为uxEventBits=0,因此不满足事件组发生条件。

         之后要将函数传参xClearOnExitxWaitForAllBits记录到xEventGroupWaitBits中的局部变量uxControlBits中(uxControlBits的bit24记录xClearOnExit,bit26用来记录xWaitForAllBits)。

         此时将当前任务控制块TCBxEventListItem节点的xItemValue32int类型)的0~23位设置成事件标志位(本例中为BIT_0 | BIT_4)xItemValue中的第24~31位设置成相应的控制位{xItemValue32位数据分成两部分,其中第24~31位设置成相应的控制位,0~23是事件标志位,控制位来源于上一段的uxControlBits和第31位(用来标记当前任务控制块的xItemValue是否正在使用)}在本例中,由于xClearOnExitpdTRUE,因此将xItemValue的第24位置1,同时标记xItemValue31位为1,表明本任务控制块的xEventListItemxItemValue正在使用)。

         之后利用vListInsertEnd函数将当前任务控制块的xEventListItem节点插入到xEventGroupxTasksWaitingForBits链表中,并且将当前控制块TCBxStateListItem节点从就绪任务链表中删除,并且将xStateListItem插入到pxDelayedTaskList链表中,并将下一个即将唤醒的pxDelayedTaskList中的节点的绝对时间记录到xNextTaskUnblockTime全局变量中。

          之后执行xTaskResumeAll发生任务调度(即使xTaskResumeAll内部没有发生任务调度,执行完xTaskResumeAll也会发生调度)。执行完上面的内容之后,内存中的数据结构情况如下:

上面内存变化情况总结是:

        任务控制块TCB_First在等待一个事件(xEventGroup结构体中的uxEventBitsBIT_0 或BIT_4有一个位为1,而调用xEventGroupWaitBits就是判断事件组结构体xEventGroup是否满足这个条件,但是本例中uxEventBits满足不了,所以要挂起任务控制块TCB_First到xEventGroup结构体的xTasksWaitingForBits链表中,同时将这个要求(uxEventBits中只要BIT_0 BIT_4有一个位为1)和对应的一些操作记录在xEventListItemxItemValue



       当任务再次调度回来继续执行任务TCB_First对应的代码的时候,继续执行xEventGroupWaitBits函数。取出当前任务控制块的xEventListItem节点的xItemValue的值,并将其恢复为configMAX_PRIORITIES - pxCurrentTCB->uxPriority)。

        如果解挂原因是因为xEventGroupSetBits函数,则返回导致其解挂的uxEventBits的第0~23位(这个值是其他任务中xEventGroupSetBits函数设置的,存储在当前任务控制块的xEventListItem节点的xItemValue中,也就是需要返回当前任务控制块xEventListItem节点的xItemValue的第0~23位,记录到底是什么样的uxEventBits使之解挂),之后退出函数。

        如果解挂的原因是因为超时,则还需要判断uxEventBits中是满足当前控制块事件发生条件(在本例中为BIT4|BIT0)(为什么都已经解挂了还需要判断uxEventBits是否满足事件标志发生条件呢?主要是因为其他任务优先级可能高于当前任务,不会让出CPU的控制权,这些高优先级的任务也会调用xEventGroupSetBits来修改uxEventBits),如果满足事件发生条件,并且xClearOnExit=true则会将uxEventBits相应位(在本例中为BIT4|BIT0)清零,并返回当前事件组uxEventBits的第0到23位(清零前的,主要是返回到第是什么样的uxEventBits使本任务控制块的事件组满足了条件),如果xClearOnExit=false,则不清零,返回当前事件组uxEventBits的第0到23位。如果仍不满足事件发生条件,则返回当前uxEventBits的第0到23位。










































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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值