释放双眼,带上耳机,听听看~!
一,介绍
事件组的好处:
– 任务将处于阻塞状态以等待一个或多个事件的组合。它有助于同步多个任务,广播事件(通过设置任务的事件位以通知发生的事件)到多个任务。
– 取消阻止等待相同事件/操作或要发生/完成的事件/操作组合的所有任务。
– 事件标志可以是0或1.它用于指示事件是否发生。并且由EventBits_t数据类型中的一个位表示。
– 事件组是一组事件标志。
– EventBits_t的值为0x92(1001 0010)。这意味着设置了事件位1,4和7。
– 您必须定义每个事件位的含义。例如:位0表示发送消息事件已完成。
– 让我们进行2次演示:
+演示1(“任务将处于阻塞状态以等待一个或多个事件的组合”):计时器正在运行,计时器超时时计数器将增加3个任务正在等待反击事件。如果counter等于2,则任务1将离开Blocked状态。如果计数器等于3,则任务2和任务3都将离开阻塞状态,计数器将重置为0.
+演示2(“同步多个任务”):创建3个任务,其中任务1(最高优先级)将打印“任务1完成“然后等到任务2完成打印”任务2完成“并且任务3完成打印”。
演示1
- #include "freertos/event_groups.h"
-
- /*定义事件位 */
- #define TASK_1_BIT ( 1 << 0 ) //1
- #define TASK_2_BIT ( 1 << 1 ) //10
- #define TASK_3_BIT ( 1 << 2 ) //100
- #define ALL_SYNC_BITS (TASK_1_BIT | TASK_2_BIT | TASK_3_BIT) //111
-
-
- /* 创建硬件定时器 */
- hw_timer_t * timer = NULL;
- /* 创建事件组 */
- EventGroupHandle_t eg;
- int count = 0;
-
- /* timer ISR callback */
- void IRAM_ATTR onTimer(){
- BaseType_t xHigherPriorityTaskWoken;
- count++;
- if(count == 2){
- /* 如果counter等于2则设置 task1 */
- xEventGroupSetBitsFromISR(eg,TASK_1_BIT, &xHigherPriorityTaskWoken);
- }else if(count == 3){
- /* 如果counter等于3然后设置任务2的事件位和3 * */
- xEventGroupSetBitsFromISR(eg,TASK_2_BIT | TASK_3_BIT, &xHigherPriorityTaskWoken);
- }else if(count == 4){
- /* counter再次启动 */
- count = 0;
- }
- }
-
- void setup() {
-
- Serial.begin(112500);
- eg = xEventGroupCreate();
-
-
- /* 1/(80MHZ/80) = 1us */
- timer = timerBegin(0, 80, true);
-
- /* 将onTimer函数附加到我们的计时器 */
- timerAttachInterrupt(timer, &onTimer, true);
-
- /* 设置闹钟每秒调用onTimer函数1 tick为1us
- => 1秒为1000000us*/
- /* 重复闹钟(第三个参数) */
- timerAlarmWrite(timer, 1000000, true);
-
- /* 发出警报 */
- timerAlarmEnable(timer);
- Serial.println("start timer");
-
- xTaskCreate(
- task1, /* 任务功能 */
- "task1", /* 任务名称. */
- 10000, /* 任务的堆栈大小 */
- NULL, /* 任务的参数*/
- 1, /* 任务的优先级 */
- NULL); /* 跟踪创建任务的任务句柄 */
- xTaskCreate(
- task2,
- "task2",
- 10000,
- NULL,
- 1,
- NULL);
- xTaskCreate(
- task3,
- "task3",
- 10000,
- NULL,
- 1,
- NULL);
- }
-
- void loop() {
-
- }
-
- void task1( void * parameter )
- {
- for(;;){
- /* 永远等待,直到任务1的事件位被设置为 */
- EventBits_t xbit = xEventGroupWaitBits(eg, TASK_1_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
- Serial.print("task1 has even bit: ");
- Serial.println(xbit);
- }
- vTaskDelete( NULL );
- }
- /* 此任务类似于sendTask1 */
- void task2( void * parameter )
- {
-
- for(;;){
-
- EventBits_t xbit = xEventGroupWaitBits(eg, TASK_2_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
- Serial.print("task2 has even bit: ");
- Serial.println(xbit);
- }
- vTaskDelete( NULL );
- }
- void task3( void * parameter )
- {
- for(;;){
-
- EventBits_t xbit = xEventGroupWaitBits(eg, TASK_3_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
- Serial.print("task3 has even bit: ");
- Serial.println(xbit);
- }
- vTaskDelete( NULL );
- }
-
测试结果

演示2
- #include "freertos/event_groups.h"
-
- /* 定义事件位 */
- #define TASK_1_BIT ( 1 << 0 ) //1
- #define TASK_2_BIT ( 1 << 1 ) //10
- #define TASK_3_BIT ( 1 << 2 ) //100
- #define ALL_SYNC_BITS (TASK_1_BIT | TASK_2_BIT | TASK_3_BIT) //111
-
- /* 创建事件组 */
- EventGroupHandle_t eg;
-
- void setup() {
-
- Serial.begin(112500);
- eg = xEventGroupCreate();
-
- xTaskCreate(
- task1, /* 任务函数. */
- "task1", /* 任务名称 */
- 10000, /* 任务的堆栈大小 */
- NULL, /* 任务的参数 */
- 3, /*任务的优先级 */
- NULL); /* 跟踪创建的任务的任务句柄*/
- xTaskCreate(
- task2,
- "task2",
- 10000,
- NULL,
- 1,
- NULL);
- xTaskCreate(
- task3,
- "task3",
- 10000,
- NULL,
- 1,
- NULL);
- }
-
- void loop() {
-
- }
-
- void task1( void * parameter )
- {
- for(;;){
- Serial.println("task1 done");
- /* task 2完成打印,因此设置其事件位并等待其他任务完成 */
- EventBits_t uxBits = xEventGroupSync(eg, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
- /* 如果其他任务完成,则所有事件位将被设置为*/
- if( ( uxBits & ALL_SYNC_BITS ) == ALL_SYNC_BITS ){
- Serial.println("task 1 - all task done !!!");
- }
- }
- vTaskDelete( NULL );
- }
-
- void task2( void * parameter )
- {
-
- for(;;){
- Serial.println("task2 done");
- /* task 2完成打印,因此设置其事件位 */
- EventBits_t uxBits = xEventGroupSync( eg, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
- }
- vTaskDelete( NULL );
- }
- void task3( void * parameter )
- {
- for(;;){
- Serial.println("task3 done");
- /* task 3完成打印,因此设置其事件位* */
- EventBits_t uxBits = xEventGroupSync( eg, TASK_3_BIT, ALL_SYNC_BITS, portMAX_DELAY );
- }
- vTaskDelete( NULL );
- }
-
测试结果
