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
53 extern "C" {
54 #endif /* __cplusplus */
55 #endif /* __cplusplus */
56 #if (CMSIS_OS_VER == 2)
57
58 /* Kernel initialization state */
59 static osKernelState_t g_kernelState;
60
61 extern BOOL g_taskScheduled;
62
63 #define LOS_PRIORITY_WIN 8
64
65 const 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 ====
80 uint32_t osTaskStackWaterMarkGet(UINT32 taskID);
81
82
osKernelInitialize(void)83 osStatus_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
osKernelGetInfo(osVersion_t * version,char * id_buf,uint32_t id_size)102 osStatus_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
osKernelGetState(void)130 osKernelState_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
osKernelStart(void)150 osStatus_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
osKernelLock(void)169 int32_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
osKernelUnlock(void)192 int32_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
osKernelRestoreLock(int32_t lock)218 int32_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
osKernelGetTickCount(void)246 uint32_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
osKernelGetTickFreq(void)270 uint32_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
283 extern VOID LOS_GetCpuCycle(UINT32 *puwCntHi, UINT32 *puwCntLo);
osKernelGetSysTimerCount(void)284 uint32_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
osKernelGetSysTimerFreq(void)297 uint32_t osKernelGetSysTimerFreq(void)
298 {
299 return OS_SYS_CLOCK;
300 }
301
302
303 // ==== Thread Management Functions ====
304
osThreadNew(osThreadFunc_t func,void * argument,const osThreadAttr_t * attr)305 osThreadId_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
osThreadGetName(osThreadId_t thread_id)344 const 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
osThreadGetId(void)358 osThreadId_t osThreadGetId(void)
359 {
360 if (OS_INT_ACTIVE) {
361 return NULL;
362 }
363
364 return (osThreadId_t)(g_losTask.runTask);
365 }
366
osThreadGetArgument(void)367 void *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
osThreadGetState(osThreadId_t thread_id)384 osThreadState_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
osThreadGetStackSize(osThreadId_t thread_id)414 uint32_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
osTaskStackWaterMarkGet(UINT32 taskID)428 uint32_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
osThreadGetStackSpace(osThreadId_t thread_id)462 uint32_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
osThreadSetPriority(osThreadId_t thread_id,osPriority_t priority)476 osStatus_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
osThreadGetPriority(osThreadId_t thread_id)512 osPriority_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
osThreadYield(void)532 osStatus_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
osThreadSuspend(osThreadId_t thread_id)550 osStatus_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
osThreadResume(osThreadId_t thread_id)582 osStatus_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
osThreadTerminate(osThreadId_t thread_id)612 osStatus_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
osThreadGetCount(void)643 uint32_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 ====
LOS_HalDelay(UINT32 ticks)662 WEAK UINT32 LOS_HalDelay(UINT32 ticks)
663 {
664 UNUSED(ticks);
665 return LOS_ERRNO_TSK_DELAY_IN_INT;
666 }
667
668
osDelay(uint32_t ticks)669 osStatus_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
osDelayUntil(uint32_t ticks)688 osStatus_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)
osTimerNew(osTimerFunc_t func,osTimerType_t type,void * argument,const osTimerAttr_t * attr)710 osTimerId_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
osTimerStart(osTimerId_t timer_id,uint32_t ticks)739 osStatus_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
osTimerGetName(osTimerId_t timer_id)761 const char *osTimerGetName(osTimerId_t timer_id)
762 {
763 UNUSED(timer_id);
764 return (const char *)NULL;
765 }
766
767
osTimerStop(osTimerId_t timer_id)768 osStatus_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
osTimerIsRunning(osTimerId_t timer_id)792 uint32_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
osTimerDelete(osTimerId_t timer_id)802 osStatus_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
osEventFlagsNew(const osEventFlagsAttr_t * attr)826 osEventFlagsId_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
osEventFlagsGetName(osEventFlagsId_t ef_id)851 const 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
osEventFlagsSet(osEventFlagsId_t ef_id,uint32_t flags)863 uint32_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
osEventFlagsClear(osEventFlagsId_t ef_id,uint32_t flags)881 uint32_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
osEventFlagsGet(osEventFlagsId_t ef_id)905 uint32_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
osEventFlagsWait(osEventFlagsId_t ef_id,uint32_t flags,uint32_t options,uint32_t timeout)922 uint32_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
osEventFlagsDelete(osEventFlagsId_t ef_id)966 osStatus_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)
osMutexNew(const osMutexAttr_t * attr)991 osMutexId_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
osMutexAcquire(osMutexId_t mutex_id,uint32_t timeout)1011 osStatus_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
osMutexRelease(osMutexId_t mutex_id)1036 osStatus_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
osMutexGetOwner(osMutexId_t mutex_id)1053 osThreadId_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
osMutexDelete(osMutexId_t mutex_id)1074 osStatus_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
osSemaphoreNew(uint32_t max_count,uint32_t initial_count,const osSemaphoreAttr_t * attr)1100 osSemaphoreId_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
osSemaphoreAcquire(osSemaphoreId_t semaphore_id,uint32_t timeout)1125 osStatus_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
osSemaphoreRelease(osSemaphoreId_t semaphore_id)1152 osStatus_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
osSemaphoreGetCount(osSemaphoreId_t semaphore_id)1171 uint32_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
osSemaphoreDelete(osSemaphoreId_t semaphore_id)1192 osStatus_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)
osMessageQueueNew(uint32_t msg_count,uint32_t msg_size,const osMessageQueueAttr_t * attr)1218 osMessageQueueId_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
osMessageQueuePut(osMessageQueueId_t mq_id,const void * msg_ptr,uint8_t msg_prio,uint32_t timeout)1240 osStatus_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
osMessageQueueGet(osMessageQueueId_t mq_id,void * msg_ptr,uint8_t * msg_prio,uint32_t timeout)1267 osStatus_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
osMessageQueueGetCapacity(osMessageQueueId_t mq_id)1291 uint32_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
osMessageQueueGetMsgSize(osMessageQueueId_t mq_id)1305 uint32_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
osMessageQueueGetCount(osMessageQueueId_t mq_id)1320 uint32_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
osMessageQueueGetSpace(osMessageQueueId_t mq_id)1337 uint32_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
osMessageQueueDelete(osMessageQueueId_t mq_id)1353 osStatus_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 }
osThreadExit(void)1375 void 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