README.md
1# BearPi-HM_Nano开发板OpenHarmony内核编程开发——互斥锁
2本示例将演示如何在BearPi-HM_Nano开发板上使用cmsis 2.0 接口中提供的互斥锁来实现任务同步。
3
4
5## Mutex API分析
6
7
8### osMutexNew()
9
10```c
11osMutexId_t osMutexNew(const osMutexAttr_t *attr)
12```
13**描述:**
14
15函数osMutexNew创建并初始化一个新的互斥锁对象,并返回指向互斥锁对象标识符的指针,如果出现错误则返回NULL。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
16> **注意** :不能在中断服务中调用该函数。
17
18
19**参数:**
20
21|参数名|描述|
22|:--|:------|
23| attr |互斥锁对象的属性。 |
24
25### osMutexAcquire()
26
27```c
28osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
29```
30**描述:**
31函数osMutexAcquire一直等待,直到参数mutex_id指定的互斥锁对象可用为止。如果没有其余线程获得互斥锁,该函数立即返回并阻塞互斥锁对象。
32
33> **注意** :不能在中断服务中调用该函数。
34
35
36**参数:**
37
38|参数名|描述|
39|:--|:------|
40| mutex_id | 通过osMutexNew获得的互斥锁对象ID。 |
41| timeout | 超时值。 |
42
43### osMutexRelease()
44
45```c
46osStatus_t osMutexRelease(osMutexId_t mutex_id)
47```
48**描述:**
49函数osMutexRelease释放一个由参数mutex_id指定的互斥锁对象。当前等待这个互斥锁的其余线程将被置于就绪状态。
50
51> **注意** :不能在中断服务例程中调用此函数。
52
53
54**参数:**
55
56|参数名|描述|
57|:--|:------|
58| mutex_id | 通过osMutexNew获得的互斥锁对象ID。 |
59
60
61## 软件设计
62
63**主要代码分析**
64
65在MutexExample函数中,通过osMutexNew()函数创建了互斥锁对象,并创建三个不同优先级的任务,在第一秒,高优先级和中优先级线程被延迟。因此,低优先级线程可以启动自己的工作,获得互斥锁并在持有它时延迟。在第一秒之后,高优先级和中优先级线程就准备好了。因此高优先级线程获得优先级并尝试获取互斥锁。因为互斥锁已经被低优先级线程所拥有,所以高优先级线程被阻塞,中间优先级线程被执行,并开始执行许多非阻塞的工作,低优先级线程3s后释放互斥锁,高优先级线程获得互斥锁后准备就绪并立即被调度。
66
67```c
68void HighPrioThread(void)
69{
70 // wait 1s until start actual work
71 osDelay(THREAD_DELAY_1S);
72
73 while (1) {
74 // try to acquire mutex
75 osMutexAcquire(g_mutexId, osWaitForever);
76
77 printf("HighPrioThread is running.\n");
78 osDelay(THREAD_DELAY_3S);
79 osMutexRelease(g_mutexId);
80 }
81}
82
83void MidPrioThread(void)
84{
85 // wait 1s until start actual work
86 osDelay(THREAD_DELAY_1S);
87
88 while (1) {
89 printf("MidPrioThread is running.\n");
90 osDelay(THREAD_DELAY_1S);
91 }
92}
93
94void LowPrioThread(void)
95{
96 while (1) {
97 osMutexAcquire(g_mutexId, osWaitForever);
98 printf("LowPrioThread is running.\n");
99
100 // block mutex for 3s
101 osDelay(THREAD_DELAY_3S);
102 osMutexRelease(g_mutexId);
103 }
104}
105
106/**
107 * @brief Main Entry of the Mutex Example
108 *
109 */
110void MutexExample(void)
111{
112 osThreadAttr_t attr;
113
114 attr.attr_bits = 0U;
115 attr.cb_mem = NULL;
116 attr.cb_size = 0U;
117 attr.stack_mem = NULL;
118 attr.stack_size = THREAD_STACK_SIZE;
119
120 attr.name = "HighPrioThread";
121 attr.priority = HIGH_THREAD_PRIO;
122 if (osThreadNew((osThreadFunc_t)HighPrioThread, NULL, &attr) == NULL) {
123 printf("Failed to create HighPrioThread!\n");
124 }
125
126 attr.name = "MidPrioThread";
127 attr.priority = MID_THREAD_PRIO;
128 if (osThreadNew((osThreadFunc_t)MidPrioThread, NULL, &attr) == NULL) {
129 printf("Failed to create MidPrioThread!\n");
130 }
131
132 attr.name = "LowPrioThread";
133 attr.priority = LOW_THREAD_PRIO;
134 if (osThreadNew((osThreadFunc_t)LowPrioThread, NULL, &attr) == NULL) {
135 printf("Failed to create LowPrioThread!\n");
136 }
137
138 g_mutexId = osMutexNew(NULL);
139 if (g_mutexId == NULL) {
140 printf("Failed to create Mutex!\n");
141 }
142}
143```
144
145## 编译调试
146
147### 修改 BUILD.gn 文件
148
149修改 `device\board\bearpi\bearpi_hm_nano\app`路径下 BUILD.gn 文件,指定 `mutex_example` 参与编译。
150
151```r
152#"A1_kernal_thread:thread_example",
153#"A2_kernel_timer:timer_example",
154#"A3_kernel_event:event_example",
155"A4_kernel_mutex:mutex_example",
156#"A5_kernel_semaphore:semaphore_example",
157#"A6_kernel_message:message_example",
158```
159
160
161### 运行结果
162
163示例代码编译烧录后,按下开发板的RESET按键,通过串口助手查看日志,中优先级任务一直正常运行,而高优先级和低优先级的任务因为互相抢占互斥锁,交替运行。
164```sh
165LowPrioThread is running.
166MidPrioThread is running.
167MidPrioThread is running.
168MidPrioThread is running.
169HighPrioThread is running.
170MidPrioThread is running.
171MidPrioThread is running.
172MidPrioThread is running.
173LowPrioThread is running.
174MidPrioThread is running.
175MidPrioThread is running.
176MidPrioThread is running.
177HighPrioThread is running.
178MidPrioThread is running.
179MidPrioThread is running.
180MidPrioThread is running
181```
182