• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification,
5  * are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  *    conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *    of conditions and the following disclaimer in the documentation and/or other materials
12  *    provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15  *    to endorse or promote products derived from this software without specific prior written
16  *    permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "cmsis_os2.h"
32 #include "prt_config.h"
33 #include "prt_event.h"
34 #include "prt_mem.h"
35 #include "prt_hwi.h"
36 #include "prt_queue.h"
37 #include "prt_sem.h"
38 #include "prt_tick.h"
39 #include "prt_task.h"
40 #include "prt_timer.h"
41 #include "prt_task_external.h"
42 #include "prt_queue_external.h"
43 #include "prt_sem_external.h"
44 
45 #include "string.h"
46 #include "securec.h"
47 
48 #define OS_BASE_CORE_TSK_DEFAULT_PRIO OS_TSK_PRIORITY_10
49 /* OS_BASE_CORE_TSK_DEFAULT_PRIO <---> osPriorityNormal */
50 #define OS_PRIORITY(cmsisPriority) (OS_BASE_CORE_TSK_DEFAULT_PRIO - ((cmsisPriority) - osPriorityNormal))
51 #define CMSIS_PRIORITY(losPriority) (osPriorityNormal + (OS_BASE_CORE_TSK_DEFAULT_PRIO - (losPriority)))
52 
53 #define ISVALID_OS_PRIORITY(losPrio) ((losPrio) > OS_TSK_PRIORITY_00 && (losPrio) < OS_TSK_PRIORITY_31)
54 
55 #define KERNEL_UNLOCKED 0
56 #define KERNEL_LOCKED   1
57 
osKernelLock(void)58 int32_t osKernelLock(void)
59 {
60     int32_t lock;
61 
62     if (OS_INT_ACTIVE) {
63         return (int32_t)osErrorISR;
64     }
65 
66     if (OS_TASK_LOCK_DATA > 0) {
67         lock = KERNEL_LOCKED;
68     } else {
69         PRT_TaskLock();
70         lock = KERNEL_UNLOCKED;
71     }
72 
73     return lock;
74 }
75 
osKernelUnlock(void)76 int32_t osKernelUnlock(void)
77 {
78     int32_t lock;
79 
80     if (OS_INT_ACTIVE) {
81         return (int32_t)osErrorISR;
82     }
83 
84     if (OS_TASK_LOCK_DATA > 0) {
85         PRT_TaskUnlock();
86         if (OS_TASK_LOCK_DATA != 0) {
87             return (int32_t)osError;
88         }
89         lock = KERNEL_LOCKED;
90     } else {
91         lock = KERNEL_UNLOCKED;
92     }
93 
94     return lock;
95 }
96 
osThreadGetId(void)97 osThreadId_t osThreadGetId(void)
98 {
99     TskHandle taskId = 0;
100     (void)PRT_TaskSelf(&taskId);
101     return (osThreadId_t)GET_TCB_HANDLE(taskId);
102 }
103 
osThreadGetArgument(void)104 void *osThreadGetArgument(void)
105 {
106     struct TskInfo taskInfo = {0};
107 
108     if (OS_INT_ACTIVE) {
109         return 0;
110     }
111 
112     struct TagTskCb *taskCb = (struct TagTskCb *)osThreadGetId();
113     if (taskCb == NULL) {
114         return NULL;
115     }
116     return (void *)(taskCb->args[0]);
117 }
118 
osKernelGetTickCount(void)119 uint32_t osKernelGetTickCount(void)
120 {
121     uint64_t ticks = PRT_TickGetCount();
122     return (uint32_t)ticks;
123 }
124 
osKernelGetTickFreq(void)125 uint32_t osKernelGetTickFreq(void)
126 {
127     return (uint32_t)OS_TICK_PER_SECOND;
128 }
129 
130 //  ==== Thread Management Functions ====
osThreadNew(osThreadFunc_t func,void * argument,const osThreadAttr_t * attr)131 osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
132 {
133     U32 tid;
134     U32 ret;
135     osThreadAttr_t attrTemp = {0};
136     struct TskInitParam stTskInitParam = {0};
137     U16 priority;
138 
139     if (OS_INT_ACTIVE || (func == NULL)) {
140         return (osThreadId_t)NULL;
141     }
142 
143     if (attr == NULL) {
144         attrTemp.priority = osPriorityNormal,
145         attr = &attrTemp;
146     }
147 
148     priority = OS_PRIORITY(attr->priority);
149     if (!ISVALID_OS_PRIORITY(priority)) {
150         /* unsupported priority */
151         return (osThreadId_t)NULL;
152     }
153     stTskInitParam.taskEntry = (TskEntryFunc)func;
154     stTskInitParam.args[0] = (U32)argument;
155     if ((attr->stack_mem != NULL) && (attr->stack_size != 0)) {
156         stTskInitParam.stackAddr = (uintptr_t)attr->stack_mem;
157         stTskInitParam.stackSize = attr->stack_size;
158     } else if (attr->stack_size != 0) {
159         stTskInitParam.stackSize = attr->stack_size;
160     } else {
161         stTskInitParam.stackSize = OS_TSK_DEFAULT_STACK_SIZE;
162     }
163     if (attr->name != NULL) {
164         stTskInitParam.name = (char *)attr->name;
165     } else {
166         stTskInitParam.name = "CmsisTask";
167     }
168     stTskInitParam.taskPrio = priority;
169     ret = PRT_TaskCreate(&tid, &stTskInitParam);
170     if (ret != OS_OK) {
171         return (osThreadId_t)NULL;
172     }
173 
174     ret = PRT_TaskResume(tid);
175     if (ret != OS_OK) {
176         (void)PRT_TaskDelete(tid);
177         return (osThreadId_t)NULL;
178     }
179 
180     return (osThreadId_t)GET_TCB_HANDLE(tid);
181 }
182 
osThreadGetCount(void)183 uint32_t osThreadGetCount(void)
184 {
185     uint32_t count = 0;
186 
187     if (OS_INT_ACTIVE) {
188         return 0U;
189     }
190 
191     for (TskHandle index = 0; index <= OS_TSK_MAX_SUPPORT_NUM; index++) {
192         TskStatus status = PRT_TaskGetStatus(index);
193         if ((status != (TskStatus)OS_INVALID) && (status & OS_TSK_INUSE)) {
194             count++;
195         }
196     }
197 
198     return count;
199 }
200 
osThreadExit(void)201 void osThreadExit(void)
202 {
203     TskHandle taskId = 0;
204     (void)PRT_TaskSelf(&taskId);
205     (void)PRT_TaskDelete(taskId);
206     //UNREACHABLE;
207 }
208 
osMutexNew(const osMutexAttr_t * attr)209 osMutexId_t osMutexNew(const osMutexAttr_t *attr)
210 {
211     U32 ret;
212     SemHandle muxId;
213 
214     (void)attr;
215 
216     ret = PRT_SemCreate(1, &muxId);
217     if (ret == OS_OK) {
218         return (osMutexId_t)GET_SEM(muxId);
219     } else {
220         return (osMutexId_t)NULL;
221     }
222 }
223 
osMutexAcquire(osMutexId_t mutex_id,uint32_t timeout)224 osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
225 {
226     struct TagSemCb *semCb = (struct TagSemCb *)mutex_id;
227     if (semCb == NULL) {
228         return osErrorParameter;
229     }
230 
231     U32 ret = PRT_SemPend(semCb->semId, timeout);
232     if (ret == OS_OK) {
233         return osOK;
234     } else if (ret == OS_ERRNO_SEM_INVALID) {
235         return osErrorParameter;
236     } else if (ret == OS_ERRNO_SEM_TIMEOUT) {
237         return osErrorTimeout;
238     } else {
239         return osErrorResource;
240     }
241 }
242 
osMutexRelease(osMutexId_t mutex_id)243 osStatus_t osMutexRelease(osMutexId_t mutex_id)
244 {
245     struct TagSemCb *semCb = (struct TagSemCb *)mutex_id;
246     if (semCb == NULL) {
247         return osErrorParameter;
248     }
249 
250     U32 ret = PRT_SemPost(semCb->semId);
251     if (ret == OS_OK) {
252         return osOK;
253     } else if (ret == OS_ERRNO_SEM_INVALID) {
254         return osErrorParameter;
255     } else {
256         return osErrorResource;
257     }
258 }
259 
260 typedef enum {
261     ATTR_CAPACITY = 0,
262     ATTR_MSGSIZE = 1,
263     ATTR_COUNT = 2,
264     ATTR_SPACE = 3
265 } QueueAttribute;
266 
osMessageQueueNew(uint32_t msg_count,uint32_t msg_size,const osMessageQueueAttr_t * attr)267 osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
268 {
269     U32 queueId;
270     U32 ret;
271     osMessageQueueId_t handle;
272 
273     if ((msg_count == 0) || (msg_size == 0) || OS_INT_ACTIVE) {
274         return (osMessageQueueId_t)NULL;
275     }
276 
277     ret = PRT_QueueCreate((U16)msg_count, (U16)msg_size, &queueId);
278     if (ret == OS_OK) {
279         handle = (osMessageQueueId_t)queueId;
280     } else {
281         handle = (osMessageQueueId_t)NULL;
282     }
283 
284     return handle;
285 }
286 
osMessageQueueOp(osMessageQueueId_t mq_id,void * msg_ptr,U32 timeout,int rw)287 static osStatus_t osMessageQueueOp(osMessageQueueId_t mq_id, void *msg_ptr, U32 timeout, int rw)
288 {
289     struct TagQueCb *queueCb = (struct TagQueCb *)GET_QUEUE_HANDLE(OS_QUEUE_INNER_ID((U32)mq_id));
290     U32 ret;
291     U32 bufferSize;
292 
293     if ((queueCb == NULL) || (msg_ptr == NULL) || (OS_INT_ACTIVE && (timeout != 0))) {
294         return osErrorParameter;
295     }
296 
297     bufferSize = (U32)(queueCb->nodeSize - OS_QUEUE_NODE_HEAD_LEN);
298     if (rw == 0) {
299         ret = PRT_QueueWrite(mq_id, msg_ptr, bufferSize, timeout, OS_QUEUE_NORMAL);
300     } else {
301         ret = PRT_QueueRead(mq_id, msg_ptr, &bufferSize, timeout);
302     }
303 
304     if (ret == OS_OK) {
305         return osOK;
306     } else if ((ret == OS_ERRNO_QUEUE_INVALID) || (ret == OS_ERRNO_QUEUE_PTR_NULL) ||
307                (OS_ERRNO_QUEUE_SIZE_ZERO) || (OS_ERRNO_QUEUE_PRIO_INVALID) || (OS_ERRNO_QUEUE_NOT_CREATE)) {
308         return osErrorParameter;
309     } else if (ret == OS_ERRNO_QUEUE_TIMEOUT) {
310         return osErrorTimeout;
311     } else {
312         return osErrorResource;
313     }
314 }
315 
osMessageQueuePut(osMessageQueueId_t mq_id,const void * msg_ptr,uint8_t msg_prio,uint32_t timeout)316 osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)
317 {
318     (void)msg_prio;
319     return osMessageQueueOp(mq_id, (void *)msg_ptr, (U32)timeout, 0);
320 }
321 
osMessageQueueGet(osMessageQueueId_t mq_id,void * msg_ptr,uint8_t * msg_prio,uint32_t timeout)322 osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
323 {
324     (void)msg_prio;
325     return osMessageQueueOp(mq_id, (void *)msg_ptr, (U32)timeout, 1);
326 }
327 
osMessageQueueDelete(osMessageQueueId_t mq_id)328 osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
329 {
330     U32 ret;
331     if (OS_INT_ACTIVE) {
332         return osErrorISR;
333     }
334 
335     ret = PRT_QueueDelete((U32)mq_id);
336     if (ret == OS_OK) {
337         return osOK;
338     } else if (ret == OS_ERRNO_QUEUE_INVALID || ret == OS_ERRNO_QUEUE_NOT_CREATE) {
339         return osErrorParameter;
340     } else {
341         return osErrorResource;
342     }
343 }
344 
sleep(unsigned time)345 unsigned sleep(unsigned time)
346 {
347     U32 ticks = time * OS_TICK_PER_SECOND;
348     PRT_TaskDelay(ticks);
349 }
350