1 /*
2 * Copyright (C) 2022 HiHope Open Source Organization .
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http:// www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 *
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <unistd.h>
19
20 #include "ohos_init.h"
21 #include "cmsis_os2.h"
22
23 #define ATTR.STACK_SIZE 1024
24 #define OS_DELAY 5
25 #define OS_DELAY_F 13
26 #define OS_DELAY_S 17
27 #define NUM 100
28 #define NUMS 2
29
30 static int g_test_value = 0;
31
32 /*
33 * 全局变量g_test_value若同时被多个线程访问,会将其加1,然后判断其奇偶性,
34 * 并输出日志,如果没有互斥锁保护,线程会被中断导致错误,所以需要创建互斥锁来保护多线程共享区域
35 */
36
number_thread(int * arg)37 void number_thread(int *arg)
38 {
39 osMutexId_t *mid = (osMutexId_t *)arg;
40 while (1) {
41 // 加锁(获取互斥锁/占用互斥锁)
42 if (osMutexAcquire(*mid, NUM) == osOK) {
43 g_test_value++;
44 if (g_test_value % NUMS == 0) {
45 printf("[Mutex Test]%s gets an even value %d.\r\n", osThreadGetName(osThreadGetId()), g_test_value);
46 } else {
47 printf("[Mutex Test]%s gets an odd value %d.\r\n", osThreadGetName(osThreadGetId()), g_test_value);
48 }
49 osMutexRelease(*mid);
50 osDelay(OS_DELAY);
51 }
52 }
53 }
54
newThread(char * name,osThreadFunc_t func,int * arg)55 osThreadId_t newThread(char *name, osThreadFunc_t func, int *arg)
56 {
57 osThreadAttr_t attr = {
58 name, 0, NULL, 0, NULL, 1024*2, osPriorityNormal, 0, 0
59 };
60 osThreadId_t tid = osThreadNew(func, arg, &attr);
61 if (tid == NULL) {
62 printf("[Mutex Test]osThreadNew(%s) failed.\r\n", name);
63 } else {
64 printf("[Mutex Test]osThreadNew(%s) success, thread id: %d.\r\n", name, tid);
65 }
66 return tid;
67 }
68
69 /*
70 * 创建三个线程访问全局变量g_test_value ,同时创建一个互斥锁共所有线程使用
71 */
72
rtosv2_mutex_main(int * arg)73 void rtosv2_mutex_main(int *arg)
74 {
75 (int)arg;
76 osMutexAttr_t attr = {0};
77
78 osMutexId_t mid = osMutexNew(&attr); // 创建互斥锁
79 if (mid == NULL) {
80 printf("[Mutex Test]osMutexNew, create mutex failed.\r\n");
81 } else {
82 printf("[Mutex Test]osMutexNew, create mutex success.\r\n");
83 }
84
85 // 创建三个线程
86 osThreadId_t tid1 = newThread("Thread_1", number_thread, &mid);
87 osThreadId_t tid2 = newThread("Thread_2", number_thread, &mid);
88 osThreadId_t tid3 = newThread("Thread_3", number_thread, &mid);
89 // 注释Mutex
90 osDelay(OS_DELAY_F);
91 osThreadId_t tid = osMutexGetOwner(mid);
92 printf("[Mutex Test]osMutexGetOwner, thread id: %p, thread name: %s.\r\n", tid, osThreadGetName(tid));
93 osDelay(OS_DELAY_S);
94
95 osThreadTerminate(tid1);
96 osThreadTerminate(tid2);
97 osThreadTerminate(tid3);
98 osMutexDelete(mid); // 删除互斥锁
99 }
100
MutexTestTask(void)101 static void MutexTestTask(void)
102 {
103 osThreadAttr_t attr;
104
105 attr.name = "rtosv2_mutex_main";
106 attr.attr_bits = 0U;
107 attr.cb_mem = NULL;
108 attr.cb_size = 0U;
109 attr.stack_mem = NULL;
110 attr.stack_size = ATTR.STACK_SIZE;
111 attr.priority = osPriorityNormal;
112
113 if (osThreadNew((osThreadFunc_t)rtosv2_mutex_main, NULL, &attr) == NULL) {
114 printf("[MutexTestTask] Failed to create rtosv2_mutex_main!\n");
115 }
116 }
117
118 APP_FEATURE_INIT(MutexTestTask);