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