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和任务B同时等待同一信号量,\n\r
17 * 此时测试任务T调用aos_sem_signal()释放信号量,任务A首先获得信号量,任务A操作完成后释放一次信号量,此时任务B获取信号量得到运行。
18 * 示例说明如下:
19 * 1. t0时刻,任务T调用aos_sem_new()创建一信号量,初始计数值为0。任务T然后调用aos_task_create()创建任务A和任务B,\n\r
20 * 任务A优先级为30,任务B优先级为31。任务A和任务B运行后因等待信号量而阻塞。
21 * 2. t1时刻,任务T调用aos_sem_signal()释放信号量,任务A获得信号量。
22 * 3. t2时刻,任务A调用aos_sem_signal()释放信号量,任务B获得信号量。
23 */
24
25 /* module name used by log print */
26 #define MODULE_NAME "aos_sem_example"
27
28 /* taskA parameters */
29 #define TASKA_NAME "taskA"
30 #define TASKA_STACKSIZE 1024
31 #define TASKA_PRIO 30
32
33 /* taskB parameters */
34 #define TASKB_NAME "taskB"
35 #define TASKB_STACKSIZE 1024
36 #define TASKB_PRIO 31
37
38 /* Static memory for static creation */
39 static aos_sem_t sem_handle;
40
41 /*
42 * simulated critical section resources.
43 * The critical resource consistency condition is that all four fields are equal,
44 * otherwise the critical resource is destroyed.
45 */
46 static struct record {
47 uint32_t field1;
48 uint32_t field2;
49 uint32_t field3;
50 uint32_t field4;
51 } record_status;
52
53 /* task entry for taskA and taskB*/
task_entry(void * arg)54 static void task_entry(void *arg)
55 {
56 uint32_t i = 0;
57 aos_status_t status;
58
59 while (1) {
60 /**
61 * In order to ensure the consistency of the critical resource,
62 * the task must obtain a sem to access the critical resource.
63 */
64 status = aos_sem_wait(&sem_handle, AOS_WAIT_FOREVER);
65 if (status != 0) {
66 printf("[%s] %p sem wait error\n", MODULE_NAME, (void *)aos_task_self());
67 continue;
68 }
69
70 /**
71 * read critical resource.
72 * If the four fields are not equal, the critical resource is destroyed.
73 */
74 printf("[%s]%p field1=%ld, field2=%ld, field3=%ld, field4=%ld\n", MODULE_NAME, (void *)aos_task_self(), record_status.field1,
75 record_status.field2, record_status.field3, record_status.field4);
76
77 /* modify critical resources */
78 i = rand();
79 record_status.field1 = i;
80 record_status.field2 = i;
81 record_status.field3 = i;
82 record_status.field4 = i;
83
84 /* a semaphore is released when critical resource access is complete */
85 aos_sem_signal(&sem_handle);
86
87 aos_msleep(1000); /* sleep 1000ms */
88 }
89 }
90
aos_sem_example(int argc,char ** argv)91 static void aos_sem_example(int argc, char **argv)
92 {
93 aos_status_t status;
94 aos_task_t taskA_handle;
95 aos_task_t taskB_handle;
96
97 /**
98 * create sem. In this case, the sem is used to access the critical resource,
99 * so count is initialized to 0
100 */
101 status = aos_sem_create(&sem_handle, 0, 0);
102 if (status != 0) {
103 printf("[%s]create sem error\n", MODULE_NAME);
104 return ;
105 }
106
107 /* TaskA and taskB both acess critical resources. */
108 status = aos_task_create(&taskA_handle, TASKA_NAME, task_entry, NULL, NULL, TASKA_STACKSIZE, TASKA_PRIO, AOS_TASK_AUTORUN);
109 if (status != 0) {
110 aos_sem_free(&sem_handle);
111 printf("[%s]create %s error\n", MODULE_NAME, TASKA_NAME);
112 return ;
113 }
114
115 status = aos_task_create(&taskB_handle, TASKB_NAME, task_entry, NULL, NULL, TASKB_STACKSIZE, TASKB_PRIO, AOS_TASK_AUTORUN);
116 if (status != 0) {
117 aos_sem_free(&sem_handle);
118 printf("[%s]create %s error\n", MODULE_NAME, TASKB_NAME);
119 return ;
120 }
121
122 aos_msleep(100);
123
124 /* a semaphore is released when critical resource access is complete */
125 aos_sem_signal(&sem_handle);
126
127 aos_msleep(100);
128
129 }
130
131
132 #if AOS_COMP_CLI
133 /* reg args: fun, cmd, description*/
134 ALIOS_CLI_CMD_REGISTER(aos_sem_example, sem_example, aos sem example)
135 #endif
136