1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8
9 #include <aos/kernel.h>
10
11 #if AOS_COMP_CLI
12 #include "aos/cli.h"
13 #endif
14
15 /**
16 * 该示例使用事件机制实现任务间同步,具体场景为创建任务A和认为B,以及一事件。任务A以“与”的方式等待事件1和事件2;任务B以“或”的方式等待事件1和事件2。测试任务T设置事件1,则任务B因获取事件得到运行,之后测试任务T设置事件2,则任务A因等到全部事件而得到运行。
17 * 示例说明如下:
18 * 1. t0时刻,任务T调用aos_event_new()创建一事件。任务T然后调用aos_task_create()创建任务A和任务B。任务A调用aos_event_get()以RHINO_AND为选项参数等待事件1和事件2的发生;任务B调用aos_event_get()以RHINO_OR为选项参数等待事件1或事件2的发生。
19 * 2. t1时刻,任务T调用aos_event_get()设置事件1,任务B因等到事件1得到运行。
20 * 3. t2时刻,任务T调用aos_event_get()设置事件2,任务A因等到了所有事件1和2而得到运行。
21 */
22
23 /* module name used by log print */
24 #define MODULE_NAME "aos_event_example"
25
26 /* taskA parameters */
27 #define TASKA_NAME "taskA"
28 #define TASKA_STACKSIZE 1024
29 #define TASKA_PRIO 30
30
31 /* taskB parameters */
32 #define TASKB_NAME "taskB"
33 #define TASKB_STACKSIZE 1024
34 #define TASKB_PRIO 31
35
36 #define USER_EVENT_1 (1 << 0) /**< user event 1*/
37 #define USER_EVENT_2 (1 << 1) /**< user event 2 */
38
39 /* Static memory for static creation */
40 static aos_event_t event_handle;
41
42 /*
43 * simulated critical section resources.
44 * The critical resource consistency condition is that all four fields are equal,
45 * otherwise the critical resource is destroyed.
46 */
47 static struct record {
48 uint32_t field1;
49 uint32_t field2;
50 uint32_t field3;
51 uint32_t field4;
52 } record_status;
53
54 /* task entry */
taskA_entry(void * arg)55 static void taskA_entry(void *arg)
56 {
57 uint32_t i = 0;
58 aos_status_t status;
59 uint32_t actl_flags;
60
61 /**
62 * In order to ensure the consistency of the critical resource,
63 * the task must obtain a sem to access the critical resource.
64 */
65
66 status = aos_event_get(&event_handle, USER_EVENT_1 | USER_EVENT_2, AOS_EVENT_OR, &actl_flags, AOS_WAIT_FOREVER);
67
68 if (status != 0) {
69 printf("[%s] %p sem wait error\n", MODULE_NAME, (void *)aos_task_self());
70 return;
71 }
72
73 /**
74 * read critical resource.
75 * If the four fields are not equal, the critical resource is destroyed.
76 */
77 printf("[%s][%s]field1=%ld, field2=%ld, field3=%ld, field4=%ld\n", MODULE_NAME, TASKA_NAME, record_status.field1,
78 record_status.field2, record_status.field3, record_status.field4);
79
80 /* modify critical resources */
81 i = rand();
82 record_status.field1 = i;
83 record_status.field2 = i;
84 record_status.field3 = i;
85 record_status.field4 = i;
86
87 aos_msleep(1000); /* sleep 1000ms */
88 }
89
90 /* task entry */
taskB_entry(void * arg)91 static void taskB_entry(void *arg)
92 {
93 uint32_t i = 0;
94 aos_status_t status;
95 uint32_t actl_flags;
96
97 /**
98 * In order to ensure the consistency of the critical resource,
99 * the task must obtain a sem to access the critical resource.
100 */
101 status = aos_event_get(&event_handle, USER_EVENT_1 | USER_EVENT_2, AOS_EVENT_AND, &actl_flags, AOS_WAIT_FOREVER);
102 if (status != 0) {
103 printf("[%s]%p sem wait error\n", MODULE_NAME, (void *)aos_task_self());
104 return;
105 }
106
107 /**
108 * read critical resource.
109 * If the four fields are not equal, the critical resource is destroyed.
110 */
111 printf("[%s][%s]field1=%ld, field2=%ld, field3=%ld, field4=%ld\n", MODULE_NAME, TASKB_NAME, record_status.field1,
112 record_status.field2, record_status.field3, record_status.field4);
113
114 /* modify critical resources */
115 i = rand();
116 record_status.field1 = i;
117 record_status.field2 = i;
118 record_status.field3 = i;
119 record_status.field4 = i;
120
121 aos_msleep(1000); /* sleep 1000ms */
122 }
123
aos_event_example(int argc,char ** argv)124 static void aos_event_example(int argc, char **argv)
125 {
126 aos_status_t status;
127 aos_task_t taskA_handle;
128 aos_task_t taskB_handle;
129
130 /**
131 * create event. In this case, the event is used to access the critical resource,
132 * so flag is initialized to 0
133 */
134 status = aos_event_create(&event_handle, 0, 0);
135 if (status != 0) {
136 printf("[%s]create sem error\n", MODULE_NAME);
137 return;
138 }
139
140 /* TaskA and taskB both acess critical resources. */
141 status = aos_task_create(&taskA_handle, TASKA_NAME, taskA_entry, NULL, NULL, TASKA_STACKSIZE, TASKA_PRIO, AOS_TASK_AUTORUN);
142 if (status != 0) {
143 aos_event_free(&event_handle);
144 printf("[%s]create %s error\n", MODULE_NAME, TASKA_NAME);
145 return;
146 }
147
148 status = aos_task_create(&taskB_handle, TASKB_NAME, taskB_entry, NULL, NULL, TASKB_STACKSIZE, TASKB_PRIO, AOS_TASK_AUTORUN);
149 if (status != 0) {
150 aos_event_free(&event_handle);
151 printf("[%s]create %s error\n", MODULE_NAME, TASKB_NAME);
152 return;
153 }
154
155 aos_msleep(100);
156
157 printf("[%s]set event 1!\n", MODULE_NAME);
158 /* a semaphore is released when critical resource access is complete */
159 aos_event_set(&event_handle, USER_EVENT_1, AOS_EVENT_OR);
160
161 aos_msleep(100);
162
163 printf("[%s]set event 2!\n", MODULE_NAME);
164 aos_event_set(&event_handle, USER_EVENT_2, AOS_EVENT_OR);
165
166 aos_msleep(100);
167
168 return;
169 }
170
171 #if AOS_COMP_CLI
172 /* reg args: fun, cmd, description*/
173 ALIOS_CLI_CMD_REGISTER(aos_event_example, event_example, aos event example)
174 #endif