README.md
1# BearPi-HM_Nano开发板OpenHarmony内核编程开发——信号量
2本示例将演示如何在BearPi-HM_Nano开发板上使用cmsis 2.0 接口通过信号量同时从不同的线程访问共享资源。
3
4
5## Semaphore API分析
6
7### osSemaphoreNew()
8
9```c
10osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
11```
12**描述:**
13
14osSemaphoreNew 函数创建并初始化一个信号量对象,该对象用于管理对共享资源的访问,并返回指向信号量对象标识符的指针或在发生错误时返回 NULL 。可以在 RTOS 启动之前(调用 osKernelStart)安全地调用该函数,但不能在内核初始化之前(调用 osKernelInitialize)调用该函数。
15> **注意** :不能在中断服务中调用该函数。
16
17
18**参数:**
19
20|参数名|描述|
21|:--|:------|
22| max_count |可用令牌的最大数量。 |
23| initial_count |可用令牌的初始数量。 |
24| attr |信号量的属性; 空:默认值。 |
25
26### osSemaphoreRelease()
27
28```c
29osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
30```
31**描述:**
32函数osSemaphoreRelease释放由参数semaphore_id指定的信号量令牌,最多释放个数为初始设置的最大值。
33
34> **注意** :该函数可以在中断服务例程中调用。
35
36
37**参数:**
38
39|参数名|描述|
40|:--|:------|
41| semaphore_id | 由osSemaphoreNew获得的信号量ID。 |
42
43
44### osSemaphoreAcquire()
45
46```c
47osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
48```
49**描述:**
50阻塞函数osSemaphoreAcquire在超时时间结束前一直等待,直到由参数semaphore_id指定的信号量令牌可用为止。如果一个信号量令牌可用,该函数立即返回并递减可用的信号量令牌计数。
51
52> **注意** :如果参数timeout设置为0,可以在中断服务例程中调用。
53
54
55**参数:**
56
57|参数名|描述|
58|:--|:------|
59| semaphore_id | 由osSemaphoreNew获得的信号量ID。 |
60| timeout | 超时值。 |
61
62
63## 软件设计
64
65**主要代码分析**
66
67在SemaphoreExample()函数中,通过osSemaphoreNew()函数创建了g_semaphoreId信号量,并初始化信号量令牌数为4。Semaphore2Thread()和Semaphore3Thread()函数中,刚开始阻塞等待g_semaphoreId信号量中可用令牌。只有当Semaphore1Thread()函数中通过osSemaphoreRelease()函数释放两个信号量令牌后,Semaphore2Thread()和Semaphore3Thread()才能继续同步运行。若Semaphore1Thread()函数中只释放一个信号量令牌,那么Semaphore2Thread()和Semaphore3Thread()只能轮流执行。
68```c
69void Semaphore1Thread(void)
70{
71 while (1) {
72 // release Semaphores twice so that Semaphore2Thread and Semaphore3Thread can execute synchronously
73 osSemaphoreRelease(g_semaphoreId);
74
75 // if the Semaphore is released only once, Semaphore2Thread and Semaphore3Thread will run alternately.
76 osSemaphoreRelease(g_semaphoreId);
77
78 printf("Semaphore1Thread Release Semap \n");
79 osDelay(THREAD_DELAY_1S);
80 }
81}
82void Semaphore2Thread(void)
83{
84 while (1) {
85 // wait Semaphore
86 osSemaphoreAcquire(g_semaphoreId, osWaitForever);
87
88 printf("Semaphore2Thread get Semap \n");
89 osDelay(THREAD_DELAY_10MS);
90 }
91}
92
93void Semaphore3Thread(void)
94{
95 while (1) {
96 // wait Semaphore
97 osSemaphoreAcquire(g_semaphoreId, osWaitForever);
98
99 printf("Semaphore3Thread get Semap \n");
100 osDelay(THREAD_DELAY_10MS);
101 }
102}
103
104/**
105 * @brief Main Entry of the Semaphore Example
106 *
107 */
108void SemaphoreExample(void)
109{
110 osThreadAttr_t attr;
111
112 attr.attr_bits = 0U;
113 attr.cb_mem = NULL;
114 attr.cb_size = 0U;
115 attr.stack_mem = NULL;
116 attr.stack_size = THREAD_STACK_SIZE;
117 attr.priority = THREAD_PRIO;
118
119 attr.name = "Semaphore1Thread";
120 if (osThreadNew((osThreadFunc_t)Semaphore1Thread, NULL, &attr) == NULL) {
121 printf("Failed to create Semaphore1Thread!\n");
122 }
123
124 attr.name = "Semaphore2Thread";
125 if (osThreadNew((osThreadFunc_t)Semaphore2Thread, NULL, &attr) == NULL) {
126 printf("Failed to create Semaphore2Thread!\n");
127 }
128
129 attr.name = "Semaphore3Thread";
130 if (osThreadNew((osThreadFunc_t)Semaphore3Thread, NULL, &attr) == NULL) {
131 printf("Failed to create Semaphore3Thread!\n");
132 }
133
134 g_semaphoreId = osSemaphoreNew(SEM_MAX_COUNT, 0, NULL);
135 if (g_semaphoreId == NULL) {
136 printf("Failed to create Semaphore!\n");
137 }
138}
139```
140
141## 编译调试
142
143### 修改 BUILD.gn 文件
144
145修改 `device\board\bearpi\bearpi_hm_nano\app`路径下 BUILD.gn 文件,指定 `semaphore_example` 参与编译。
146
147```r
148#"A1_kernal_thread:thread_example",
149#"A2_kernel_timer:timer_example",
150#"A3_kernel_event:event_example",
151#"A4_kernel_mutex:mutex_example",
152"A5_kernel_semaphore:semaphore_example",
153#"A6_kernel_message:message_example",
154```
155
156### 运行结果
157
158示例代码编译烧录后,按下开发板的RESET按键,通过串口助手查看日志,Semaphore1Thread一次释放两个信号量令牌,Semaphore2Thread和Semaphore3Thread同步执行。
159```
160Semaphore1Thread Release Semap
161Semaphore2Thread get Semap
162Semaphore3Thread get Semap
163Semaphore1Thread Release Semap
164Semaphore2Thread get Semap
165Semaphore3Thread get Semap
166Semaphore1Thread Release Semap
167Semaphore2Thread get Semap
168Semaphore3Thread get Semap
169```
170