FreeRTOS事件组之事件组置位(xEventGroupSetBits)

来源:互联网 发布:永宏伺服编程 编辑:程序博客网 时间:2024/05/16 17:05

(1)第一种情况描述如下(最简单的情况)

           事件组的xTasksWaitingForBits下面没有挂载任何东西,而且uxEventBits=0;相当于调用xEventGroupCreate之后马上执行xEventGroupSetBits。

       

#define BIT_0 (1 << 0 )

#define BIT_4 (1 << 4 )

xEventGroup =xEventGroupCreate()

uxBits =xEventGroupSetBits (xEventGroup, /* The event group being tested. */

                                                              BIT_0 | BIT_4),/* The bits within the eventgroup to wait for. */


执行之前的内存状态为:

        


xEventGroupSetBits中所做的工作有:

uxEventBits的第bit0bit4置位。之后退出函数并返回uxEventBits的值。

(2)第二种情况描述如下

      事件组的xTasksWaitingForBits下面挂载一个节点,而且uxEventBits=0,这个节点以及具体内存情况见我的博客xEventGroupWaitBits的情况(1)。等效程序执行代码如下

下面两句代码是在在任务TCB_First中对应的代码中执行的:

xEventGroup =xEventGroupCreate();

uxBits = xEventGroupWaitBits(

xEventGroup, /*The event group being tested. */

BIT_0 | BIT_4, /* The bits within the eventgroup to wait for. */

pdTRUE,     /* BIT_0 & BIT_4 should be cleared before returning.

xClearOnExit在返回之前需要将第0位和第4位清楚*/

pdFALSE,     /* Don't wait for both bits, either bit will do.不是等待所有都要置                               xWaitForAllBits 位,只要有一个满足条件就好*/

xTicksToWait); /* Waita maximum of 100ms for either bit to be set. */

      执行之后的的内存情况如下:


之后由于发生任务调度,任务TCB_Second得到执行执行:

uxBits =xEventGroupSetBits (xEventGroup, /* The event group being tested. */

BIT_0 | BIT_4)/* The bits within the eventgroup to wait for. */

        由于此时在xTasksWaitingForBits中挂载了节点,和本文的情况(1)出现了不同情形。在这种情况下xEventGroupSetBits 内部所进行的操作有:

  • 首先将uxEventBits设置成BIT_0 | BIT_4(执行的过程是uxEventBits |= BIT_0 | BIT_4
  • 由于xTasksWaitingForBits链表中有节点存在,得到xTasksWaitingForBits链表中每一个节点xEventListItemxItemValue值(TCB_First),分别提取xItemValue中的控制位(第24~31位)和等待事件位(xItemValue中的第0到第23位)。
  •  将等待事件位(xItemValue中的第0到第23位)和xEventGroupuxEventBits进行比较,由于TCB_First并不是等待BIT_0 BIT_4同时置位,所以当前uxEventBits的值满足TCB_First的要求(在本例中,只要uxEventBits中有一个位和xItemValue0到第23位中的BIT_0 BIT_4位一样就满足了TCB_First的要求)(可以这样理解,xEventListItemxItemValue提出要求,而uxEventBits是用来满足这种要求的),如果满足要求就标记xMatchFound为pdTrue(在本例中是满足要求的因此标记为pdTrue)。
  • 如果xMatchFound为pdTrue,将TCB_First的xEventListItemxItemValue的值修改uxEventBits|eventUNBLOCKED_DUE_TO_BIT_SETeventUNBLOCKED_DUE_TO_BIT_SET用来标志记录解挂原因)更新完的xItemValue中记录的是解挂原因以及到底是什么样的uxEventBits使TCB_First解挂的。
  • xEventListItemxStateListItem分别从xTasksWaitingForBits链表pxDelayedTaskList链表中删除,并且将任务控制块TCB_First放到相应的就绪链表中,如果TCB_First任务控制块的优先级大于当前任务控制块的优先级,则标记需要进行任务调度,标记记录在xYieldPending(是个全局变量)中。(需要注意的是如果xTasksWaitingForBits链表中不只有一个xEventListItem节点时,需要遍历xTasksWaitingForBits链表,如果节点都满足要求则会将所有节点TCB都解挂,如果没有一个节点xMatchFound,也不清零,直接返回uxEventBits的值,然后退出函数)。
  •  如果在TCB_First的xEventGroupWaitBits中输入参数xClearOnExit设置为pdTrue,要将uxEventBits相应位清零(需要清除哪些位是TCB_FirstxEventListItemxItemValue第0~23位中置位的那些位)这点一定要注意xClearOnExit是在xEventGroupSetBits中完成的,而且清零操作是在遍历完xTasksWaitingForBits链表中所有xEventListItem节点之后,统一清零的
  • 然后根据xYieldPending是否为pdTrue,在xTaskResumeAll中发生任务调度。

  • 当调度回来再次执行本任务控制块的时候,则返回当前uxEventBits值(注意此时uxEventBits值的值不一定是0,因为其他函数可能也会调用xEventGroupSetBits












0 0
原创粉丝点击