1.事件位
·当收到一条消息并且把这条消息处理掉以后就可以将某个位(标志)置1,当队列中没有消息需要处理的时候就可以将这个位(标志)置0
·当把队列中的消息通过网络发送输出以后就可以将某个位(标志)置1,当没有数据需要从网络发送出去的话就将这个位(标志)置0
·现在需要向网络中心发送一个心跳信息,将某个位(标志)置1。现在不需要向网络中发送心跳信息,这个位(标志)置0
2.事件组
一个事件组就是一组事件位,事件组中的事件位通过位编号来访问
·事件标志组的bit0表示队列中的消息是否处理掉
·事件标志组的bit1表示是否有消息需要从网络中发送出去
3.事件组的作用
在stm32里面freertos的事件组一般为16位,这样也就是可以同时存储16个事件的状态,事件其实和前面的信号量很像,可以类似看作成多个现在专门有一个东西"事件组"来管理多个信号量,之前的二值,互斥信号量都是只有一位的"事件组",当你任务或者中断存在多个标志位需要传递的时候,这个时候选择事件组会更加方便,你选择多个信号量也可以,但是你要挨个配置真的麻烦,这里可能会想到为啥不用全局变量,因为全局变量当被多个任务同时调用的时候,就会存在风险。这样我们还要自己去写任务调度的机制大大增加了成本。
事件的获取有两个方法:1.逻辑或:只要期望中的任何一个事件发生就可以唤醒任务, 2.逻辑与:任务所期望的事件必须全部获取,任务才可以被唤醒。
4.代码分析:
为事件结构体分配内存
初始化事件组
初始化等待链表【初始化等待链表是指在创建事件组时,将等待链表初始化为空。这样,在一开始没有任何进程或线程等待事件组信号时,事件组的等待链表为空,当一个或多个任务开始等待事件组信号时,其会加入等待链表中,等待该事件组信号被置位并被唤醒。】
EventGroupHandle_t xEventGroupCreate( void ){EventGroup_t *pxEventBits;/* Allocate the event group. */分配内存pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );if( pxEventBits != NULL ){事件组初始化为0pxEventBits->uxEventBits = 0;初始化等待链表vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );#if( configSUPPORT_STATIC_ALLOCATION == 1 ){/* Both static and dynamic allocation can be used, so note thisevent group was allocated statically in case the event group islater deleted. */pxEventBits->ucStaticallyAllocated = pdFALSE;}#endif /* configSUPPORT_STATIC_ALLOCATION */traceEVENT_GROUP_CREATE( pxEventBits );}else{traceEVENT_GROUP_CREATE_FAILED();}return ( EventGroupHandle_t ) pxEventBits;}
等待事件函数
xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
xEventGroup: 事件组的句柄
uxBitsToWaitFor:等待的事件位,可以用逻辑或等待多个标志位
xClearOnExit: pdTRUE--->当任务唤醒后自动清楚对应的事件标志位,也就是将1变为0 pdFALSE---> 任务唤醒后不会自动清除事件位。
xWaitForAllBits: pdTRUE--->当uxBitsToWaitFor指定的事件位都为1的时候,才可以满足任务唤醒的条件 pdFALSE--->当uxBitsToWaitFor指定事件位任何一位为1就可以唤醒任务。
xTicksToWait:等待的阻塞时间
//事件标志组处理任务
void eventgroup_task(void *pvParameters)
{u8 num;EventBits_t EventValue;while(1){if(EventGroupHandler!=NULL){//等待事件组中的相应事件位EventValue=xEventGroupWaitBits((EventGroupHandle_t )EventGroupHandler, (EventBits_t )EVENTBIT_ALL,(BaseType_t )pdTRUE, (BaseType_t )pdTRUE,(TickType_t )portMAX_DELAY); printf("事件标志组的值:%d\r\n",EventValue);LCD_ShowxNum(174,110,EventValue,1,16,0);num++;LED1=!LED1; LCD_Fill(6,131,233,313,lcd_discolor[num%14]);}else{vTaskDelay(10); //延时10ms,也就是10个时钟节拍}}
}
事件组置位函数
xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
xEventGroup:事件句柄
uxBitsToSet:将对应的事件设置为1。
void eventsetbit_task(void *pvParameters)
{u8 key;while(1){if(EventGroupHandler!=NULL){key=KEY_Scan(0);switch(key){case KEY1_PRES:xEventGroupSetBits(EventGroupHandler,EVENTBIT_1);break;case WKUP_PRES:xEventGroupSetBits(EventGroupHandler,EVENTBIT_2);break;}}vTaskDelay(10); //延时10ms,也就是10个时钟节拍}
}
任务同步函数xEventGroupSync
xEventGroupSync() 函数会等待多个事件位都置1后才会唤醒任务。它的功能是同步等待多个事件在不同任务中发生后再继续执行。
该函数需要指定一个事件组和一组要等待的辅助事件位(sync bits),当这些辅助事件位都为1时,该函数会返回并唤醒等待该事件组的任务。如果指定的辅助事件位没有全部置1,那么该任务将会被阻塞,并等待其他任务或事件处理程序将相应的位设置为1。