事件标志组的具体实现过程和前面信号量实现方式非常相似,信号量只能和单个任务或事件进行同步,而事件标志组能和多个任务或事件进行同步。事件标志组顾名思义就是用事件位来表示某个任务是否发生了,发生了的话就标记一个标志位,然后通知接收任务去做相应的处理工作。当然标志可以以组的形式出现,就是接收任务同时要求有多个事件(所有需求的标志都置位了)发生了才执行处理。
事件标志组的相关接口函数如下:
/* 创建事件标志组 */
xEventGroupCreate(void)
EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer )
/* 将指定事件位清除 */
xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear)
xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear)
/* 将指定事件位置1 */
xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet)
xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t * pxHigherPriorityTaskWoken)
/* 等待指定的事件位 */
xEventGroupWaitBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait)
/* 获取当前事件标志组的值 */
xEventGroupGetBits(xEventGroup)
xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup)
关于静态分配和中断相关的接口函数这里就不分析了,这里只分析几个核心的函数,关于中断、静态分配的处理方式和非中断、动态的逻辑处理方式大同小异,前面信号量有分析过这块差异,可以触类旁通。先分析一下创建事件标志组的源码:
#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
EventGroupHandle_t xEventGroupCreate( void )
{
EventGroup_t *pxEventBits;
/* 动态分配事件标志组存储空间 */
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */
if( pxEventBits != NULL )
{
/* 初始化事件位标志为0*/
pxEventBits->uxEventBits = 0;
/* 初始化任务等待事件标志列表 */
vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
{
/* 使用动态分配 */
pxEventBits->ucStaticallyAllocated = pdFALSE;
}
#endif
traceEVENT_GROUP_CREATE( pxEventBits );
}
else
{
traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */
}
return pxEventBits;
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
代码比较简单,涉及到一个事件标志组的结构体,它的定义如下:
typedef struct EventGroupDef_t
{
/* 保存事件标志位 */
EventBits_t uxEventBits;
/* 任务等待标志列表 */
List_t xTasksWaitingForBits;
#if( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxEventGroupNumber;
#endif
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1