1/*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 *    conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 *    of conditions and the following disclaimer in the documentation and/or other materials
13 *    provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 *    to endorse or promote products derived from this software without specific prior written
17 *    permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "cmsis_os.h"
33#include "los_typedef.h"
34#include "los_printf.h"
35
36#include "los_event.h"
37#include "los_membox.h"
38#include "los_memory.h"
39#include "los_hwi.h"
40
41#include "los_mux_pri.h"
42#include "los_queue_pri.h"
43#include "los_sem_pri.h"
44#include "los_swtmr_pri.h"
45#include "los_sys_pri.h"
46#include "los_task_pri.h"
47#include "los_tick_pri.h"
48#include "string.h"
49#include "securec.h"
50
51#ifdef __cplusplus
52#if __cplusplus
53extern "C" {
54#endif /* __cplusplus */
55#endif /* __cplusplus */
56#if (CMSIS_OS_VER == 2)
57
58/* Kernel initialization state */
59static osKernelState_t g_kernelState;
60
61extern BOOL g_taskScheduled;
62
63#define LOS_PRIORITY_WIN 8
64
65const osVersion_t g_stLosVersion = { 001, 001 };
66
67#define LITEOS_VERSION_MAJOR 1
68#define LITEOS_VERSION_MINOR 0
69#define LITEOS_VERSION_BUILD 0
70
71/* Kernel version and identification string definition */
72#define KERNEL_VERSION            (((UINT32)LITEOS_VERSION_MAJOR * 10000000UL) | \
73                                   ((UINT32)LITEOS_VERSION_MINOR *    10000UL) | \
74                                   ((UINT32)LITEOS_VERSION_BUILD *        1UL))
75
76#define KERNEL_ID "HUAWEI-LiteOS"
77#define UNUSED(var) do { (void)var; } while (0)
78
79//  ==== Kernel Management Functions ====
80uint32_t osTaskStackWaterMarkGet(UINT32 taskID);
81
82
83osStatus_t osKernelInitialize(void)
84{
85    if (OS_INT_ACTIVE) {
86        return osErrorISR;
87    }
88
89    if (g_kernelState != osKernelInactive) {
90        return osError;
91    }
92
93    if (LOS_OK == LOS_KernelInit()) {
94        g_kernelState = osKernelReady;
95        return osOK;
96    } else {
97        return osError;
98    }
99}
100
101
102osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size)
103{
104    uint32_t uwRet;
105
106    if (OS_INT_ACTIVE) {
107        return osErrorISR;
108    }
109
110    if (version != NULL) {
111        version->api = g_stLosVersion.api;
112        version->kernel = g_stLosVersion.kernel;
113    }
114
115    if ((id_buf != NULL) && (id_size != 0U)) {
116        if (id_size > sizeof(KERNEL_ID)) {
117            id_size = sizeof(KERNEL_ID);
118        }
119        uwRet = memcpy_s(id_buf, id_size, KERNEL_ID, id_size);
120        if (uwRet != EOK) {
121            PRINT_ERR("%s[%d] memcpy failed, error type = %u\n", __FUNCTION__, __LINE__, uwRet);
122            return osError;
123        }
124    }
125
126    return osOK;
127}
128
129
130osKernelState_t osKernelGetState(void)
131{
132    if (OS_INT_ACTIVE) {
133        return osKernelError;
134    }
135
136    if (!g_taskScheduled) {
137        if (g_kernelState == osKernelReady) {
138            return osKernelReady;
139        } else {
140            return osKernelInactive;
141        }
142    } else if (g_losTaskLock > 0) {
143        return osKernelLocked;
144    } else {
145        return osKernelRunning;
146    }
147}
148
149
150osStatus_t osKernelStart(void)
151{
152    if (OS_INT_ACTIVE) {
153        return osErrorISR;
154    }
155
156    if (g_kernelState == osKernelReady) {
157        if (LOS_OK == LOS_Start()) {
158            g_kernelState = osKernelRunning;
159            return osOK;
160        } else {
161            return osError;
162        }
163    } else {
164        return osError;
165    }
166}
167
168
169int32_t osKernelLock(void)
170{
171    int32_t lock;
172
173    if (OS_INT_ACTIVE) {
174        return (int32_t)osErrorISR;
175    }
176
177    if (!g_taskScheduled) {
178        return (int32_t)osError;
179    }
180
181    if (g_losTaskLock > 0) {
182        lock = 1;
183    } else {
184        LOS_TaskLock();
185        lock = 0;
186    }
187
188    return lock;
189}
190
191
192int32_t osKernelUnlock(void)
193{
194    int32_t lock;
195
196    if (OS_INT_ACTIVE) {
197        return (int32_t)osErrorISR;
198    }
199
200    if (!g_taskScheduled) {
201        return (int32_t)osError;
202    }
203
204    if (g_losTaskLock > 0) {
205        LOS_TaskUnlock();
206        if (g_losTaskLock != 0) {
207            return (int32_t)osError;
208        }
209        lock = 1;
210    } else {
211        lock = 0;
212    }
213
214    return lock;
215}
216
217
218int32_t osKernelRestoreLock(int32_t lock)
219{
220    if (OS_INT_ACTIVE) {
221        return (int32_t)osErrorISR;
222    }
223
224    if (!g_taskScheduled) {
225        return (int32_t)osError;
226    }
227
228    switch (lock) {
229        case 0:
230            LOS_TaskUnlock();
231            if (g_losTaskLock != 0) {
232                break;
233            }
234            return 0;
235        case 1:
236            LOS_TaskLock();
237            return 1;
238        default:
239            break;
240    }
241
242    return (int32_t)osError;
243}
244
245
246uint32_t osKernelGetTickCount(void)
247{
248    uint64_t ticks;
249    UINTPTR uvIntSave;
250
251    if (OS_INT_ACTIVE) {
252#ifndef LITEOS_WIFI_IOT_VERSION
253        ticks = g_ullTickCount;
254#else
255        ticks = g_tickCount;
256#endif
257    } else {
258        uvIntSave = LOS_IntLock();
259#ifndef LITEOS_WIFI_IOT_VERSION
260        ticks = g_ullTickCount;
261#else
262        ticks = g_tickCount;
263#endif
264        LOS_IntRestore(uvIntSave);
265    }
266
267    return (uint32_t)ticks;
268}
269
270uint32_t osKernelGetTickFreq(void)
271{
272    uint32_t freq;
273
274    if (OS_INT_ACTIVE) {
275        freq = 0U;
276    } else {
277        freq = LOSCFG_BASE_CORE_TICK_PER_SECOND;
278    }
279
280    return (freq);
281}
282
283extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo);
284uint32_t osKernelGetSysTimerCount(void)
285{
286    uint32_t countHigh = 0;
287    uint32_t countLow = 0;
288    if (OS_INT_ACTIVE) {
289        countLow = 0U;
290    } else {
291        LOS_GetCpuCycle((UINT32 *)&countHigh, (UINT32 *)&countLow);
292    }
293    return countLow;
294}
295
296
297uint32_t osKernelGetSysTimerFreq(void)
298{
299    return OS_SYS_CLOCK;
300}
301
302
303//  ==== Thread Management Functions ====
304
305osThreadId_t osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr)
306{
307    UINT32 uwTid;
308    UINT32 uwRet;
309    LosTaskCB *pstTaskCB = NULL;
310    TSK_INIT_PARAM_S stTskInitParam;
311
312    if (OS_INT_ACTIVE) {
313        return NULL;
314    }
315
316    if ((attr == NULL) || (func == NULL) || (attr->priority < osPriorityLow1) ||
317        (attr->priority > osPriorityAboveNormal6)) {
318        return (osThreadId_t)NULL;
319    }
320
321    (void)memset_s(&stTskInitParam, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
322    stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)func;
323#ifndef LITEOS_WIFI_IOT_VERSION
324    stTskInitParam.uwArg = (UINT32)argument;
325#else
326    stTskInitParam.auwArgs[0] = (UINT32)argument;
327#endif
328    stTskInitParam.uwStackSize = attr->stack_size;
329    stTskInitParam.pcName = (CHAR *)attr->name;
330    stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - ((UINT16)(attr->priority) - LOS_PRIORITY_WIN); /* 0~31 */
331
332    uwRet = LOS_TaskCreate(&uwTid, &stTskInitParam);
333
334    if (LOS_OK != uwRet) {
335        return (osThreadId_t)NULL;
336    }
337
338    pstTaskCB = OS_TCB_FROM_TID(uwTid);
339
340    return (osThreadId_t)pstTaskCB;
341}
342
343
344const char *osThreadGetName(osThreadId_t thread_id)
345{
346    LosTaskCB *pstTaskCB = NULL;
347
348    if (OS_INT_ACTIVE || thread_id == NULL) {
349        return NULL;
350    }
351
352    pstTaskCB = (LosTaskCB *)thread_id;
353
354    return pstTaskCB->taskName;
355}
356
357
358osThreadId_t osThreadGetId(void)
359{
360    if (OS_INT_ACTIVE) {
361        return NULL;
362    }
363
364    return (osThreadId_t)(g_losTask.runTask);
365}
366
367void *osThreadGetArgument(void)
368{
369    if (OS_INT_ACTIVE) {
370        return 0;
371    }
372
373    LosTaskCB *taskCb = (LosTaskCB *)osThreadGetId();
374    if (taskCb == NULL) {
375        return NULL;
376    }
377#ifndef LITEOS_WIFI_IOT_VERSION
378    return (void *)(taskCb->arg);
379#else
380    return (void *)(taskCb->args[0]);
381#endif
382}
383
384osThreadState_t osThreadGetState(osThreadId_t thread_id)
385{
386    UINT16 taskStatus;
387    osThreadState_t stState;
388    LosTaskCB *pstTaskCB = NULL;
389
390    if (OS_INT_ACTIVE || thread_id == NULL) {
391        return osThreadError;
392    }
393
394    pstTaskCB = (LosTaskCB *)thread_id;
395    taskStatus = pstTaskCB->taskStatus;
396
397    if (taskStatus & OS_TASK_STATUS_RUNNING) {
398        stState = osThreadRunning;
399    } else if (taskStatus & OS_TASK_STATUS_READY) {
400        stState = osThreadReady;
401    } else if (taskStatus &
402        (OS_TASK_STATUS_DELAY | OS_TASK_STATUS_PEND | OS_TASK_STATUS_SUSPEND | OS_TASK_STATUS_PEND_QUEUE)) {
403        stState = osThreadBlocked;
404    } else if (taskStatus & OS_TASK_STATUS_UNUSED) {
405        stState = osThreadInactive;
406    } else {
407        stState = osThreadError;
408    }
409
410    return stState;
411}
412
413
414uint32_t osThreadGetStackSize(osThreadId_t thread_id)
415{
416    LosTaskCB *pstTaskCB = NULL;
417
418    if (OS_INT_ACTIVE || thread_id == NULL) {
419        return 0U;
420    }
421
422    pstTaskCB = (LosTaskCB *)thread_id;
423
424    return pstTaskCB->stackSize;
425}
426
427
428uint32_t osTaskStackWaterMarkGet(UINT32 taskID)
429{
430    UINT32 uwCount = 0;
431    UINT32 *ptopOfStack;
432    UINTPTR uvIntSave;
433    LosTaskCB *pstTaskCB = NULL;
434
435    if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) {
436        return 0;
437    }
438
439    uvIntSave = LOS_IntLock();
440
441    pstTaskCB = OS_TCB_FROM_TID(taskID);
442    if (OS_TASK_STATUS_UNUSED & (pstTaskCB->taskStatus)) {
443        LOS_IntRestore(uvIntSave);
444        return 0;
445    }
446
447    // first 4 bytes is OS_TASK_MAGIC_WORD, skip
448    ptopOfStack = (UINT32 *)(UINTPTR)pstTaskCB->topOfStack + 1;
449
450    while (*ptopOfStack == (UINT32)OS_TASK_STACK_INIT) {
451        ++ptopOfStack;
452        ++uwCount;
453    }
454
455    uwCount *= sizeof(UINT32);
456
457    LOS_IntRestore(uvIntSave);
458    return uwCount;
459}
460
461
462uint32_t osThreadGetStackSpace(osThreadId_t thread_id)
463{
464    LosTaskCB *pstTaskCB = NULL;
465
466    if (OS_INT_ACTIVE || thread_id == NULL) {
467        return 0U;
468    }
469
470    pstTaskCB = (LosTaskCB *)thread_id;
471
472    return osTaskStackWaterMarkGet(pstTaskCB->taskID);
473}
474
475
476osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority)
477{
478    UINT32 uwRet;
479    UINT16 usPriority;
480    LosTaskCB *pstTaskCB = NULL;
481
482    if (OS_INT_ACTIVE) {
483        return osErrorISR;
484    }
485
486    if (thread_id == NULL) {
487        return osErrorParameter;
488    }
489
490    if (priority < osPriorityLow1 || priority > osPriorityAboveNormal6) {
491        return osErrorParameter;
492    }
493
494    pstTaskCB = (LosTaskCB *)thread_id;
495    usPriority = OS_TASK_PRIORITY_LOWEST - ((UINT16)priority - LOS_PRIORITY_WIN);
496    uwRet = LOS_TaskPriSet(pstTaskCB->taskID, usPriority);
497    switch (uwRet) {
498        case LOS_ERRNO_TSK_PRIOR_ERROR:
499        case LOS_ERRNO_TSK_OPERATE_IDLE:
500        case LOS_ERRNO_TSK_ID_INVALID:
501            return osErrorParameter;
502
503        case LOS_ERRNO_TSK_NOT_CREATED:
504            return osErrorResource;
505
506        default:
507            return osOK;
508    }
509}
510
511
512osPriority_t osThreadGetPriority(osThreadId_t thread_id)
513{
514    UINT16 usRet;
515    LosTaskCB *pstTaskCB = NULL;
516
517    if (OS_INT_ACTIVE || thread_id == NULL) {
518        return osPriorityError;
519    }
520
521    pstTaskCB = (LosTaskCB *)thread_id;
522    usRet = LOS_TaskPriGet(pstTaskCB->taskID);
523
524    if (usRet == (UINT16)OS_INVALID) {
525        return osPriorityError;
526    }
527
528    return (osPriority_t)(OS_TASK_PRIORITY_LOWEST - (usRet - LOS_PRIORITY_WIN));
529}
530
531
532osStatus_t osThreadYield(void)
533{
534    UINT32 uwRet;
535
536    if (OS_INT_ACTIVE) {
537        return osErrorISR;
538    }
539
540    uwRet = LOS_TaskYield();
541
542    if (uwRet == LOS_OK) {
543        return osOK;
544    }
545
546    return osError;
547}
548
549
550osStatus_t osThreadSuspend(osThreadId_t thread_id)
551{
552    UINT32 uwRet;
553    LosTaskCB *pstTaskCB = NULL;
554
555    if (OS_INT_ACTIVE) {
556        return osErrorISR;
557    }
558
559    if (thread_id == NULL) {
560        return osErrorParameter;
561    }
562
563    pstTaskCB = (LosTaskCB *)thread_id;
564    uwRet = LOS_TaskSuspend(pstTaskCB->taskID);
565    switch (uwRet) {
566        case LOS_ERRNO_TSK_OPERATE_IDLE:
567        case LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED:
568        case LOS_ERRNO_TSK_ID_INVALID:
569            return osErrorParameter;
570
571        case LOS_ERRNO_TSK_NOT_CREATED:
572        case LOS_ERRNO_TSK_ALREADY_SUSPENDED:
573        case LOS_ERRNO_TSK_SUSPEND_LOCKED:
574            return osErrorResource;
575
576        default:
577            return osOK;
578    }
579}
580
581
582osStatus_t osThreadResume(osThreadId_t thread_id)
583{
584    UINT32 uwRet;
585    LosTaskCB *pstTaskCB = NULL;
586
587    if (OS_INT_ACTIVE) {
588        return osErrorISR;
589    }
590
591    if (thread_id == NULL) {
592        return osErrorParameter;
593    }
594
595    pstTaskCB = (LosTaskCB *)thread_id;
596    uwRet = LOS_TaskResume(pstTaskCB->taskID);
597
598    switch (uwRet) {
599        case LOS_ERRNO_TSK_ID_INVALID:
600            return osErrorParameter;
601
602        case LOS_ERRNO_TSK_NOT_CREATED:
603        case LOS_ERRNO_TSK_NOT_SUSPENDED:
604            return osErrorResource;
605
606        default:
607            return osOK;
608    }
609}
610
611
612osStatus_t osThreadTerminate(osThreadId_t thread_id)
613{
614    UINT32 uwRet;
615    LosTaskCB *pstTaskCB = NULL;
616
617    if (OS_INT_ACTIVE) {
618        return osErrorISR;
619    }
620
621    if (thread_id == NULL) {
622        return osErrorParameter;
623    }
624
625    pstTaskCB = (LosTaskCB *)thread_id;
626    uwRet = LOS_TaskDelete(pstTaskCB->taskID);
627
628    switch (uwRet) {
629        case LOS_ERRNO_TSK_OPERATE_IDLE:
630        case LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED:
631        case LOS_ERRNO_TSK_ID_INVALID:
632            return osErrorParameter;
633
634        case LOS_ERRNO_TSK_NOT_CREATED:
635            return osErrorResource;
636
637        default:
638            return osOK;
639    }
640}
641
642
643uint32_t osThreadGetCount(void)
644{
645    uint32_t uwCount = 0;
646
647    if (OS_INT_ACTIVE) {
648        return 0U;
649    }
650
651    for (uint32_t index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) {
652        if (!((g_taskCBArray + index)->taskStatus & OS_TASK_STATUS_UNUSED)) {
653            uwCount++;
654        }
655    }
656
657    return uwCount;
658}
659
660
661//  ==== Generic Wait Functions ====
662WEAK UINT32 LOS_HalDelay(UINT32 ticks)
663{
664    UNUSED(ticks);
665    return LOS_ERRNO_TSK_DELAY_IN_INT;
666}
667
668
669osStatus_t osDelay(uint32_t ticks)
670{
671    UINT32 uwRet;
672    if (ticks == 0) {
673        return osOK;
674    }
675    if (osKernelGetState() != osKernelRunning) {
676        uwRet = LOS_HalDelay(ticks);
677    } else {
678        uwRet = LOS_TaskDelay(ticks);
679    }
680    if (uwRet == LOS_OK) {
681        return osOK;
682    } else {
683        return osError;
684    }
685}
686
687
688osStatus_t osDelayUntil(uint32_t ticks)
689{
690    UINT32 uwRet;
691    UINT32 uwTicks;
692    UINT32 tickCount = osKernelGetTickCount();
693
694    if (ticks < tickCount) {
695        return osError;
696    }
697
698    uwTicks = (UINT32)(ticks - tickCount);
699
700    uwRet = LOS_TaskDelay(uwTicks);
701    if (uwRet == LOS_OK) {
702        return osOK;
703    } else {
704        return osError;
705    }
706}
707
708//  ==== Timer Management Functions ====
709#if (LOSCFG_BASE_CORE_SWTMR == 1)
710osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr)
711{
712    UNUSED(attr);
713    UINT16 usSwTmrID;
714    UINT8 mode;
715
716    if ((OS_INT_ACTIVE) || (NULL == func) || ((osTimerOnce != type) && (osTimerPeriodic != type))) {
717        return (osTimerId_t)NULL;
718    }
719
720    if (osTimerOnce == type) {
721        mode = LOS_SWTMR_MODE_NO_SELFDELETE;
722    } else {
723        mode = LOS_SWTMR_MODE_PERIOD;
724    }
725#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
726    if (LOS_OK != LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, &usSwTmrID, (UINT32)(UINTPTR)argument,
727        osTimerRousesAllow, osTimerAlignIgnore)) {
728        return (osTimerId_t)NULL;
729    }
730#else
731    if (LOS_OK != LOS_SwtmrCreate(1, mode, (SWTMR_PROC_FUNC)func, &usSwTmrID, (UINT32)(UINTPTR)argument)) {
732        return (osTimerId_t)NULL;
733    }
734#endif
735
736    return (osTimerId_t)OS_SWT_FROM_SID(usSwTmrID);
737}
738
739osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
740{
741    UINT32 uwRet;
742    SWTMR_CTRL_S *pstSwtmr;
743
744    if ((0 == ticks) || (NULL == timer_id)) {
745        return osErrorParameter;
746    }
747
748    pstSwtmr = (SWTMR_CTRL_S *)timer_id;
749    pstSwtmr->uwInterval = ticks;
750    uwRet = LOS_SwtmrStart(pstSwtmr->usTimerID);
751    if (LOS_OK == uwRet) {
752        return osOK;
753    } else if (LOS_ERRNO_SWTMR_ID_INVALID == uwRet) {
754        return osErrorParameter;
755    } else {
756        return osErrorResource;
757    }
758}
759
760
761const char *osTimerGetName(osTimerId_t timer_id)
762{
763    UNUSED(timer_id);
764    return (const char *)NULL;
765}
766
767
768osStatus_t osTimerStop(osTimerId_t timer_id)
769{
770    UINT32 uwRet;
771    SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)timer_id;
772
773    if (OS_INT_ACTIVE) {
774        return osErrorISR;
775    }
776
777    if (NULL == pstSwtmr) {
778        return osErrorParameter;
779    }
780
781    uwRet = LOS_SwtmrStop(pstSwtmr->usTimerID);
782    if (LOS_OK == uwRet) {
783        return osOK;
784    } else if (LOS_ERRNO_SWTMR_ID_INVALID == uwRet) {
785        return osErrorParameter;
786    } else {
787        return osErrorResource;
788    }
789}
790
791
792uint32_t osTimerIsRunning(osTimerId_t timer_id)
793{
794    if ((OS_INT_ACTIVE) || (NULL == timer_id)) {
795        return 0;
796    }
797
798    return (OS_SWTMR_STATUS_TICKING == ((SWTMR_CTRL_S *)timer_id)->ucState);
799}
800
801
802osStatus_t osTimerDelete(osTimerId_t timer_id)
803{
804    UINT32 uwRet;
805    SWTMR_CTRL_S *pstSwtmr = (SWTMR_CTRL_S *)timer_id;
806
807    if (OS_INT_ACTIVE) {
808        return osErrorISR;
809    }
810
811    if (NULL == pstSwtmr) {
812        return osErrorParameter;
813    }
814
815    uwRet = LOS_SwtmrDelete(pstSwtmr->usTimerID);
816    if (LOS_OK == uwRet) {
817        return osOK;
818    } else if (LOS_ERRNO_SWTMR_ID_INVALID == uwRet) {
819        return osErrorParameter;
820    } else {
821        return osErrorResource;
822    }
823}
824#endif
825
826osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
827{
828    PEVENT_CB_S pstEventCB;
829    UINT32 uwRet;
830
831    UNUSED(attr);
832
833    if (OS_INT_ACTIVE) {
834        return (osEventFlagsId_t)NULL;
835    }
836
837    pstEventCB = (PEVENT_CB_S)LOS_MemAlloc(m_aucSysMem0, sizeof(EVENT_CB_S));
838    if (pstEventCB == NULL) {
839        return (osEventFlagsId_t)NULL;
840    }
841
842    uwRet = LOS_EventInit(pstEventCB);
843    if (uwRet == LOS_ERRNO_EVENT_PTR_NULL) {
844        return (osEventFlagsId_t)NULL;
845    } else {
846        return (osEventFlagsId_t)pstEventCB;
847    }
848}
849
850
851const char *osEventFlagsGetName(osEventFlagsId_t ef_id)
852{
853    UNUSED(ef_id);
854
855    if (OS_INT_ACTIVE) {
856        return (const char *)NULL;
857    }
858
859    return (const char *)NULL;
860}
861
862
863uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags)
864{
865    PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id;
866    UINT32 uwRet;
867    uint32_t rflags;
868    if (pstEventCB == NULL) {
869        return osFlagsErrorParameter;
870    }
871    uwRet = LOS_EventWrite(pstEventCB, (UINT32)flags);
872    if (uwRet != LOS_OK) {
873        return (uint32_t)osFlagsErrorParameter;
874    } else {
875        rflags = pstEventCB->uwEventID;
876        return rflags;
877    }
878}
879
880
881uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags)
882{
883    PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id;
884    UINTPTR uwIntSave;
885    uint32_t rflags;
886    UINT32 uwRet;
887
888    if (pstEventCB == NULL) {
889        return (uint32_t)osFlagsErrorParameter;
890    }
891
892    uwIntSave = LOS_IntLock();
893    rflags = pstEventCB->uwEventID;
894
895    uwRet = LOS_EventClear(pstEventCB, ~flags);
896    LOS_IntRestore(uwIntSave);
897    if (uwRet != LOS_OK) {
898        return (uint32_t)osFlagsErrorParameter;
899    } else {
900        return rflags;
901    }
902}
903
904
905uint32_t osEventFlagsGet(osEventFlagsId_t ef_id)
906{
907    PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id;
908    UINTPTR uwIntSave;
909    uint32_t rflags;
910
911    if (pstEventCB == NULL) {
912        return (uint32_t)osFlagsErrorParameter;
913    }
914
915    uwIntSave = LOS_IntLock();
916    rflags = pstEventCB->uwEventID;
917    LOS_IntRestore(uwIntSave);
918
919    return rflags;
920}
921
922uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)
923{
924    PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id;
925    UINT32 uwMode = 0;
926    UINT32 uwRet;
927    uint32_t rflags;
928
929    if (options > (osFlagsWaitAny | osFlagsWaitAll | osFlagsNoClear)) {
930        return (uint32_t)osFlagsErrorParameter;
931    }
932
933    if ((options & osFlagsWaitAll) == osFlagsWaitAll) {
934        uwMode |= LOS_WAITMODE_AND;
935    } else {
936        uwMode |= LOS_WAITMODE_OR;
937    }
938
939    if ((options & osFlagsNoClear) == osFlagsNoClear) {
940        uwMode &= ~LOS_WAITMODE_CLR;
941    } else {
942        uwMode |= LOS_WAITMODE_CLR;
943    }
944
945    uwRet = LOS_EventRead(pstEventCB, (UINT32)flags, uwMode, (UINT32)timeout);
946    switch (uwRet) {
947        case LOS_ERRNO_EVENT_PTR_NULL:
948        case LOS_ERRNO_EVENT_EVENTMASK_INVALID:
949        case LOS_ERRNO_EVENT_SETBIT_INVALID:
950            return (uint32_t)osFlagsErrorParameter;
951
952        case LOS_ERRNO_EVENT_READ_IN_INTERRUPT:
953        case LOS_ERRNO_EVENT_FLAGS_INVALID:
954        case LOS_ERRNO_EVENT_READ_IN_LOCK:
955            return (uint32_t)osFlagsErrorResource;
956
957        case LOS_ERRNO_EVENT_READ_TIMEOUT:
958            return (uint32_t)osFlagsErrorTimeout;
959
960        default:
961            rflags = (uint32_t)uwRet;
962            return rflags;
963    }
964}
965
966osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id)
967{
968    PEVENT_CB_S pstEventCB = (PEVENT_CB_S)ef_id;
969    UINTPTR uwIntSave;
970    osStatus_t uwRet;
971
972    uwIntSave = LOS_IntLock();
973    if (LOS_EventDestroy(pstEventCB) == LOS_OK) {
974        uwRet = osOK;
975    } else {
976        uwRet = osErrorParameter;
977    }
978    LOS_IntRestore(uwIntSave);
979
980    if (LOS_MemFree(m_aucSysMem0, (void *)pstEventCB) == LOS_OK) {
981        uwRet = osOK;
982    } else {
983        uwRet = osErrorParameter;
984    }
985
986    return uwRet;
987}
988
989//  ==== Mutex Management Functions ====
990#if (LOSCFG_BASE_IPC_MUX == 1)
991osMutexId_t osMutexNew(const osMutexAttr_t *attr)
992{
993    UINT32 uwRet;
994    UINT32 uwMuxId;
995
996    UNUSED(attr);
997
998    if (OS_INT_ACTIVE) {
999        return NULL;
1000    }
1001
1002    uwRet = LOS_MuxCreate(&uwMuxId);
1003    if (uwRet == LOS_OK) {
1004        return (osMutexId_t)(GET_MUX(uwMuxId));
1005    } else {
1006        return (osMutexId_t)NULL;
1007    }
1008}
1009
1010
1011osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout)
1012{
1013    UINT32 uwRet;
1014
1015    if (mutex_id == NULL) {
1016        return osErrorParameter;
1017    }
1018
1019    if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) {
1020        timeout = 0;
1021    }
1022
1023    uwRet = LOS_MuxPend(((LosMuxCB *)mutex_id)->muxID, timeout);
1024    if (uwRet == LOS_OK) {
1025        return osOK;
1026    } else if (uwRet == LOS_ERRNO_MUX_TIMEOUT) {
1027        return osErrorTimeout;
1028    } else if (uwRet == LOS_ERRNO_MUX_INVALID) {
1029        return osErrorParameter;
1030    } else {
1031        return osErrorResource;
1032    }
1033}
1034
1035
1036osStatus_t osMutexRelease(osMutexId_t mutex_id)
1037{
1038    UINT32 uwRet;
1039
1040    if (mutex_id == NULL) {
1041        return osErrorParameter;
1042    }
1043
1044    uwRet = LOS_MuxPost(((LosMuxCB *)mutex_id)->muxID);
1045    if (uwRet == LOS_OK) {
1046        return osOK;
1047    } else {
1048        return osErrorResource;
1049    }
1050}
1051
1052
1053osThreadId_t osMutexGetOwner(osMutexId_t mutex_id)
1054{
1055    UINT32 uwIntSave;
1056    LosTaskCB *pstTaskCB;
1057
1058    if (OS_INT_ACTIVE) {
1059        return NULL;
1060    }
1061
1062    if (mutex_id == NULL) {
1063        return NULL;
1064    }
1065
1066    uwIntSave = LOS_IntLock();
1067    pstTaskCB = ((LosMuxCB *)mutex_id)->owner;
1068    LOS_IntRestore(uwIntSave);
1069
1070    return (osThreadId_t)pstTaskCB;
1071}
1072
1073
1074osStatus_t osMutexDelete(osMutexId_t mutex_id)
1075{
1076    UINT32 uwRet;
1077
1078    if (OS_INT_ACTIVE) {
1079        return osErrorISR;
1080    }
1081
1082    if (mutex_id == NULL) {
1083        return osErrorParameter;
1084    }
1085
1086    uwRet = LOS_MuxDelete(((LosMuxCB *)mutex_id)->muxID);
1087    if (uwRet == LOS_OK) {
1088        return osOK;
1089    } else if (uwRet == LOS_ERRNO_MUX_INVALID) {
1090        return osErrorParameter;
1091    } else {
1092        return osErrorResource;
1093    }
1094}
1095#endif
1096
1097//  ==== Semaphore Management Functions ====
1098#if (LOSCFG_BASE_IPC_SEM == 1)
1099
1100osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
1101{
1102    UINT32 uwRet;
1103    UINT32 uwSemId;
1104
1105    UNUSED(attr);
1106
1107    if (OS_INT_ACTIVE) {
1108        return (osSemaphoreId_t)NULL;
1109    }
1110
1111    if (1 == max_count) {
1112        uwRet = LOS_BinarySemCreate((UINT16)initial_count, &uwSemId);
1113    } else {
1114        uwRet = LOS_SemCreate((UINT16)initial_count, &uwSemId);
1115    }
1116
1117    if (uwRet == LOS_OK) {
1118        return (osSemaphoreId_t)(GET_SEM(uwSemId));
1119    } else {
1120        return (osSemaphoreId_t)NULL;
1121    }
1122}
1123
1124
1125osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
1126{
1127    UINT32 uwRet;
1128
1129    if (semaphore_id == NULL) {
1130        return osErrorParameter;
1131    }
1132
1133    if (OS_INT_ACTIVE && (timeout != LOS_NO_WAIT)) {
1134        return osErrorISR;
1135    }
1136
1137    uwRet = LOS_SemPend(((LosSemCB *)semaphore_id)->semID, timeout);
1138    if (uwRet == LOS_OK) {
1139        return osOK;
1140    } else if (uwRet == LOS_ERRNO_SEM_TIMEOUT) {
1141        return osErrorTimeout;
1142    } else if (uwRet == LOS_ERRNO_SEM_INVALID) {
1143        return osErrorParameter;
1144    } else if (uwRet == LOS_ERRNO_SEM_PEND_INTERR) {
1145        return osErrorISR;
1146    } else {
1147        return osErrorResource;
1148    }
1149}
1150
1151
1152osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
1153{
1154    UINT32 uwRet;
1155
1156    if (semaphore_id == NULL) {
1157        return osErrorParameter;
1158    }
1159
1160    uwRet = LOS_SemPost(((LosSemCB *)semaphore_id)->semID);
1161    if (uwRet == LOS_OK) {
1162        return osOK;
1163    } else if (uwRet == LOS_ERRNO_SEM_INVALID) {
1164        return osErrorParameter;
1165    } else {
1166        return osErrorResource;
1167    }
1168}
1169
1170
1171uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
1172{
1173    UINT32 uwIntSave;
1174    UINT32 uwCount;
1175
1176    if (OS_INT_ACTIVE) {
1177        return 0;
1178    }
1179
1180    if (semaphore_id == NULL) {
1181        return 0;
1182    }
1183
1184    uwIntSave = LOS_IntLock();
1185    uwCount = ((LosSemCB *)semaphore_id)->semCount;
1186    LOS_IntRestore(uwIntSave);
1187
1188    return uwCount;
1189}
1190
1191
1192osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
1193{
1194    UINT32 uwRet;
1195
1196    if (OS_INT_ACTIVE) {
1197        return osErrorISR;
1198    }
1199
1200    if (semaphore_id == NULL) {
1201        return osErrorParameter;
1202    }
1203
1204    uwRet = LOS_SemDelete(((LosSemCB *)semaphore_id)->semID);
1205    if (uwRet == LOS_OK) {
1206        return osOK;
1207    } else if (uwRet == LOS_ERRNO_SEM_INVALID) {
1208        return osErrorParameter;
1209    } else {
1210        return osErrorResource;
1211    }
1212}
1213#endif
1214
1215
1216//  ==== Message Queue Management Functions ====
1217#if (LOSCFG_BASE_IPC_QUEUE == 1)
1218osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
1219{
1220    UINT32 uwQueueID;
1221    UINT32 uwRet;
1222    UNUSED(attr);
1223    osMessageQueueId_t handle;
1224
1225    if (0 == msg_count || 0 == msg_size || OS_INT_ACTIVE) {
1226        return (osMessageQueueId_t)NULL;
1227    }
1228
1229    uwRet = LOS_QueueCreate((char *)NULL, (UINT16)msg_count, &uwQueueID, 0, (UINT16)msg_size);
1230    if (uwRet == LOS_OK) {
1231        handle = (osMessageQueueId_t)(GET_QUEUE_HANDLE(uwQueueID));
1232    } else {
1233        handle = (osMessageQueueId_t)NULL;
1234    }
1235
1236    return handle;
1237}
1238
1239
1240osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)
1241{
1242    UNUSED(msg_prio);
1243    UINT32 uwRet;
1244    UINT32 uwBufferSize;
1245    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1246
1247    if (pstQueue == NULL || msg_ptr == NULL || ((OS_INT_ACTIVE) && (0 != timeout))) {
1248        return osErrorParameter;
1249    }
1250    if (pstQueue->queueSize < sizeof(UINT32)) {
1251        return osErrorParameter;
1252    }
1253    uwBufferSize = (UINT32)(pstQueue->queueSize - sizeof(UINT32));
1254    uwRet = LOS_QueueWriteCopy((UINT32)pstQueue->queueID, (void *)msg_ptr, uwBufferSize, timeout);
1255    if (uwRet == LOS_OK) {
1256        return osOK;
1257    } else if (uwRet == LOS_ERRNO_QUEUE_INVALID || uwRet == LOS_ERRNO_QUEUE_NOT_CREATE) {
1258        return osErrorParameter;
1259    } else if (uwRet == LOS_ERRNO_QUEUE_TIMEOUT) {
1260        return osErrorTimeout;
1261    } else {
1262        return osErrorResource;
1263    }
1264}
1265
1266
1267osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
1268{
1269    UNUSED(msg_prio);
1270    UINT32 uwRet;
1271    UINT32 uwBufferSize;
1272    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1273
1274    if (pstQueue == NULL || msg_ptr == NULL || ((OS_INT_ACTIVE) && (0 != timeout))) {
1275        return osErrorParameter;
1276    }
1277
1278    uwBufferSize = (UINT32)(pstQueue->queueSize - sizeof(UINT32));
1279    uwRet = LOS_QueueReadCopy((UINT32)pstQueue->queueID, msg_ptr, &uwBufferSize, timeout);
1280    if (uwRet == LOS_OK) {
1281        return osOK;
1282    } else if (uwRet == LOS_ERRNO_QUEUE_INVALID || uwRet == LOS_ERRNO_QUEUE_NOT_CREATE) {
1283        return osErrorParameter;
1284    } else if (uwRet == LOS_ERRNO_QUEUE_TIMEOUT) {
1285        return osErrorTimeout;
1286    } else {
1287        return osErrorResource;
1288    }
1289}
1290
1291uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id)
1292{
1293    uint32_t capacity;
1294    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1295
1296    if (pstQueue == NULL) {
1297        capacity = 0U;
1298    } else {
1299        capacity = pstQueue->queueLen;
1300    }
1301
1302    return (capacity);
1303}
1304
1305uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)
1306{
1307    uint32_t size;
1308    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1309
1310    if (pstQueue == NULL) {
1311        size = 0U;
1312    } else {
1313        size = pstQueue->queueSize - sizeof(UINT32);
1314    }
1315
1316    return (size);
1317}
1318
1319
1320uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id)
1321{
1322    uint32_t count;
1323    UINTPTR uwIntSave;
1324    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1325
1326    if (pstQueue == NULL) {
1327        count = 0U;
1328    } else {
1329        uwIntSave = LOS_IntLock();
1330        count = (uint32_t)(pstQueue->readWriteableCnt[OS_QUEUE_READ]);
1331        LOS_IntRestore(uwIntSave);
1332    }
1333    return count;
1334}
1335
1336
1337uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id)
1338{
1339    uint32_t space;
1340    UINTPTR uwIntSave;
1341    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1342
1343    if (pstQueue == NULL) {
1344        space = 0U;
1345    } else {
1346        uwIntSave = LOS_IntLock();
1347        space = (uint32_t)pstQueue->readWriteableCnt[OS_QUEUE_WRITE];
1348        LOS_IntRestore(uwIntSave);
1349    }
1350    return space;
1351}
1352
1353osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
1354{
1355    LosQueueCB *pstQueue = (LosQueueCB *)mq_id;
1356    UINT32 uwRet;
1357
1358    if (pstQueue == NULL) {
1359        return osErrorParameter;
1360    }
1361
1362    if (OS_INT_ACTIVE) {
1363        return osErrorISR;
1364    }
1365
1366    uwRet = LOS_QueueDelete((UINT32)pstQueue->queueID);
1367    if (uwRet == LOS_OK) {
1368        return osOK;
1369    } else if (uwRet == LOS_ERRNO_QUEUE_NOT_FOUND || uwRet == LOS_ERRNO_QUEUE_NOT_CREATE) {
1370        return osErrorParameter;
1371    } else {
1372        return osErrorResource;
1373    }
1374}
1375void osThreadExit(void)
1376{
1377    return;
1378}
1379#endif
1380
1381#endif // (CMSIS_OS_VER == 2)
1382#ifdef __cplusplus
1383#if __cplusplus
1384}
1385#endif /* __cplusplus */
1386#endif /* __cplusplus */
1387