• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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