1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
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 * limitations under the License.
14 * Description: 线程适配层接口cmsis2实现源文件(此文件为DEMO,需集成方适配修改)
15 */
16
17 #include "hilink_thread_adapter.h"
18 #include <stddef.h>
19 #include <stdint.h>
20 #include <stdarg.h>
21 #include "cmsis_os2.h"
22 #include "securec.h"
23 #include "hilink_sal_defines.h"
24
25 #ifdef SUPPORT_MUTEX_DEBUG
26 #undef HILINK_MutexLock
27 #undef HILINK_MutexUnlock
28 #undef HILINK_MutexCreate
29 #undef HILINK_MutexDestroy
30 #endif
31
32 #ifndef MS_PER_SECOND
33 #define MS_PER_SECOND 1000
34 #endif
35
HILINK_CreateTask(HiLinkTaskParam * param)36 HiLinkTaskId HILINK_CreateTask(HiLinkTaskParam *param)
37 {
38 if ((param == NULL) || (param->func == NULL) || (param->prio > HILINK_TASK_PRIORITY_MAX) ||
39 (param->stackSize == 0)) {
40 HILINK_SAL_WARN("invalid param");
41 return NULL;
42 }
43
44 const osPriority_t prioMap[] = {
45 osPriorityLow1,
46 osPriorityBelowNormal1,
47 osPriorityNormal2,
48 osPriorityNormal7,
49 osPriorityHigh
50 };
51
52 osThreadAttr_t attr;
53 (void)memset_s(&attr, sizeof(osThreadAttr_t), 0, sizeof(osThreadAttr_t));
54 attr.name = param->name;
55 attr.priority = prioMap[param->prio];
56 attr.stack_size = param->stackSize;
57
58 return (HiLinkTaskId)osThreadNew((osThreadFunc_t)param->func, param->arg, &attr);
59 }
60
HILINK_ThreadSuspend(HiLinkTaskId handle)61 int HILINK_ThreadSuspend(HiLinkTaskId handle)
62 {
63 if (handle == NULL) {
64 HILINK_SAL_WARN("invalid param\r\n");
65 return HILINK_SAL_PARAM_INVALID;
66 }
67
68 osStatus_t status = osThreadSuspend((osThreadId_t)handle);
69 if (status != osOK) {
70 HILINK_SAL_WARN("suspend error %d\r\n", status);
71 return HILINK_SAL_THREAD_ERR;
72 }
73 return HILINK_SAL_OK;
74 }
75
HILINK_ThreadResume(HiLinkTaskId handle)76 int HILINK_ThreadResume(HiLinkTaskId handle)
77 {
78 if (handle == NULL) {
79 HILINK_SAL_WARN("invalid param\r\n");
80 return HILINK_SAL_PARAM_INVALID;
81 }
82
83 osStatus_t status = osThreadResume((osThreadId_t)handle);
84 if (status != osOK) {
85 HILINK_SAL_WARN("resume error %d\r\n", status);
86 return HILINK_SAL_THREAD_ERR;
87 }
88 return HILINK_SAL_OK;
89 }
90
HILINK_DeleteTask(HiLinkTaskId handle)91 void HILINK_DeleteTask(HiLinkTaskId handle)
92 {
93 if (handle == NULL) {
94 HILINK_SAL_NOTICE("invalid param\r\n");
95 return;
96 }
97
98 osStatus_t status = osThreadTerminate((osThreadId_t)handle);
99 if (status != osOK) {
100 HILINK_SAL_NOTICE("delete task error %d\r\n", status);
101 }
102 }
103
HILINK_GetCurrentTaskId(void)104 HiLinkTaskId HILINK_GetCurrentTaskId(void)
105 {
106 return (HiLinkTaskId)osThreadGetId();
107 }
108
HILINK_MutexCreate(void)109 HiLinkMutexId HILINK_MutexCreate(void)
110 {
111 return (HiLinkMutexId)osMutexNew(NULL);
112 }
113
MsToTick(unsigned int ms)114 static inline unsigned int MsToTick(unsigned int ms)
115 {
116 uint64_t tick = ms * osKernelGetTickFreq() / MS_PER_SECOND;
117 if (tick > UINT32_MAX) {
118 return UINT32_MAX;
119 }
120 return (unsigned int)tick;
121 }
122
HILINK_MutexLock(HiLinkMutexId mutex,unsigned int ms)123 int HILINK_MutexLock(HiLinkMutexId mutex, unsigned int ms)
124 {
125 if (mutex == NULL) {
126 HILINK_SAL_WARN("invalid param\r\n");
127 return HILINK_SAL_PARAM_INVALID;
128 }
129
130 osStatus_t status = osMutexAcquire((osMutexId_t)mutex, MsToTick(ms));
131 if (status != osOK) {
132 if (status == osErrorTimeout) {
133 return HILINK_SAL_TIMEOUT;
134 }
135 HILINK_SAL_WARN("mutex lock error %d\r\n", status);
136 return HILINK_SAL_MUTEX_ERR;
137 }
138
139 return HILINK_SAL_OK;
140 }
141
HILINK_MutexUnlock(HiLinkMutexId mutex)142 int HILINK_MutexUnlock(HiLinkMutexId mutex)
143 {
144 if (mutex == NULL) {
145 HILINK_SAL_WARN("invalid param\r\n");
146 return HILINK_SAL_PARAM_INVALID;
147 }
148
149 osStatus_t status = osMutexRelease((osMutexId_t)mutex);
150 if (status != osOK) {
151 HILINK_SAL_WARN("mutex unlock error %d\r\n", status);
152 return HILINK_SAL_MUTEX_ERR;
153 }
154 return HILINK_SAL_OK;
155 }
156
HILINK_MutexDestroy(HiLinkMutexId mutex)157 void HILINK_MutexDestroy(HiLinkMutexId mutex)
158 {
159 if (mutex == NULL) {
160 HILINK_SAL_NOTICE("invalid param\r\n");
161 return;
162 }
163
164 osStatus_t status = osMutexDelete((osMutexId_t)mutex);
165 if (status != osOK) {
166 HILINK_SAL_NOTICE("mutex delete error %d\r\n", status);
167 }
168 }
169
HILINK_SemCreate(unsigned int count)170 HiLinkSemId HILINK_SemCreate(unsigned int count)
171 {
172 /* count为0是默认为二元信号量 */
173 return (HiLinkSemId)osSemaphoreNew(count > 0 ? count : 1, count, NULL);
174 }
175
HILINK_SemWait(HiLinkSemId handle,unsigned int ms)176 int HILINK_SemWait(HiLinkSemId handle, unsigned int ms)
177 {
178 if (handle == NULL) {
179 HILINK_SAL_WARN("invalid param\r\n");
180 return HILINK_SAL_PARAM_INVALID;
181 }
182
183 osStatus_t status = osSemaphoreAcquire((osSemaphoreId_t)handle, MsToTick(ms));
184 if (status != osOK) {
185 return HILINK_SAL_SEM_ERR;
186 }
187
188 return HILINK_SAL_OK;
189 }
190
HILINK_SemPost(HiLinkSemId handle)191 int HILINK_SemPost(HiLinkSemId handle)
192 {
193 if (handle == NULL) {
194 HILINK_SAL_WARN("invalid param\r\n");
195 return HILINK_SAL_PARAM_INVALID;
196 }
197
198 osStatus_t status = osSemaphoreRelease((osSemaphoreId_t)handle);
199 if (status != osOK) {
200 HILINK_SAL_WARN("post sem error %d\r\n", status);
201 return HILINK_SAL_SEM_ERR;
202 }
203
204 return HILINK_SAL_OK;
205 }
206
HILINK_SemDestroy(HiLinkSemId handle)207 void HILINK_SemDestroy(HiLinkSemId handle)
208 {
209 if (handle == NULL) {
210 HILINK_SAL_NOTICE("invalid param\r\n");
211 return;
212 }
213
214 osStatus_t status = osSemaphoreDelete((osSemaphoreId_t)handle);
215 if (status != osOK) {
216 HILINK_SAL_NOTICE("sem delete error %d\r\n", status);
217 }
218 }
219
HILINK_MilliSleep(unsigned int ms)220 int HILINK_MilliSleep(unsigned int ms)
221 {
222 osStatus_t status = osDelay(MsToTick(ms));
223 if (status != osOK) {
224 HILINK_SAL_WARN("delay %u ms error %d\r\n", ms, status);
225 return -1;
226 }
227 return HILINK_SAL_SLEEP_ERR;
228 }
229
HILINK_SchedYield(void)230 void HILINK_SchedYield(void)
231 {
232 (void)osDelay(0);
233 }