README_zh.md
1# NiobeU4开发板OpenHarmony内核编程开发——mutex
2本示例将演示如何在Niobe u4开发板上使用liteos-m 接口进行互斥锁开发
3
4## mutex API分析
5
6### LOS_MuxCreate()
7
8```c
9UINT32 LOS_MuxCreate(UINT32 *muxHandle);
10```
11**描述:**
12
13创建互斥锁
14
15
16**参数:**
17
18|名字|描述|
19|:--|:------|
20| muxHandle | 互斥锁id |
21
22### LOS_MuxPend()
23
24```c
25UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout);
26```
27**描述:**
28
29获取互斥锁
30
31
32**参数:**
33
34|名字|描述|
35|:--|:------|
36| muxHandle | 互斥锁id,由LOS_MuxCreate创建得到 |
37| timeout | delay时间 |
38
39
40### LOS_MuxPost()
41
42```c
43UINT32 LOS_MuxPost(UINT32 muxHandle);
44```
45**描述:**
46
47释放互斥锁
48
49
50**参数:**
51
52|名字|描述|
53|:--|:------|
54| muxHandle | 互斥锁id,由LOS_MuxCreate创建得到 |
55
56### LOS_MuxDelete()
57
58```c
59UINT32 LOS_MuxDelete(UINT32 muxHandle);
60```
61**描述:**
62
63删除互斥锁
64
65
66**参数:**
67
68|名字|描述|
69|:--|:------|
70| muxHandle | 互斥锁id,由LOS_MuxCreate创建得到 |
71
72
73## 软件设计
74
75### 主要代码分析
76
77创建四个线程,同时访问全局变量g_str,通过互斥锁控制实现 g_str中的值按照 "firstThread" --> "firstThread+twoThread" --> "firstThread+twoThread+threeThread" --> 清空 上述步骤。
78
79```c
80UINT32 mutex1_id;
81UINT32 mutex2_id;
82
83EVENT_CB_S g_event_clean;
84#define EVENT_MASK_CLEAN 0x00000001
85
86static char g_str[256];
87
88void firstThread(void)
89{
90 //osDelay(100U);
91 while(1)
92 {
93 LOS_MuxPend(mutex1_id, osWaitForever);
94 sprintf(g_str,"firstThread");
95 printf("firstThread is Acquire. g_str=%s\r\n",g_str);
96 LOS_MuxPost(mutex1_id);
97 LOS_TaskDelay(1000U);
98 }
99}
100
101void twoThread(void)
102{
103 //osDelay(100U);
104 while(1)
105 {
106 LOS_MuxPend(mutex2_id, osWaitForever);
107 char tmp[256]={0};
108 sprintf(tmp,"%s+twoThread",g_str);
109 memcpy(g_str,tmp,sizeof(tmp));
110 printf("twoThread is Acquire. g_str=%s\r\n",g_str);
111 LOS_MuxPost(mutex2_id);
112 LOS_TaskDelay(1000U);
113 }
114}
115
116void threeThread(void)
117{
118 while(1)
119 {
120 LOS_MuxPend(mutex1_id, osWaitForever);
121 LOS_MuxPend(mutex2_id, osWaitForever);
122 char tmp[256]={0};
123 sprintf(tmp,"%s+threeThread",g_str);
124 memcpy(g_str,tmp,sizeof(tmp));
125 printf("threeThread is Acquire. g_str=%s\r\n",g_str);
126 UINT32 flags = LOS_EventWrite(&g_event_clean, EVENT_MASK_CLEAN);
127 printf("write event %x\n",flags);
128 LOS_TaskDelay(100U);
129 LOS_MuxPost(mutex1_id);
130 LOS_MuxPost(mutex2_id);
131 LOS_TaskDelay(1000U);
132 }
133}
134
135void fourThread(void)
136{
137 while(1)
138 {
139 LOS_EventRead(&g_event_clean,EVENT_MASK_CLEAN,LOS_WAITMODE_OR,osWaitForever);
140 memset(g_str,0,sizeof(g_str));
141 printf("threeThread: clean g_str.\r\n");
142 }
143}
144
145void os_mutex_example(void)
146{
147 memset(g_str,0,sizeof(g_str));
148 TSK_INIT_PARAM_S attr={0};
149 attr.uwStackSize = 1024 * 4;
150 attr.usTaskPrio = 5;
151
152 //创建互斥锁
153 mutex1_id = LOS_MuxCreate(NULL);
154 if (mutex1_id == NULL)
155 {
156 printf("create Mutex1 failed!\n");
157 return ;
158 }
159 mutex2_id = osMutexNew(NULL);
160 if (mutex2_id == NULL)
161 {
162 printf("create Mutex2 failed!\n");
163 LOS_MuxDelete(mutex1_id);
164 return ;
165 }
166
167 //创建事件标志位
168 if(LOS_EventInit(&g_event_clean) != LOS_OK)
169 {
170 printf("Failed to create EventFlags!\n");
171 LOS_MuxDelete(mutex1_id);
172 LOS_MuxDelete(mutex2_id);
173 return ;
174 }
175
176 //锁任务调度
177 LOS_TaskLock();
178 attr.pcName = "firstThread";
179 attr.pfnTaskEntry = (TSK_ENTRY_FUNC)firstThread;
180 UINT32 taskIDFirst;
181 if (osThreadNew(&taskIDFirst, &attr) != LOS_OK)
182 {
183 printf("create firstThread failed!\n");
184 LOS_MuxDelete(mutex1_id);
185 LOS_MuxDelete(mutex2_id);
186 LOS_EventDestroy(g_event_clean);
187 return ;
188 }
189
190 attr.pcName = "twoThread";
191 attr.pfnTaskEntry = (TSK_ENTRY_FUNC)twoThread;
192 UINT32 taskIDTwo;
193 if (osThreadNew(&taskIDTwo, &attr) != LOS_OK)
194 {
195 printf("create twoThread failed!\n");
196 }
197
198 attr.pcName = "threeThread";
199 attr.pfnTaskEntry = (TSK_ENTRY_FUNC)threeThread;
200 UINT32 taskIDThree;
201 if (osThreadNew(&taskIDThree, &attr) != LOS_OK)
202 {
203 printf("create threeThread failed!\n");
204 }
205
206 attr.pcName = "fourThread";
207 attr.pfnTaskEntry = (TSK_ENTRY_FUNC)fourThread;
208 UINT32 taskIDFour;
209 if (osThreadNew(&taskIDFour, &attr) != LOS_OK)
210 {
211 printf("create fourThread failed!\n");
212 }
213
214 //解锁任务调度
215 LOS_TaskUnlock();
216
217 //osThreadYield()
218}
219
220```
221
222## 编译调试
223
224- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
225 `(Top) → Platform → Board Selection → select board niobeu4 → use openvalley niobeu4 application → niobeu4 application choose`
226- 选择 `005_system_los_mutex`
227- 回到sdk根目录,执行`hb build`脚本进行编译。
228
229
230### 运行结果<a name="section_os_mutex_example"></a>
231
232示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志
233```c
234firstThread is Acquire. g_str = firstThread
235twoThread is Acquire. g_str = firstThread+twoThread
236threeThread is Acquire. g_str = firstThread+twoThread+threeThread
237write event 1
238threeThread: clean g_str.
239
240firstThread is Acquire. g_str = firstThread
241twoThread is Acquire. g_str = firstThread+twoThread
242threeThread is Acquire. g_str = firstThread+twoThread+threeThread
243write event 1
244threeThread: clean g_str.
245
246firstThread is Acquire. g_str = firstThread
247twoThread is Acquire. g_str = firstThread+twoThread
248threeThread is Acquire. g_str = firstThread+twoThread+threeThread
249write event 1
250threeThread: clean g_str.
251```
252
253
254
255