1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <stdlib.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使用互斥量同时访问共享数据区,访问共享数据区时使用互斥量做保护。
17  * 示例说明如下:
18  * 1. t0时刻,任务T调用aos_mutex_create()创建一互斥量。任务T然后调用aos_task_create()创建任务A和任务B。任务A得到运行,并获取互斥量对数据区record_status进行读写操作。
19  * 2. t1时刻,任务A因时间片耗尽,让出CPU,任务B得到运行。
20  * 3. t2时刻,任务B因无法获得互斥量,进入阻塞状态,任务A得到运行。
21  * 4. t3时刻,任务A对数据区record_status的操作完成,释放互斥量,任务B获得互斥量开始对数据区record_status进行读写操作。
22  */
23 
24 /* module name used by log print*/
25 #define MODULE_NAME "aos_mutex_example"
26 
27 /* taskA parameters */
28 #define TASKA_NAME      "taskA"
29 #define TASKA_PRI       50
30 #define TASKA_STACKSIZE 1024
31 
32 /* taskB parameters */
33 #define TASKB_NAME      "taskB"
34 #define TASKB_PRI       50
35 #define TASKB_STACKSIZE 1024
36 
37 /* mutex handle */
38 static aos_mutex_t mutex_handle;
39 
40 /*
41  * simulated critical section resources.
42  * The critical resource consistency condition is that all four fields are equal,
43  * otherwise the critical resource is destroyed.
44  */
45 static struct record {
46     uint32_t field1;
47     uint32_t field2;
48     uint32_t field3;
49     uint32_t field4;
50 } record_status;
51 
52 /* task entry */
task_entry(void * arg)53 static void task_entry(void *arg)
54 {
55     uint32_t     i = 0;
56     aos_status_t status;
57 
58     while (1) {
59         /**
60          * In order to ensure the consistency of the critical resource,
61          * the task must obtain a mutex to access the critical resource.
62          */
63         status = aos_mutex_lock(&mutex_handle, AOS_WAIT_FOREVER);
64         if (status != 0) {
65             printf("[%s] %p mutex lock error\n", MODULE_NAME, (void *)aos_task_self());
66             continue;
67         }
68 
69         /**
70          * read critical resource.
71          * If the four fields are not equal, the critical resource is destroyed.
72          */
73         printf("[%s] %p field1=%ld, field2=%ld, field3=%ld, field4=%ld\n", MODULE_NAME, (void *)aos_task_self(), record_status.field1,
74              record_status.field2, record_status.field3, record_status.field4);
75 
76         /* modify critical resources */
77         i = rand();
78         record_status.field1 = i;
79         record_status.field2 = i;
80         record_status.field3 = i;
81         record_status.field4 = i;
82 
83         status = aos_mutex_unlock(&mutex_handle);
84         if (status != 0) {
85             printf("[%s]%p mutex unlock error\n", MODULE_NAME, (void *)aos_task_self());
86             return;
87         }
88 
89         aos_msleep(1000); /* sleep 1000ms */
90     }
91 }
92 
aos_mutex_example(int argc,char ** argv)93 static void aos_mutex_example(int argc, char **argv)
94 {
95     aos_status_t status;
96 
97     /* create mutex statically */
98     status = aos_mutex_create(&mutex_handle, 0);
99     if (status != 0) {
100         printf("[%s]create mutex error\n", MODULE_NAME);
101         return;
102     }
103 
104     /* Task1 and task2 both acess critical resources. */
105     status = aos_task_new(TASKA_NAME, task_entry, NULL, TASKA_STACKSIZE);
106     if (status != 0) {
107         aos_mutex_free(&mutex_handle);
108         printf("[%s]create %s error\n", MODULE_NAME, TASKA_NAME);
109         return;
110     }
111 
112     status = aos_task_new(TASKB_NAME, task_entry, NULL, TASKB_STACKSIZE);
113     if (status != 0) {
114         aos_mutex_free(&mutex_handle);
115         printf("[%s]create %s error\n", MODULE_NAME, TASKB_NAME);
116         return;
117     }
118 }
119 
120 #if AOS_COMP_CLI
121 /* reg args: fun, cmd, description*/
122 ALIOS_CLI_CMD_REGISTER(aos_mutex_example, mutex_example, aos mutex example)
123 #endif
124