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