广东湘恒智能科技有限公司
主营产品: 西门子PLC代理商,plc变频器,伺服电机,人机界面,触摸屏,线缆,DP接头
SIEMENS山东省淄博市 西门子代理商——西门子华北一级总代理

11基础概述

1.1 基本作用

事件标志的作用类似于全局型的flag,多个标志组合在一起构成事件标志组,这里先分析一下事件标志组于全局flag的区别:

使用事件标志组可以让 FreeRTOS内核有效地管理任务,而全局变量是无法做到的,任务的超时等机制需要用户自己去实现

使用了全局变量就要防止多任务的访问冲突,而使用事件标志组则处理好了这个问题,用户无需担心

使用事件标志组可以有效地解决中断服务程序和任务之间的同步问题

1.2 运行原理

如上图:

任务1在一个循环中等待事件的到来,等待时处于阻塞状态,即任务挂起状态。阻塞的时间可用设置。当有事件位被置位时,执行处理事件。

任务1的处理事件可以触发事件(给自身的任务触发事件),但这种方式触发后,只能等程序再次运行到xEventGroupWaitBits才能处理

任务2或其它任务可以触发事件(这是比较常用的用法),这样,在任务2触发事件后,任务1可以从阻塞态变为就绪态,如果任务1的优先级较高,则任务1开始运行,执行处理事件,实现任务间的同步

中断中也可以可以触发事件(这也是比较常用的用法),作用也是实现同步,只是需要使用加FromISR后缀的API函数

1.3 事件组的最大位数

事件标志存储在一个EventBits_t类型的变量中,该变量在事件组结构体中定义,事件标志组的可用位数通过宏定义确定:

configUSE_16_BIT_TICKS定义为1,uxEventBits是16位的,低8位用来存储事件组

configUSE_16_BIT_TICKS 定义为0,uxEventBits是32位的,低24位用来存储事件组

注:高8位用于系统内核使用,不可用户使用!












#if configUSE_16_BIT_TICKS == 1    #define eventCLEAR_EVENTS_ON_EXIT_BIT0x0100U    #define eventUNBLOCKED_DUE_TO_BIT_SET0x0200U    #define eventWAIT_FOR_ALL_BITS          0x0400U    #define eventEVENT_BITS_CONTROL_BYTES0xff00U#else    #define eventCLEAR_EVENTS_ON_EXIT_BIT0x01000000UL     /*在退出时清除位*/    #define eventUNBLOCKED_DUE_TO_BIT_SET0x02000000UL    #define eventWAIT_FOR_ALL_BITS          0x04000000UL     /*等待所有位*/    #define eventEVENT_BITS_CONTROL_BYTES0xff000000UL#endif


22源码分析

首先来看一下事件控制块:

2.1 事件控制块

除了事件标志组变量之外,FreeRTOS还使用了一个链表来记录等待事件的任务,所有在等待此事件的任务均会被挂载在等待事件列表xTasksWaitingForBits














typedef struct xEventGroupDefinition{    EventBits_t uxEventBits;        /*事件标志组变量*/    List_t xTasksWaitingForBits;        /*等待事件组的任务链表 */
   #if( configUSE_TRACE_FACILITY == 1 )        UBaseType_t uxEventGroupNumber;    #endif
   #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )        uint8_t ucStaticallyAllocated;    #endif} EventGroup_t;

2.2 创建事件标志组

主要功能是为事件标志组控制块分配内存以及创建一个任务等待列表


































/*创建事件标志组*/#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
   EventGroupHandle_t xEventGroupCreate( void ){    EventGroup_t *pxEventBits;
       /* 为事件标志组控制块分配内存 */        pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );
       if( pxEventBits != NULL )        {            pxEventBits->uxEventBits = 0;            /*创建一个列表*/            vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
           #if( configSUPPORT_STATIC_ALLOCATION == 1 )            {                pxEventBits->ucStaticallyAllocated = pdFALSE;            }            #endif /* configSUPPORT_STATIC_ALLOCATION */
           traceEVENT_GROUP_CREATE( pxEventBits );        }        else        {            traceEVENT_GROUP_CREATE_FAILED();        }
       return ( EventGroupHandle_t ) pxEventBits;}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */


展开全文
相关产品
拨打电话 微信咨询 发送询价