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

来源:互联网 发布:日本经营管理签证知乎 编辑:程序博客网 时间:2024/05/18 11:48

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位。





0 0
原创粉丝点击