1# Event 2 3 4## Basic Concepts 5 6An event is a communication mechanism used to synchronize tasks. Events have the following features: 7 8- Events can be synchronized in one-to-many or many-to-many mode. In one-to-many mode, a task can wait for multiple events. In many-to-many mode, multiple tasks can wait for multiple events. However, a write event wakes up only one task from the block. 9 10- Event read timeout mechanism is used. 11 12- Events are used for task synchronization, but not for data transmission. 13 14APIs are provided to initialize, read/write, clear, and destroy events. 15 16 17## Working Principles 18 19### Event Control Block 20 21The event control block is a structure in the event initialization function. It passes in event identifies for operations such as event read and write. The data structure of the event control block is as follows: 22 23 24``` 25typedef struct tagEvent { 26 UINT32 uwEventID; /* Event set, which is a collection of events processed (written and cleared). */ 27 LOS_DL_LIST stEventList; /* List of tasks waiting for specific events. */ 28} EVENT_CB_S, *PEVENT_CB_S; 29``` 30 31 32### Working Principles 33 34**Initializing an Event** 35 36An event control block is created to maintain a set of processed events and a linked list of tasks waiting for specific events. 37 38**Writing an Event** 39 40When an event is written to the event control block, the event control block updates the event set, traverses the task linked list, and determines whether to wake up related tasks based on the task conditions. 41 42**Reading an Event** 43 44If the event to read already exists, it is returned synchronously. In other cases, the event is returned based on the timeout period and event triggering conditions. If the wait condition is met before the timeout period expires, the blocked task will be directly woken up. Otherwise, the blocked task will be woken up only after the timeout period has expired. 45 46The parameters **eventMask** and **mode** determine whether the condition for reading an event is met. **eventMask** specifies the event mask. **mode** specifies the handling mode, which can be any of the following: 47 48- **LOS_WAITMODE_AND**: Read the event only when all the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned. 49 50- **LOS_WAITMODE_OR**: Read the event only when any of the events corresponding to **eventMask** occur. Otherwise, the task will be blocked, or an error code will be returned. 51 52- **LOS_WAITMODE_CLR**: This mode must be used with one or all of the event modes (LOS_WAITMODE_AND | LOS_WAITMODE_CLR or LOS_WAITMODE_OR | LOS_WAITMODE_CLR). In this mode, if all event modes or any event mode is successful, the corresponding event type bit in the event control block will be automatically cleared. 53 54**Clearing Events** 55 56The events in the event set of the event control block can be cleared based on the specified mask. The mask **0** means to clear the event set; the mask **0xffff** means the opposite. 57 58**Destroying Events** 59 60The event control block can be destroyed to release resources. 61 62**Figure 1** Event working mechanism for a mini system 63 64![](figures/event-working-mechanism-for-mini-systems.png "event-working-mechanism-for-mini-systems") 65 66 67## Available APIs 68 69| Category| API| Description| 70| -------- | -------- | -------- | 71| Checking an event | LOS_EventPoll | Checks whether the expected event occurs based on **eventID**, **eventMask**, and **mode**.<br>**NOTE**<br>If **mode** contains **LOS_WAITMODE_CLR** and the expected event occurs, the event that meets the requirements in **eventID** will be cleared. In this case, **eventID** is an input parameter and an output parameter. In other cases, **eventID** is used only as an input parameter. | 72| Initializing an event control block | LOS_EventInit | Initializes an event control block.| 73| Reading an event | LOS_EventRead | Reads an event (wait event). The task will be blocked to wait based on the timeout period (in ticks).<br>If no event is read, **0** is returned.<br>If an event is successfully read, a positive value (event set) is returned.<br>In other cases, an error code is returned.| 74| Writing an event | LOS_EventWrite | Writes an event to the event control block.| 75| Clearing events | LOS_EventClear | Clears events in the event control block based on the event mask. | 76| Destroying events | LOS_EventDestroy | Destroys an event control block.| 77 78 79## How to Develop 80 81The typical event development process is as follows: 82 831. Initialize an event control block. 84 852. Block a read event. 86 873. Write events. 88 894. Wake up the blocked task, read the event, and check whether the event meets conditions. 90 915. Handle the event control block. 92 936. Destroy an event control block. 94 95 96> **NOTE** 97> - For event read and write operations, the 25th bit (`0x02U << 24`) of the event is reserved and cannot be set. 98> 99> - Repeated writes of the same event are treated as one write. 100 101 102## Development Example 103 104 105### Example Description 106 107In the **ExampleEvent** task, create an **EventReadTask** task with a timout period of 100 ticks. When the **EventReadTask** task is blocked, **ExampleEvent** task writes an event. You can understand the task switching during event operations based on the sequence in which logs are recorded. 108 1091. In the **ExampleEvent** task, create an **EventReadTask** task with a timeout period of 100 ticks. The **EventReadTask** task has a higher priority than the **ExampleEvent** task. 110 1112. **EventReadTask** is scheduled to read event **0x00000001**, but suspended to wait 100 ticks. The **ExampleEvent** task is scheduled to write event **0x00000001**. 112 1133. When **ExampleEvent** is scheduled to write event **0x00000001**, the wait time of **EventReadTask** expires and **EventReadTask** task is scheduled to run. 114 1154. The **EventReadTask** task is executed. 116 1175. The **ExampleEvent** task is executed. 118 119 120### Sample Code 121 122The sample code is as follows: 123 124The sample code can be compiled and verified in **./kernel/liteos_m/testsuites/src/osTest.c**. The **ExampleEvent()** function is called in **TestTaskEntry**. 125 126 127``` 128#include "los_event.h" 129#include "los_task.h" 130 131/* Event control struct */ 132EVENT_CB_S g_exampleEvent; 133 134/* Type of the wait event */ 135#define EVENT_WAIT 0x00000001 136 137/* Wait timeout time */ 138#define EVENT_TIMEOUT 100 139 140/* Example task entry function */ 141VOID EventReadTask(VOID) 142{ 143 UINT32 ret; 144 UINT32 event; 145 146 /* Set a timeout period for event reading to 100 ticks. If the specified event is not read within 100 ticks, the read operation times out and the task is woken up. */ 147 printf("Example_Event wait event 0x%x \n", EVENT_WAIT); 148 149 event = LOS_EventRead(&g_exampleEvent, EVENT_WAIT, LOS_WAITMODE_AND, EVENT_TIMEOUT); 150 if (event == EVENT_WAIT) { 151 printf("Example_Event, read event :0x%x\n", event); 152 } else { 153 printf("Example_Event, read event timeout\n"); 154 } 155} 156 157UINT32 ExampleEvent(VOID) 158{ 159 UINT32 ret; 160 UINT32 taskId; 161 TSK_INIT_PARAM_S taskParam = { 0 }; 162 163 /* Initialize the event control block. */ 164 ret = LOS_EventInit(&g_exampleEvent); 165 if (ret != LOS_OK) { 166 printf("init event failed .\n"); 167 return LOS_NOK; 168 } 169 170 /* Create a task. */ 171 taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)EventReadTask; 172 taskParam.pcName = "EventReadTask"; 173 taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; 174 taskParam.usTaskPrio = 3; 175 ret = LOS_TaskCreate(&taskId, &taskParam); 176 if (ret != LOS_OK) { 177 printf("task create failed.\n"); 178 return LOS_NOK; 179 } 180 181 /* Write an event. */ 182 printf("Example_TaskEntry write event.\n"); 183 184 ret = LOS_EventWrite(&g_exampleEvent, EVENT_WAIT); 185 if (ret != LOS_OK) { 186 printf("event write failed.\n"); 187 return LOS_NOK; 188 } 189 190 /* Clear the flag. */ 191 printf("EventMask:%d\n", g_exampleEvent.uwEventID); 192 LOS_EventClear(&g_exampleEvent, ~g_exampleEvent.uwEventID); 193 printf("EventMask:%d\n", g_exampleEvent.uwEventID); 194 195 /* Delete the event. */ 196 ret = LOS_EventDestroy(&g_exampleEvent); 197 if (ret != LOS_OK) { 198 printf("destory event failed .\n"); 199 return LOS_NOK; 200 } 201 202 return LOS_OK; 203} 204``` 205 206 207### Verification 208 209The development is successful if the return result is as follows: 210 211 212 213``` 214Example_Event wait event 0x1 215Example_TaskEntry write event. 216Example_Event, read event :0x1 217EventMask:1 218EventMask:0 219``` 220