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