1# User Event Loops Example
2
3(See the README.md file in the upper level 'examples' directory for more information about examples.)
4
5This example demonstrates the creation and use of [**user event loops**](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/esp_event.html#). This example is a supplement to the [**default event loop** example](https://github.com/espressif/esp-idf/tree/master/examples/system/esp_event/default_event_loop), if the default event loop is not sufficient for the user's use case.
6
7This example demonstrates the following things regarding user event loops:
8
9### Creating Event Loops
10
11Creating a loop entails populating the structure `esp_event_loop_args_t` with the desired parameters and calling `esp_event_loop_create()`. The call to `esp_event_loop_create()` produces a handle to the loop, which is used to perform actions on that loop such as handler registration/unregistration and posting events.
12
13### Running Event Loops
14
15Depending on the parameters, the user can create either a loop with a dedicated task or one without. The purpose of the dedicated task is to unqueue events from the loop and execute its handlers. For loops without the dedicated task, the user should make a call to `esp_event_loop_run()` in an application task.
16
17### Handler Registration/Unregistration,
18
19Handler registration and unregistration works the same way as the default event loop, just with a different API, `esp_event_handler_instance_register_with()` and `esp_event_handler_instance_unregister_with()` respectively. There are two things this example highlights:
20
211. The possibility of registering the same handler for different loops
222. The ability to pass static data to handlers.
23
24### Posting Events to the Default Event Loop
25
26Posting events also works the same way as the default event loop, except with a different API, `esp_event_post_to()`.
27
28## How to use example
29
30### Hardware Required
31
32This example should be able to run on any commonly available ESP32 development board.
33
34### Configure the project
35
36```
37idf.py menuconfig
38```
39
40### Build and Flash
41
42Build the project and flash it to the board, then run monitor tool to view serial output:
43
44```
45idf.py -p PORT flash monitor
46```
47
48(Replace PORT with the name of the serial port to use.)
49
50(To exit the serial monitor, type ``Ctrl-]``.)
51
52See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
53
54## Example Output
55
56The example should have the following log output:
57
58```
59I (296) user_event_loops: setting up
60I (296) user_event_loops: starting event source
61I (296) user_event_loops: starting application task
62I (296) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 1 out of 10
63I (316) user_event_loops: application_task: running application task
64I (326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 1
65I (826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 2 out of 10
66I (826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 2
67I (1326) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 3 out of 10
68I (1326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 3
69I (1426) user_event_loops: application_task: running application task
70I (1826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 4 out of 10
71I (1826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 4
72I (2326) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 5 out of 10
73I (2326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 5
74I (2526) user_event_loops: application_task: running application task
75I (2826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 6 out of 10
76I (2826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 6
77I (3326) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 7 out of 10
78I (3326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 7
79I (3626) user_event_loops: application_task: running application task
80I (3826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 8 out of 10
81I (3826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 8
82I (4326) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 9 out of 10
83I (4326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 9
84I (4726) user_event_loops: application_task: running application task
85I (4826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 10 out of 10
86I (4826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 10
87I (5826) user_event_loops: application_task: running application task
88I (5826) user_event_loops: deleting task event source
89I (6926) user_event_loops: application_task: running application task
90I (8026) user_event_loops: application_task: running application task
91I (9126) user_event_loops: application_task: running application task
92...
93```
94
95## Example Breakdown
96
97### Setting of Event Sources
98
99This example has a single event source: a task with a loop inside. Events are raised for the task event source when the loop iterates.
100
101Two user event loops are created, one with a dedicated task and one without. Events are posted to either loops, depending on whether the iteration is odd or even. For the loop with a dedicated task, event handlers are automatically executed. However, for the loop without the dedicated task, a call to run the loop is made in one of the application tasks. As a result, the execution of the event handlers for this loop is interspersed with the execution of application task code.
102
103### Step-by-Step Explanation
104
105#### 1.Setting up user event loop and event handlers
106
107```
108I (296) user_event_loops: setting up
109I (296) user_event_loops: starting event source
110I (296) user_event_loops: starting application task
111```
112At this stage the two event loops are created, as well as the handlers for the iteration event registered. The event source is started, which will post the event to the appropriate loop. The application task which makes the call to run the loop without dedicated task, is also created and started.
113
114#### 2. Posting to the event loop
115```
116I (296) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 1 out of 10
117I (316) user_event_loops: application_task: running application task
118I (326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 1
119I (826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 2 out of 10
120I (826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 2
121I (1326) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_without_task, iteration 3 out of 10
122I (1326) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_without_task, iteration 3
123I (1426) user_event_loops: application_task: running application task
124I (1826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 4 out of 10
125...
126```
127In this section of the log we see the odd iterations posted to the loop without dedicated task, and the even iterations to the loop with a dedicated task. For the event with dedicated task, event handlers are executed automatically. The loop without a dedicated task, on the other hand, runs in the context of the application task.
128
129#### 3. Iteration Limit
130
131```
132...
133I (4826) user_event_loops: posting TASK_EVENTS:TASK_ITERATION_EVENT to loop_with_task, iteration 10 out of 10
134I (4826) user_event_loops: handling TASK_EVENTS:TASK_ITERATION_EVENT from loop_with_task, iteration 10
135I (5826) user_event_loops: application_task: running application task
136I (5826) user_event_loops: deleting task event source
137I (6926) user_event_loops: application_task: running application task
138I (8026) user_event_loops: application_task: running application task
139I (9126) user_event_loops: application_task: running application task
140...
141```
142
143The last of the iteration event is posted, and the event source is deleted. Because the loop without the task no longer receive events to execute, only the application task code executes.
144