1 /* esp_event (event loop library) basic example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 
10 #include "esp_log.h"
11 
12 #include "freertos/FreeRTOS.h"
13 #include "freertos/task.h"
14 
15 #include "event_source.h"
16 #include "esp_event_base.h"
17 
18 static const char* TAG = "user_event_loops";
19 
20 // Event loops
21 esp_event_loop_handle_t loop_with_task;
22 esp_event_loop_handle_t loop_without_task;
23 
application_task(void * args)24 static void application_task(void* args)
25 {
26     while(1) {
27         ESP_LOGI(TAG, "application_task: running application task");
28         esp_event_loop_run(loop_without_task, 100);
29         vTaskDelay(10);
30     }
31 }
32 
33 /* Event source task related definitions */
34 ESP_EVENT_DEFINE_BASE(TASK_EVENTS);
35 
36 TaskHandle_t g_task;
37 
task_iteration_handler(void * handler_args,esp_event_base_t base,int32_t id,void * event_data)38 static void task_iteration_handler(void* handler_args, esp_event_base_t base, int32_t id, void* event_data)
39 {
40     // Two types of data can be passed in to the event handler: the handler specific data and the event-specific data.
41     //
42     // The handler specific data (handler_args) is a pointer to the original data, therefore, the user should ensure that
43     // the memory location it points to is still valid when the handler executes.
44     //
45     // The event-specific data (event_data) is a pointer to a deep copy of the original data, and is managed automatically.
46     int iteration = *((int*) event_data);
47 
48     char* loop;
49 
50     if (handler_args == loop_with_task) {
51         loop = "loop_with_task";
52     } else {
53         loop = "loop_without_task";
54     }
55 
56     ESP_LOGI(TAG, "handling %s:%s from %s, iteration %d", base, "TASK_ITERATION_EVENT", loop, iteration);
57 }
58 
task_event_source(void * args)59 static void task_event_source(void* args)
60 {
61     for(int iteration = 1; iteration <= TASK_ITERATIONS_COUNT; iteration++) {
62         esp_event_loop_handle_t loop_to_post_to;
63 
64         if (iteration % 2 == 0) {
65             // if even, post to the event loop with dedicated task
66             loop_to_post_to = loop_with_task;
67         } else {
68             // if odd, post to the event loop without a dedicated task
69             loop_to_post_to = loop_without_task;
70         }
71 
72         ESP_LOGI(TAG, "posting %s:%s to %s, iteration %d out of %d", TASK_EVENTS, "TASK_ITERATION_EVENT",
73                 loop_to_post_to == loop_with_task ? "loop_with_task" : "loop_without_task",
74                 iteration, TASK_ITERATIONS_COUNT);
75 
76         ESP_ERROR_CHECK(esp_event_post_to(loop_to_post_to, TASK_EVENTS, TASK_ITERATION_EVENT, &iteration, sizeof(iteration), portMAX_DELAY));
77 
78         vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD));
79     }
80 
81     vTaskDelay(pdMS_TO_TICKS(TASK_PERIOD));
82 
83     ESP_LOGI(TAG, "deleting task event source");
84 
85     vTaskDelete(NULL);
86 }
87 
88 /* Example main */
app_main(void)89 void app_main(void)
90 {
91     ESP_LOGI(TAG, "setting up");
92 
93     esp_event_loop_args_t loop_with_task_args = {
94         .queue_size = 5,
95         .task_name = "loop_task", // task will be created
96         .task_priority = uxTaskPriorityGet(NULL),
97         .task_stack_size = 2048,
98         .task_core_id = tskNO_AFFINITY
99     };
100 
101     esp_event_loop_args_t loop_without_task_args = {
102         .queue_size = 5,
103         .task_name = NULL // no task will be created
104     };
105 
106     // Create the event loops
107     ESP_ERROR_CHECK(esp_event_loop_create(&loop_with_task_args, &loop_with_task));
108     ESP_ERROR_CHECK(esp_event_loop_create(&loop_without_task_args, &loop_without_task));
109 
110     // Register the handler for task iteration event. Notice that the same handler is used for handling event on different loops.
111     // The loop handle is provided as an argument in order for this example to display the loop the handler is being run on.
112     ESP_ERROR_CHECK(esp_event_handler_instance_register_with(loop_with_task, TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler, loop_with_task, NULL));
113     ESP_ERROR_CHECK(esp_event_handler_instance_register_with(loop_without_task, TASK_EVENTS, TASK_ITERATION_EVENT, task_iteration_handler, loop_without_task, NULL));
114 
115     ESP_LOGI(TAG, "starting event source");
116 
117     // Create the event source task with the same priority as the current task
118     xTaskCreate(task_event_source, "task_event_source", 2048, NULL, uxTaskPriorityGet(NULL), NULL);
119 
120     ESP_LOGI(TAG, "starting application task");
121     // Create the application task with the same priority as the current task
122     xTaskCreate(application_task, "application_task", 2048, NULL, uxTaskPriorityGet(NULL), NULL);
123 }
124