用cubemx使用事件集时只有使用了cmisis v2 才能使用事件集这个数据结构。
创建一个事件集的高8位不用,低24位用做标记(事件位)。每一个位可相当于裸机开发时的flag,同时,每一位都可以当做二值信号量使用。不同的是,事件集可以判断每一个事件(每一位)的与成立或 或成立。
设置某个数据位则该位写1。
1.等待若干事件位一个成立就算成功 2.等待若干事件位同时成立都成立才算成功。
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
xEventGroupWaitBits(事件组,事件位(多个事件位用 | 连接 ,等待成功是否清除数据位,事件位的与还是或的关系,超时时间)
#define event1 (1<<0)
#define event2 (1<<1)
#defien event3 (1<<2)
使用:
xEventGroupWaitBits(eventgroup1,event1 | event2 | event3,pdTRUE, pdTRUE, portMAXDELAY); //等待第1位,第二位,第三位,同时满足后返回并清除数据位,否则阻塞。
内部执行过程
API函数
xEventGroupSetBits()
内部执行过程
等待事件位的任务不能在中断中触发,但写事件位的任务可以在中断中触发。触发后并不会真正的去修改事件位,而是会触发一个软件定时任务,这个软件定时器去执行设置事件位(调用xEventGroupSetBits)。
调用顺序:
xEventGroupSetBitsFromISR->xTimerPendFunctionCallFromIS>vEventGroupSetBitsCallback(作为函数指针传入执行)
- BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
- {
- BaseType_t xReturn;
-
- traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
- xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
-
- return xReturn;
- }
xEventGroupSetBitsFromISR() //在中断中写数据位。
为什么不在中断里写事件位?
对于一个实时操作系统来说,在中断中去设置事件位去唤醒其他的任务,这个处理时间是不确定的,会影响实时性。
由上可知,事件位的等待和设置位只是关闭了调度器,中断依然会触发,任务的调度以及硬件层面的中断依然触发,中断里能进行写事件位,不能进行等待事件位操作。在中断里写事件位会并不会去设置事件位而是去触发一个软件定时任务,由定时任务去设置事件位。