1. Introduction
Benefits of event group:
- A task will be in Blocked state to wait for a combination of one or more events. it helps synchronizing multiple tasks, broadcasting events (by setting event bits of tasks to notify that event occurred) to more than one task.
- Unblock all the tasks that were waiting for same event/action or a combination of events/actions to occur/complete.
- Event Flag can be 0 or 1. It is used to indicate whether an event occur or not. And is represented by a bit in EventBits_t data type.
- Event Group is a set of event flags.
- An EventBits_t has the value 0x92 (1001 0010). It means event bits 1, 4 and 7 are set.
- You have to define the meaning of each event bits. For example: bit 0 is to indicate that the sending message event is finished or not.
- Let 's make 2 demos:
+ Demo 1 ("A task will be in Blocked state to wait for a combination of one or more events"): a timer is running, a counter will be increased when timer is timeout and 3 tasks that are waiting for counter event. If counter is equal 2, task 1 will leave Blocked state. if counter is equal 3, both task 2 and task 3 will leave Blocked state and counter will be reset to 0.
+ Demo 2 ("synchronizing multiple tasks"): create 3 tasks in which task 1 (highest priority) will print "task 1 done" and then wait until task 2 finishes printing "task 2 done" and task 3 finishes printing "task 3 done"
2. Demo
2.1 Demo 1
Benefits of event group:
- A task will be in Blocked state to wait for a combination of one or more events. it helps synchronizing multiple tasks, broadcasting events (by setting event bits of tasks to notify that event occurred) to more than one task.
- Unblock all the tasks that were waiting for same event/action or a combination of events/actions to occur/complete.
- Event Flag can be 0 or 1. It is used to indicate whether an event occur or not. And is represented by a bit in EventBits_t data type.
- Event Group is a set of event flags.
- An EventBits_t has the value 0x92 (1001 0010). It means event bits 1, 4 and 7 are set.
- You have to define the meaning of each event bits. For example: bit 0 is to indicate that the sending message event is finished or not.
- Let 's make 2 demos:
+ Demo 1 ("A task will be in Blocked state to wait for a combination of one or more events"): a timer is running, a counter will be increased when timer is timeout and 3 tasks that are waiting for counter event. If counter is equal 2, task 1 will leave Blocked state. if counter is equal 3, both task 2 and task 3 will leave Blocked state and counter will be reset to 0.
+ Demo 2 ("synchronizing multiple tasks"): create 3 tasks in which task 1 (highest priority) will print "task 1 done" and then wait until task 2 finishes printing "task 2 done" and task 3 finishes printing "task 3 done"
2. Demo
2.1 Demo 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include "freertos/event_groups.h" /* define event bits */ #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 /* create a hardware timer */ hw_timer_t * timer = NULL; /* create event group */ EventGroupHandle_t eg; int count = 0; /* timer ISR callback */ void IRAM_ATTR onTimer(){ BaseType_t xHigherPriorityTaskWoken; count++; if(count == 2){ /* if counter is equal 2 then set event bit of task1 */ xEventGroupSetBitsFromISR(eg,TASK_1_BIT, &xHigherPriorityTaskWoken); }else if(count == 3){ /* if counter is equal 3 then set event bit of task 2 and 3 */ xEventGroupSetBitsFromISR(eg,TASK_2_BIT | TASK_3_BIT, &xHigherPriorityTaskWoken); }else if(count == 4){ /* reset counter to start again */ count = 0; } } void setup() { Serial.begin(112500); eg = xEventGroupCreate(); /* Use 1st timer of 4 */ /* 1 tick take 1/(80MHZ/80) = 1us so we set divider 80 and count up */ timer = timerBegin(0, 80, true); /* Attach onTimer function to our timer */ timerAttachInterrupt(timer, &onTimer, true); /* Set alarm to call onTimer function every second 1 tick is 1us => 1 second is 1000000us */ /* Repeat the alarm (third parameter) */ timerAlarmWrite(timer, 1000000, true); /* Start an alarm */ timerAlarmEnable(timer); Serial.println("start timer"); xTaskCreate( task1, /* Task function. */ "task1", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ NULL); /* Task handle to keep track of created task */ xTaskCreate( task2, /* Task function. */ "task2", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ NULL); /* Task handle to keep track of created task */ xTaskCreate( task3, /* Task function. */ "task3", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ NULL); /* Task handle to keep track of created task */ } void loop() { } void task1( void * parameter ) { for(;;){ /* wait forever until event bit of task 1 is set */ EventBits_t xbit = xEventGroupWaitBits(eg, TASK_1_BIT, pdTRUE, pdTRUE, portMAX_DELAY); Serial.print("task1 has even bit: "); Serial.println(xbit); } vTaskDelete( NULL ); } /* this task is similar to sendTask1 */ void task2( void * parameter ) { for(;;){ /* wait forever until event bit of task 2 is set */ 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(;;){ /* wait forever until event bit of task 3 is set */ EventBits_t xbit = xEventGroupWaitBits(eg, TASK_3_BIT, pdTRUE, pdTRUE, portMAX_DELAY); Serial.print("task3 has even bit: "); Serial.println(xbit); } vTaskDelete( NULL ); } |
Figure: tasks are waiting for event bits are set
2.2 Demo 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include "freertos/event_groups.h" /* define event bits */ #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 /* create event group */ EventGroupHandle_t eg; void setup() { Serial.begin(112500); eg = xEventGroupCreate(); xTaskCreate( task1, /* Task function. */ "task1", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 3, /* priority of the task */ NULL); /* Task handle to keep track of created task */ xTaskCreate( task2, /* Task function. */ "task2", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ NULL); /* Task handle to keep track of created task */ xTaskCreate( task3, /* Task function. */ "task3", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ NULL); /* Task handle to keep track of created task */ } void loop() { } void task1( void * parameter ) { for(;;){ Serial.println("task1 done"); /* task 2 finishes printing so set its event bit and wait until other tasks finish */ EventBits_t uxBits = xEventGroupSync(eg, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY ); /* if other tasks finished then all event bits would be set*/ if( ( uxBits & ALL_SYNC_BITS ) == ALL_SYNC_BITS ){ Serial.println("task 1 - all task done !!!"); } } vTaskDelete( NULL ); } /* this task is similar to sendTask1 */ void task2( void * parameter ) { for(;;){ Serial.println("task2 done"); /* task 2 finishes printing so set its event bit */ 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 finishes printing so set its event bit */ EventBits_t uxBits = xEventGroupSync( eg, TASK_3_BIT, ALL_SYNC_BITS, portMAX_DELAY ); } vTaskDelete( NULL ); } |
Figure: task 1 wait until task 2 and task 3 finish
0 Comments