• Home
Name Date Size #Lines LOC

..--

BUILD.gnD12-May-2024801 2117

README_zh.mdD12-May-20247.2 KiB226163

kernel_event_example.cD12-May-20243.7 KiB12165

README_zh.md

1# 小凌派-RK2206开发板OpenHarmonyOS内核开发-事件
2
3## 实验内容
4
5本例程演示如何在小凌派-RK2206开发板上使用鸿蒙LiteOS-M内核接口,进行事件编程开发。例程创建一个事件,两个任务;任务1调用读事件接口等待事件通知,任务2调用写事件接口通知任务1事件到达。
6
7![小凌派-RK2206开发板](../../docs/figures/lockzhiner-rk2206.jpg)
8
9## 程序设计
10
11事件是一种实现任务间通信的机制,可用于实现任务间的同步,但是仅仅作为事件类型的通信,不提供数据传输功能。一个任务可以等待多个事件的发生:可以是任意一个事件发生时唤醒任务进行事件处理;也可以是几个事件都发生后才唤醒任务进行事件处理。事件集合用32位无符号整型变量来表示,每一位代表一个事件。
12
13多任务环境下,任务之间往往需要同步操作,一个等待即是一个同步。事件可以提供一对多、多对多的同步操作。一对多同步模型:一个任务等待多个事件的触发;多对多同步模型:多个任务等待多个事件的触发。任务可以通过创建事件控制块来实现对事件的触发和等待操作。
14
15### API分析
16
17#### LOS_EventInit()
18
19```c
20UINT32 LOS_EventInit(PEVENT_CB_S eventCB);
21```
22
23**描述:**
24
25事件控制块初始化。
26
27**参数:**
28
29| 名字    | 描述           |
30| :------ | :------------- |
31| eventCB | 事件控制块指针 |
32
33**返回值:**
34
35| 返回值                   | 描述 |
36| :----------------------- | :--- |
37| LOS_OK                   | 成功 |
38| LOS_ERRNO_EVENT_PTR_NULL | 失败 |
39
40#### LOS_EventRead()
41
42```c
43UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeOut);
44```
45
46**描述:**
47
48读事件(等待事件),任务会根据timeOut(单位:tick)进行阻塞等待;
49未读取到事件时,返回值为0;正常读取到事件时,返回正值(事件发生的集合);其他情况返回特定错误码。
50
51**参数:**
52
53| 名字      | 描述           |
54| :-------- | :------------- |
55| eventCB   | 事件控制块指针 |
56| eventMask | 事件掩码       |
57| mode      | 事件读取的模式 |
58| timeOut   | 超时时间       |
59
60**返回值:**
61
62| 返回值                                                                                                                                                                                                                             | 描述 |
63| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--- |
64| LOS_OK                                                                                                                                                                                                                             | 成功 |
65| LOS_ERRNO_EVENT_SETBIT_INVALID`<br>` LOS_ERRNO_EVENT_EVENTMASK_INVALID `<br>` LOS_ERRNO_EVENT_READ_IN_INTERRUPT `<br>` LOS_ERRNO_EVENT_FLAGS_INVALID `<br>` LOS_ERRNO_EVENT_READ_IN_LOCK `<br>` LOS_ERRNO_EVENT_PTR_NULL | 失败 |
66
67#### LOS_EventWrite()
68
69```c
70UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events);
71```
72
73**描述:**
74
75写一个特定的事件到事件控制块。
76
77**参数:**
78
79| 名字    | 描述             |
80| :------ | :--------------- |
81| eventCB | 事件控制块指针   |
82| events  | 要写入的事件掩码 |
83
84**返回值:**
85
86| 返回值                                                          | 描述 |
87| :-------------------------------------------------------------- | :--- |
88| LOS_OK                                                          | 成功 |
89| LOS_ERRNO_EVENT_SETBIT_INVALID`<br>` LOS_ERRNO_EVENT_PTR_NULL | 失败 |
90
91#### LOS_EventClear()
92
93```c
94UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask);
95```
96
97**描述:**
98
99根据events掩码,清除事件控制块中的事件。
100
101**参数:**
102
103| 名字      | 描述             |
104| :-------- | :--------------- |
105| eventCB   | 事件控制块指针   |
106| eventMask | 要清除的事件掩码 |
107
108**返回值:**
109
110| 返回值                   | 描述 |
111| :----------------------- | :--- |
112| LOS_OK                   | 成功 |
113| LOS_ERRNO_EVENT_PTR_NULL | 失败 |
114
115### 软件设计
116
117**主要代码分析**
118
119在event_example函数中,通过LOS_EventInit函数创建事件,并通过LOS_TaskCreate函数创建两个线程:event_master_thread和event_slave_thread。
120
121```c
122void event_example()
123{
124    unsigned int thread_id1;
125    unsigned int thread_id2;
126    TSK_INIT_PARAM_S task1 = {0};
127    TSK_INIT_PARAM_S task2 = {0};
128    unsigned int ret = LOS_OK;
129
130    ret = LOS_EventInit(&m_event);
131    if (ret != LOS_OK)
132    {
133        printf("Failed to create EventFlags\n");
134        return;
135    }
136
137    task1.pfnTaskEntry = (TSK_ENTRY_FUNC)event_master_thread;
138    task1.uwStackSize = 2048;
139    task1.pcName = "event_master_thread";
140    task1.usTaskPrio = 5;
141    ret = LOS_TaskCreate(&thread_id1, &task1);
142    if (ret != LOS_OK)
143    {
144        printf("Failed to create event_master_thread ret:0x%x\n", ret);
145        return;
146    }
147
148    task2.pfnTaskEntry = (TSK_ENTRY_FUNC)event_slave_thread;
149    task2.uwStackSize = 2048;
150    task2.pcName = "event_slave_thread";
151    task2.usTaskPrio = 5;
152    ret = LOS_TaskCreate(&thread_id2, &task2);
153    if (ret != LOS_OK)
154    {
155        printf("Failed to create event_slave_thread ret:0x%x\n", ret);
156        return;
157    }
158}
159```
160
161event_slave_thread线程函数中通过LOS_EventRead函数将线程置于阻塞状态,等待事件到达;在event_master_thread函数中通过LOS_EventWrite函数每隔2S写入事件,实现线程的同步,2s后清除事件,重复以上流程。
162
163```c
164void event_master_thread()
165{
166    unsigned int ret = LOS_OK;
167
168    LOS_Msleep(1000);
169
170    while (1)
171    {
172        printf("%s write event:0x%x\n", __func__, EVENT_WAIT);
173        ret = LOS_EventWrite(&m_event, EVENT_WAIT);
174        if (ret != LOS_OK) {
175            printf("%s write event failed ret:0x%x\n", __func__, ret);
176        }
177
178        /*delay 1s*/
179        LOS_Msleep(2000);
180        LOS_EventClear(&m_event, ~m_event.uwEventID);
181    }
182}
183
184void event_slave_thread()
185{
186    unsigned int event;
187
188    while (1)
189    {
190        /* 阻塞方式读事件,等待事件到达*/
191        event = LOS_EventRead(&m_event, EVENT_WAIT, LOS_WAITMODE_AND, LOS_WAIT_FOREVER);
192        printf("%s read event:0x%x\n", __func__, event);
193        LOS_Msleep(1000);
194    }
195}
196```
197
198## 编译调试
199
200### 修改 BUILD.gn 文件
201
202修改 `vendor/lockzhiner/lingpi/sample` 路径下 BUILD.gn 文件,指定 `a6_kernel_event` 参与编译。
203
204```r
205"a6_kernel_event",
206```
207
208在主目录下输入编译命令。
209
210```shell
211hb build -f
212```
213
214### 运行结果
215
216示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,event_master_thread函数每隔2s写入事件,2s后清除事件;event_slave_thread函数阻塞等待事件达到,事件到达后,每1s打印一次读事件信息。
217
218```r
219event_master_thread write event:0x1
220event_slave_thread read event:0x1
221event_slave_thread read event:0x1
222event_master_thread write event:0x1
223event_slave_thread read event:0x1
224event_slave_thread read event:0x1
225```
226