• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "los_task.h"
33 #include "securec.h"
34 #include "los_config.h"
35 #include "los_debug.h"
36 #include "los_hook.h"
37 #include "los_interrupt.h"
38 #include "los_memory.h"
39 #include "los_mpu.h"
40 #include "los_sched.h"
41 #include "los_mux.h"
42 #include "los_sem.h"
43 #include "los_timer.h"
44 #if (LOSCFG_BASE_CORE_CPUP == 1)
45 #include "los_cpup.h"
46 #endif
47 #if (LOSCFG_KERNEL_PM == 1)
48 #include "los_pm.h"
49 #endif
50 
51 /**
52  * @ingroup los_task
53  * @brief Convenience macro for bitwise operation of task module
54  */
55 #define EVALUATE_L(NUMBER, VALUE)  \
56             ((NUMBER) = (((NUMBER) & OS_TSK_HIGH_BITS_MASK) | (VALUE)))
57 
58 #define EVALUATE_H(NUMBER, VALUE)  \
59             ((NUMBER) = (((NUMBER) & OS_TSK_LOW_BITS_MASK) | ((VALUE) << OS_TSK_LOW_BITS)))
60 
61 #define UWROLLNUMSUB(NUMBER1, NUMBER2)  \
62             ((NUMBER1) = (((NUMBER1) & OS_TSK_HIGH_BITS_MASK) | (UWROLLNUM(NUMBER1) - UWROLLNUM(NUMBER2))))
63 
64 #define UWROLLNUMADD(NUMBER1, NUMBER2)  \
65             ((NUMBER1) = (((NUMBER1) & OS_TSK_HIGH_BITS_MASK) | (UWROLLNUM(NUMBER1) + UWROLLNUM(NUMBER2))))
66 
67 #define UWROLLNUM(NUMBER) ((NUMBER) & OS_TSK_LOW_BITS_MASK)
68 
69 #define UWSORTINDEX(NUMBER) ((NUMBER) >> OS_TSK_LOW_BITS)
70 
71 #define UWROLLNUMDEC(NUMBER)  \
72             ((NUMBER) = ((NUMBER) - 1))
73 
74 /**
75  * @ingroup los_task
76  * @brief check task id's validation
77  */
78 #define OS_TASK_ID_CHECK(taskID)              LOS_ASSERT_COND(OS_TSK_GET_INDEX(taskID) < g_taskMaxNum)
79 
80 /**
81  * @ingroup los_task
82  * @brief check task id's invalidation
83  */
84 #define OS_CHECK_TSK_PID_NOIDLE(taskID)       (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum)
85 
86 /**
87  * @ingroup los_task
88  * @brief the offset of task stack's top for skipping the magic word
89  */
90 #define OS_TASK_STACK_TOP_OFFSET                4
91 
92 #if (LOSCFG_EXC_HARDWARE_STACK_PROTECTION == 1)
93 /**
94  * @ingroup los_task
95  * @brief the size of task stack's protection area
96  */
97 #define OS_TASK_STACK_PROTECT_SIZE              32
98 #endif
99 
100 LITE_OS_SEC_BSS  LosTaskCB                           *g_taskCBArray = NULL;
101 LITE_OS_SEC_BSS  LosTask                             g_losTask;
102 LITE_OS_SEC_BSS  UINT16                              g_losTaskLock;
103 LITE_OS_SEC_BSS  UINT32                              g_taskMaxNum;
104 LITE_OS_SEC_BSS  UINT32                              g_idleTaskID;
105 LITE_OS_SEC_BSS  UINT32                              g_swtmrTaskID;
106 LITE_OS_SEC_DATA_INIT LOS_DL_LIST                    g_losFreeTask;
107 LITE_OS_SEC_DATA_INIT LOS_DL_LIST                    g_taskRecycleList;
108 LITE_OS_SEC_BSS  BOOL                                g_taskScheduled = FALSE;
109 
110 STATIC VOID (*PmEnter)(VOID) = NULL;
111 
112 #if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
113 TaskSwitchInfo g_taskSwitchInfo;
114 #endif
115 
OsCheckTaskIDValid(UINT32 taskID)116 STATIC_INLINE UINT32 OsCheckTaskIDValid(UINT32 taskID)
117 {
118     UINT32 ret = LOS_OK;
119     if (taskID == g_idleTaskID) {
120         ret = LOS_ERRNO_TSK_OPERATE_IDLE;
121     } else if (taskID == g_swtmrTaskID) {
122         ret = LOS_ERRNO_TSK_SUSPEND_SWTMR_NOT_ALLOWED;
123     } else if (OS_TSK_GET_INDEX(taskID) >= g_taskMaxNum) {
124         ret = LOS_ERRNO_TSK_ID_INVALID;
125     }
126     return ret;
127 }
128 
OsInsertTCBToFreeList(LosTaskCB * taskCB)129 STATIC INLINE VOID OsInsertTCBToFreeList(LosTaskCB *taskCB)
130 {
131     UINT32 taskID = taskCB->taskID;
132     (VOID)memset_s(taskCB, sizeof(LosTaskCB), 0, sizeof(LosTaskCB));
133     taskCB->taskID = taskID;
134     taskCB->taskStatus = OS_TASK_STATUS_UNUSED;
135     LOS_ListAdd(&g_losFreeTask, &taskCB->pendList);
136 }
137 
OsRecycleTaskResources(LosTaskCB * taskCB,UINTPTR * stackPtr)138 STATIC VOID OsRecycleTaskResources(LosTaskCB *taskCB, UINTPTR *stackPtr)
139 {
140     if ((taskCB->taskStatus & OS_TASK_FLAG_STACK_FREE) && (taskCB->topOfStack != 0)) {
141 #if (LOSCFG_EXC_HARDWARE_STACK_PROTECTION == 1)
142         *stackPtr = taskCB->topOfStack - OS_TASK_STACK_PROTECT_SIZE;
143 #else
144         *stackPtr = taskCB->topOfStack;
145 #endif
146         taskCB->topOfStack = (UINT32)NULL;
147         taskCB->taskStatus &= ~OS_TASK_FLAG_STACK_FREE;
148     }
149     if (!(taskCB->taskStatus & OS_TASK_STATUS_EXIT)) {
150         OsInsertTCBToFreeList(taskCB);
151     }
152 }
153 
OsRecyleFinishedTask(VOID)154 STATIC VOID OsRecyleFinishedTask(VOID)
155 {
156     LosTaskCB *taskCB = NULL;
157     UINT32 intSave;
158     UINTPTR stackPtr;
159 
160     intSave = LOS_IntLock();
161     while (!LOS_ListEmpty(&g_taskRecycleList)) {
162         taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_taskRecycleList));
163         LOS_ListDelete(LOS_DL_LIST_FIRST(&g_taskRecycleList));
164         stackPtr = 0;
165         OsRecycleTaskResources(taskCB, &stackPtr);
166         LOS_IntRestore(intSave);
167 
168         (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)stackPtr);
169         intSave = LOS_IntLock();
170     }
171     LOS_IntRestore(intSave);
172 }
173 
OsPmEnterHandlerSet(VOID (* func)(VOID))174 UINT32 OsPmEnterHandlerSet(VOID (*func)(VOID))
175 {
176     if (func == NULL) {
177         return LOS_NOK;
178     }
179 
180     PmEnter = func;
181     return LOS_OK;
182 }
183 
184 /*****************************************************************************
185  Function    : OsIdleTask
186  Description : Idle task.
187  Input       : None
188  Output      : None
189  Return      : None
190  *****************************************************************************/
OsIdleTask(VOID)191 LITE_OS_SEC_TEXT VOID OsIdleTask(VOID)
192 {
193     while (1) {
194         OsRecyleFinishedTask();
195 
196         if (PmEnter != NULL) {
197             PmEnter();
198         } else {
199             (VOID)ArchEnterSleep();
200         }
201     }
202 }
203 
204 /*****************************************************************************
205  Function    : OsConvertTskStatus
206  Description : Convert task status to string.
207  Input       : taskStatus    --- task status
208  Output      : None
209  Return      : string
210  *****************************************************************************/
OsConvertTskStatus(UINT16 taskStatus)211 LITE_OS_SEC_TEXT_MINOR UINT8 *OsConvertTskStatus(UINT16 taskStatus)
212 {
213     if (taskStatus & OS_TASK_STATUS_RUNNING) {
214         return (UINT8 *)"Running";
215     } else if (taskStatus & OS_TASK_STATUS_READY) {
216         return (UINT8 *)"Ready";
217     } else if (taskStatus & OS_TASK_STATUS_EXIT) {
218         return (UINT8 *)"Exit";
219     } else if (taskStatus & OS_TASK_STATUS_SUSPEND) {
220         return (UINT8 *)"Suspend";
221     } else if (taskStatus & OS_TASK_STATUS_DELAY) {
222         return (UINT8 *)"Delay";
223     } else if (taskStatus & OS_TASK_STATUS_PEND) {
224         if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
225             return (UINT8 *)"PendTime";
226         }
227         return (UINT8 *)"Pend";
228     }
229 
230     return (UINT8 *)"Impossible";
231 }
232 
OsGetTaskWaterLine(UINT32 taskID)233 UINT32 OsGetTaskWaterLine(UINT32 taskID)
234 {
235     UINT32 *stackPtr = NULL;
236     UINT32 peakUsed;
237 
238     if (*(UINT32 *)(UINTPTR)OS_TCB_FROM_TID(taskID)->topOfStack == OS_TASK_MAGIC_WORD) {
239         stackPtr = (UINT32 *)(UINTPTR)(OS_TCB_FROM_TID(taskID)->topOfStack + OS_TASK_STACK_TOP_OFFSET);
240         while ((stackPtr < (UINT32 *)(OS_TCB_FROM_TID(taskID)->stackPointer)) && (*stackPtr == OS_TASK_STACK_INIT)) {
241             stackPtr += 1;
242         }
243         peakUsed = OS_TCB_FROM_TID(taskID)->stackSize -
244             ((UINT32)(UINTPTR)stackPtr - OS_TCB_FROM_TID(taskID)->topOfStack);
245     } else {
246         PRINT_ERR("CURRENT task %s stack overflow!\n", OS_TCB_FROM_TID(taskID)->taskName);
247         peakUsed = OS_NULL_INT;
248     }
249     return peakUsed;
250 }
251 
252 #if (LOSCFG_BASE_CORE_CPUP == 1)
OsGetAllTskCpupInfo(CPUP_INFO_S ** cpuLessOneSec,CPUP_INFO_S ** cpuTenSec,CPUP_INFO_S ** cpuOneSec)253 LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskCpupInfo(CPUP_INFO_S **cpuLessOneSec,
254                                                   CPUP_INFO_S **cpuTenSec,
255                                                   CPUP_INFO_S **cpuOneSec)
256 {
257     if ((cpuLessOneSec == NULL) || (cpuTenSec == NULL) || (cpuOneSec == NULL)) {
258         return OS_ERROR;
259     }
260     *cpuLessOneSec = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_taskMaxNum);
261     if (*cpuLessOneSec == NULL) {
262         PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__);
263         return OS_ERROR;
264     }
265     // Ignore the return code when matching CSEC rule 6.6(3).
266     (VOID)memset_s((VOID *)(*cpuLessOneSec), sizeof(CPUP_INFO_S) * g_taskMaxNum,
267                    (INT32)0, sizeof(CPUP_INFO_S) * g_taskMaxNum);
268 
269     *cpuTenSec = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_taskMaxNum);
270     if (*cpuTenSec == NULL) {
271         PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__);
272         (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, *cpuLessOneSec);
273         *cpuLessOneSec = NULL;
274         return OS_ERROR;
275     }
276     // Ignore the return code when matching CSEC rule 6.6(3).
277     (VOID)memset_s((VOID *)(*cpuTenSec), sizeof(CPUP_INFO_S) * g_taskMaxNum,
278                    (INT32)0, sizeof(CPUP_INFO_S) * g_taskMaxNum);
279 
280     *cpuOneSec = (CPUP_INFO_S *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(CPUP_INFO_S) * g_taskMaxNum);
281     if (*cpuOneSec == NULL) {
282         PRINT_ERR("%s[%d] malloc failure!\n", __FUNCTION__, __LINE__);
283         (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, *cpuLessOneSec);
284         (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, *cpuTenSec);
285         return OS_ERROR;
286     }
287     // Ignore the return code when matching CSEC rule 6.6(3).
288     (VOID)memset_s((VOID *)(*cpuOneSec), sizeof(CPUP_INFO_S) * g_taskMaxNum,
289                    (INT32)0, sizeof(CPUP_INFO_S) * g_taskMaxNum);
290 
291     LOS_TaskLock();
292     (VOID)LOS_AllTaskCpuUsage(*cpuLessOneSec, CPUP_LESS_THAN_1S);
293     (VOID)LOS_AllTaskCpuUsage(*cpuTenSec, CPUP_IN_10S);
294     (VOID)LOS_AllTaskCpuUsage(*cpuOneSec, CPUP_IN_1S);
295     LOS_TaskUnlock();
296 
297     return LOS_OK;
298 }
299 #endif
300 
OsPrintAllTskInfoHeader(VOID)301 LITE_OS_SEC_TEXT_MINOR VOID OsPrintAllTskInfoHeader(VOID)
302 {
303     PRINTK("\r\n TID  Priority   Status StackSize WaterLine StackPoint TopOfStack EventMask  SemID");
304 #if (LOSCFG_BASE_CORE_CPUP == 1)
305     PRINTK("  CPUUSE CPUUSE10s CPUUSE1s ");
306 #endif /* LOSCFG_BASE_CORE_CPUP */
307     PRINTK("  TaskEntry name\n");
308     PRINTK(" ---  -------- -------- ");
309     PRINTK("--------- --------- ---------- ---------- --------- ------ ");
310 #if (LOSCFG_BASE_CORE_CPUP == 1)
311     PRINTK("------- --------- --------  ");
312 #endif /* LOSCFG_BASE_CORE_CPUP */
313     PRINTK("---------- ----\n");
314 }
315 
316 /*****************************************************************************
317  Function    : OsGetAllTskInfo
318  Description : Get all task info.
319  Input       : None
320  Output      : None
321  Return      : None
322  *****************************************************************************/
OsGetAllTskInfo(VOID)323 LITE_OS_SEC_TEXT_MINOR UINT32 OsGetAllTskInfo(VOID)
324 {
325 #if (LOSCFG_KERNEL_PRINTF != 0)
326     LosTaskCB    *taskCB = (LosTaskCB *)NULL;
327     UINT32       loopNum;
328     UINT32       semID;
329 #if (LOSCFG_BASE_CORE_CPUP == 1)
330     CPUP_INFO_S *cpuLessOneSec = (CPUP_INFO_S *)NULL;
331     CPUP_INFO_S *cpuTenSec = (CPUP_INFO_S *)NULL;
332     CPUP_INFO_S *cpuOneSec = (CPUP_INFO_S *)NULL;
333 #endif
334 
335 #if (LOSCFG_BASE_CORE_CPUP == 1)
336     if (OsGetAllTskCpupInfo(&cpuLessOneSec, &cpuTenSec, &cpuOneSec) != LOS_OK) {
337         return OS_ERROR;
338     }
339 #endif
340 
341     OsPrintAllTskInfoHeader();
342 
343     for (loopNum = 0; loopNum < g_taskMaxNum; loopNum++) {
344         taskCB = (((LosTaskCB *)g_taskCBArray) + loopNum);
345         if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
346             continue;
347         }
348 
349         semID = (taskCB->taskSem == NULL) ? OS_NULL_SHORT : (((LosSemCB *)taskCB->taskSem)->semID);
350         PRINTK("%4u%9u%10s%#10x%#10x%#11x%#11x%#10x%#7x",
351                taskCB->taskID, taskCB->priority, OsConvertTskStatus(taskCB->taskStatus),
352                taskCB->stackSize, OsGetTaskWaterLine(taskCB->taskID),
353                (UINT32)(UINTPTR)taskCB->stackPointer, taskCB->topOfStack, taskCB->eventMask, semID);
354 
355 #if (LOSCFG_BASE_CORE_CPUP == 1)
356         PRINTK("%6u.%-2u%7u.%-2u%6u.%-2u ",
357                cpuLessOneSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT,
358                cpuLessOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT,
359                cpuTenSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT,
360                cpuTenSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT,
361                cpuOneSec[taskCB->taskID].uwUsage / LOS_CPUP_PRECISION_MULT,
362                cpuOneSec[taskCB->taskID].uwUsage % LOS_CPUP_PRECISION_MULT);
363 #endif /* LOSCFG_BASE_CORE_CPUP */
364         PRINTK("%#10x %-32s\n", (UINT32)(UINTPTR)taskCB->taskEntry, taskCB->taskName);
365     }
366 
367 #if (LOSCFG_BASE_CORE_CPUP == 1)
368     (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuLessOneSec);
369     (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuTenSec);
370     (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, cpuOneSec);
371 #endif
372 #endif
373     return LOS_OK;
374 }
375 
376 /*****************************************************************************
377  Function    : OsTaskInit
378  Description : Task init function.
379  Input       : None
380  Output      : None
381  Return      : LOS_OK on success or error code on failure
382  *****************************************************************************/
OsTaskInit(VOID)383 LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
384 {
385     UINT32 size;
386     UINT32 index;
387 
388     size = (g_taskMaxNum + 1) * sizeof(LosTaskCB);
389     g_taskCBArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem0, size);
390     if (g_taskCBArray == NULL) {
391         return LOS_ERRNO_TSK_NO_MEMORY;
392     }
393 
394     // Ignore the return code when matching CSEC rule 6.6(1).
395     (VOID)memset_s(g_taskCBArray, size, 0, size);
396     LOS_ListInit(&g_losFreeTask);
397     LOS_ListInit(&g_taskRecycleList);
398     for (index = 0; index <= LOSCFG_BASE_CORE_TSK_LIMIT; index++) {
399         g_taskCBArray[index].taskStatus = OS_TASK_STATUS_UNUSED;
400         g_taskCBArray[index].taskID = index;
401         LOS_ListTailInsert(&g_losFreeTask, &g_taskCBArray[index].pendList);
402     }
403 
404     // Ignore the return code when matching CSEC rule 6.6(4).
405     (VOID)memset_s((VOID *)(&g_losTask), sizeof(g_losTask), 0, sizeof(g_losTask));
406     g_losTask.runTask = &g_taskCBArray[g_taskMaxNum];
407     g_losTask.runTask->taskID = index;
408     g_losTask.runTask->taskStatus = (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_RUNNING);
409     g_losTask.runTask->priority = OS_TASK_PRIORITY_LOWEST + 1;
410 
411     g_idleTaskID = OS_INVALID;
412     return OsSchedInit();
413 }
414 
415 
416 /*****************************************************************************
417  Function    : OsIdleTaskCreate
418  Description : Create idle task.
419  Input       : None
420  Output      : None
421  Return      : LOS_OK on success or error code on failure
422  *****************************************************************************/
OsIdleTaskCreate(VOID)423 LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
424 {
425     UINT32 retVal;
426     TSK_INIT_PARAM_S taskInitParam;
427     // Ignore the return code when matching CSEC rule 6.6(4).
428     (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
429     taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;
430     taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE;
431     taskInitParam.pcName = "IdleCore000";
432     taskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST;
433     retVal = LOS_TaskCreateOnly(&g_idleTaskID, &taskInitParam);
434     if (retVal != LOS_OK) {
435         return retVal;
436     }
437 
438     OsSchedSetIdleTaskSchedParam(OS_TCB_FROM_TID(g_idleTaskID));
439     return LOS_OK;
440 }
441 
442 /*****************************************************************************
443  Function    : LOS_CurTaskIDGet
444  Description : get id of current running task.
445  Input       : None
446  Output      : None
447  Return      : task id
448  *****************************************************************************/
LOS_CurTaskIDGet(VOID)449 LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
450 {
451     if (g_losTask.runTask == NULL) {
452         return LOS_ERRNO_TSK_ID_INVALID;
453     }
454     return g_losTask.runTask->taskID;
455 }
456 
457 /*****************************************************************************
458  Function    : LOS_NextTaskIDGet
459  Description : get id of next running task.
460  Input       : None
461  Output      : None
462  Return      : task id
463  *****************************************************************************/
LOS_NextTaskIDGet(VOID)464 LITE_OS_SEC_TEXT UINT32 LOS_NextTaskIDGet(VOID)
465 {
466     UINT32 intSave = LOS_IntLock();
467     UINT32 taskID = OsGetTopTask()->taskID;
468     LOS_IntRestore(intSave);
469 
470     return taskID;
471 }
472 
473 /*****************************************************************************
474  Function    : LOS_CurTaskNameGet
475  Description : get name of current running task.
476  Input       : None
477  Output      : None
478  Return      : task name
479  *****************************************************************************/
LOS_CurTaskNameGet(VOID)480 LITE_OS_SEC_TEXT CHAR *LOS_CurTaskNameGet(VOID)
481 {
482     CHAR *taskName = NULL;
483 
484     if (g_losTask.runTask != NULL) {
485         taskName = g_losTask.runTask->taskName;
486     }
487 
488     return taskName;
489 }
490 
491 #if (LOSCFG_BASE_CORE_TSK_MONITOR == 1)
492 #if (LOSCFG_EXC_HARDWARE_STACK_PROTECTION == 0)
493 /*****************************************************************************
494  Function    : OsHandleRunTaskStackOverflow
495  Description : handle stack overflow exception of the run task.
496  Input       : None
497  Output      : None
498  Return      : None
499  *****************************************************************************/
OsHandleRunTaskStackOverflow(VOID)500 LITE_OS_SEC_TEXT STATIC VOID OsHandleRunTaskStackOverflow(VOID)
501 {
502     PRINT_ERR("CURRENT task ID: %s:%d stack overflow!\n",
503               g_losTask.runTask->taskName, g_losTask.runTask->taskID);
504     OsDoExcHook(EXC_STACKOVERFLOW);
505 }
506 
507 /*****************************************************************************
508  Function    : OsHandleNewTaskStackOverflow
509  Description : handle stack overflow exception of the new task.
510  Input       : None
511  Output      : None
512  Return      : None
513  *****************************************************************************/
OsHandleNewTaskStackOverflow(VOID)514 LITE_OS_SEC_TEXT STATIC VOID OsHandleNewTaskStackOverflow(VOID)
515 {
516     LosTaskCB *tmp = NULL;
517 
518     PRINT_ERR("HIGHEST task ID: %s:%d SP error!\n",
519               g_losTask.newTask->taskName, g_losTask.newTask->taskID);
520     PRINT_ERR("HIGHEST task StackPointer: 0x%x TopOfStack: 0x%x\n",
521               (UINT32)(UINTPTR)(g_losTask.newTask->stackPointer), g_losTask.newTask->topOfStack);
522 
523     /*
524      * make sure LOS_CurTaskIDGet and LOS_CurTaskNameGet returns the ID and name of which task
525      * that occurred stack overflow exception in OsDoExcHook temporary.
526      */
527     tmp = g_losTask.runTask;
528     g_losTask.runTask = g_losTask.newTask;
529     OsDoExcHook(EXC_STACKOVERFLOW);
530     g_losTask.runTask = tmp;
531 }
532 #else
OsTaskStackProtect(VOID)533 LITE_OS_SEC_TEXT STATIC VOID OsTaskStackProtect(VOID)
534 {
535     MPU_CFG_PARA mpuAttr = {0};
536     STATIC INT32 id = -1;
537 
538     if (id == -1) {
539         id = ArchMpuUnusedRegionGet();
540         if (id < 0) {
541             PRINT_ERR("%s %d, get unused id failed!\n", __FUNCTION__, __LINE__);
542             return;
543         }
544     }
545 
546     mpuAttr.baseAddr = g_losTask.newTask->topOfStack - OS_TASK_STACK_PROTECT_SIZE;
547     mpuAttr.size = OS_TASK_STACK_PROTECT_SIZE;
548     mpuAttr.memType = MPU_MEM_ON_CHIP_RAM;
549     mpuAttr.executable = MPU_NON_EXECUTABLE;
550     mpuAttr.shareability = MPU_NO_SHARE;
551     mpuAttr.permission = MPU_RO_BY_PRIVILEGED_ONLY;
552 
553     ArchMpuDisable();
554     (VOID)ArchMpuDisableRegion(id);
555     (VOID)ArchMpuSetRegion(id, &mpuAttr);
556     ArchMpuEnable(1);
557 }
558 #endif
559 #endif
560 
561 /*****************************************************************************
562  Function    : OsTaskSwitchCheck
563  Description : Check task switch
564  Input       : Node
565  Output      : None
566  Return      : None
567  *****************************************************************************/
568 #if (LOSCFG_BASE_CORE_TSK_MONITOR == 1)
OsTaskSwitchCheck(VOID)569 LITE_OS_SEC_TEXT VOID OsTaskSwitchCheck(VOID)
570 {
571     UINT32 intSave = LOS_IntLock();
572 #if (LOSCFG_EXC_HARDWARE_STACK_PROTECTION == 0)
573     UINT32 endOfStack = g_losTask.newTask->topOfStack + g_losTask.newTask->stackSize;
574 
575     if ((*(UINT32 *)(UINTPTR)(g_losTask.runTask->topOfStack)) != OS_TASK_MAGIC_WORD) {
576         OsHandleRunTaskStackOverflow();
577     }
578     if (((UINT32)(UINTPTR)(g_losTask.newTask->stackPointer) <= (g_losTask.newTask->topOfStack)) ||
579         ((UINT32)(UINTPTR)(g_losTask.newTask->stackPointer) > endOfStack)) {
580         OsHandleNewTaskStackOverflow();
581     }
582 #else
583     OsTaskStackProtect();
584 #endif
585 
586 #if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
587     /* record task switch info */
588     g_taskSwitchInfo.pid[g_taskSwitchInfo.idx] = (UINT16)(g_losTask.newTask->taskID);
589 
590     errno_t ret = memcpy_s(g_taskSwitchInfo.name[g_taskSwitchInfo.idx], LOS_TASK_NAMELEN,
591                            g_losTask.newTask->taskName, LOS_TASK_NAMELEN);
592     if (ret != EOK) {
593         PRINT_ERR("exc task switch copy file name failed!\n");
594     }
595     g_taskSwitchInfo.name[g_taskSwitchInfo.idx][LOS_TASK_NAMELEN - 1] = '\0';
596 
597     if (++g_taskSwitchInfo.idx == OS_TASK_SWITCH_INFO_COUNT) {
598         g_taskSwitchInfo.idx = 0;
599         g_taskSwitchInfo.cntInfo.isFull = TRUE;
600     }
601 #endif
602 
603     LOSCFG_BASE_CORE_TSK_SWITCH_HOOK();
604 
605 #if (LOSCFG_BASE_CORE_CPUP == 1)
606     OsTskCycleEndStart();
607 #endif /* LOSCFG_BASE_CORE_CPUP */
608     LOS_IntRestore(intSave);
609 }
610 
OsTaskMonInit(VOID)611 LITE_OS_SEC_TEXT_MINOR VOID OsTaskMonInit(VOID)
612 {
613 #if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
614     // Ignore the return code when matching CSEC rule 6.6(4).
615     (VOID)memset_s(&g_taskSwitchInfo, sizeof(TaskSwitchInfo), 0, sizeof(TaskSwitchInfo));
616     g_taskSwitchInfo.cntInfo.maxCnt = OS_TASK_SWITCH_INFO_COUNT;
617 #endif
618     return;
619 }
620 #endif
621 
622 /*****************************************************************************
623  Function    : OsTaskEntry
624  Description : All task entry
625  Input       : taskID     --- The ID of the task to be run
626  Output      : None
627  Return      : None
628  *****************************************************************************/
OsTaskEntry(UINT32 taskID)629 LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID)
630 {
631     UINT32 retVal;
632     LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
633 
634     taskCB->joinRetval = (UINTPTR)taskCB->taskEntry(taskCB->arg);
635     retVal = LOS_TaskDelete(taskCB->taskID);
636     if (retVal != LOS_OK) {
637         PRINT_ERR("Delete Task[TID: %d] Failed!\n", taskCB->taskID);
638     }
639 }
640 
OsTaskInitParamCheck(TSK_INIT_PARAM_S * taskInitParam)641 LITE_OS_SEC_TEXT_INIT STATIC_INLINE UINT32 OsTaskInitParamCheck(TSK_INIT_PARAM_S *taskInitParam)
642 {
643     if (taskInitParam == NULL) {
644         return LOS_ERRNO_TSK_PTR_NULL;
645     }
646 
647     if (taskInitParam->pcName == NULL) {
648         return LOS_ERRNO_TSK_NAME_EMPTY;
649     }
650 
651     if (taskInitParam->pfnTaskEntry == NULL) {
652         return LOS_ERRNO_TSK_ENTRY_NULL;
653     }
654 
655     if ((taskInitParam->usTaskPrio) > OS_TASK_PRIORITY_LOWEST) {
656         return LOS_ERRNO_TSK_PRIOR_ERROR;
657     }
658 
659     if (((taskInitParam->usTaskPrio) == OS_TASK_PRIORITY_LOWEST)
660         && (taskInitParam->pfnTaskEntry != OS_IDLE_TASK_ENTRY)) {
661         return LOS_ERRNO_TSK_PRIOR_ERROR;
662     }
663 
664     if (taskInitParam->uwStackSize > LOSCFG_SYS_HEAP_SIZE) {
665         return LOS_ERRNO_TSK_STKSZ_TOO_LARGE;
666     }
667 
668     if (taskInitParam->uwStackSize == 0) {
669         taskInitParam->uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
670     }
671 
672     if (taskInitParam->uwStackSize < LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE) {
673         return LOS_ERRNO_TSK_STKSZ_TOO_SMALL;
674     }
675     return LOS_OK;
676 }
677 
OsNewTaskInit(LosTaskCB * taskCB,TSK_INIT_PARAM_S * taskInitParam)678 STATIC UINT32 OsNewTaskInit(LosTaskCB *taskCB, TSK_INIT_PARAM_S *taskInitParam)
679 {
680     taskCB->arg             = taskInitParam->uwArg;
681     taskCB->stackSize       = taskInitParam->uwStackSize;
682     taskCB->taskSem         = NULL;
683     taskCB->taskMux         = NULL;
684     taskCB->taskStatus      = OS_TASK_STATUS_SUSPEND;
685     taskCB->priority        = taskInitParam->usTaskPrio;
686     taskCB->timeSlice       = 0;
687     taskCB->waitTimes       = 0;
688     taskCB->taskEntry       = taskInitParam->pfnTaskEntry;
689     taskCB->event.uwEventID = OS_NULL_INT;
690     taskCB->eventMask       = 0;
691     taskCB->taskName        = taskInitParam->pcName;
692     taskCB->msg             = NULL;
693 #if (LOSCFG_KERNEL_SIGNAL == 1)
694     taskCB->sig             = NULL;
695 #endif
696 
697     SET_SORTLIST_VALUE(&taskCB->sortList, OS_SORT_LINK_INVALID_TIME);
698     LOS_EventInit(&(taskCB->event));
699 
700     if (taskInitParam->uwResved & LOS_TASK_ATTR_JOINABLE) {
701         taskCB->taskStatus |= OS_TASK_FLAG_JOINABLE;
702         LOS_ListInit(&taskCB->joinList);
703     }
704 
705     if (taskInitParam->stackAddr == (UINTPTR)NULL) {
706         taskCB->stackSize = ALIGN(taskInitParam->uwStackSize, OS_TASK_STACK_ADDR_ALIGN);
707 #if (LOSCFG_EXC_HARDWARE_STACK_PROTECTION == 1)
708         UINT32 stackSize = taskCB->stackSize + OS_TASK_STACK_PROTECT_SIZE;
709         UINTPTR stackPtr = (UINTPTR)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, stackSize, OS_TASK_STACK_PROTECT_SIZE);
710         taskCB->topOfStack = stackPtr + OS_TASK_STACK_PROTECT_SIZE;
711 #else
712         taskCB->topOfStack = (UINTPTR)LOS_MemAllocAlign(OS_TASK_STACK_ADDR, taskCB->stackSize,
713                                                         LOSCFG_STACK_POINT_ALIGN_SIZE);
714 #endif
715         if (taskCB->topOfStack == (UINTPTR)NULL) {
716             return LOS_ERRNO_TSK_NO_MEMORY;
717         }
718         taskCB->taskStatus |= OS_TASK_FLAG_STACK_FREE;
719     } else {
720         taskCB->topOfStack = LOS_Align(taskInitParam->stackAddr, LOSCFG_STACK_POINT_ALIGN_SIZE);
721         taskCB->stackSize = taskInitParam->uwStackSize - (taskCB->topOfStack - taskInitParam->stackAddr);
722         taskCB->stackSize = TRUNCATE(taskCB->stackSize, OS_TASK_STACK_ADDR_ALIGN);
723     }
724 
725     /* initialize the task stack, write magic num to stack top */
726     (VOID)memset_s((VOID *)taskCB->topOfStack, taskCB->stackSize,
727                    (INT32)(OS_TASK_STACK_INIT & 0xFF), taskCB->stackSize);
728 
729     *((UINT32 *)taskCB->topOfStack) = OS_TASK_MAGIC_WORD;
730     taskCB->stackPointer = ArchTskStackInit(taskCB->taskID, taskCB->stackSize, (VOID *)taskCB->topOfStack);
731     return LOS_OK;
732 }
733 
734 /*****************************************************************************
735  Function    : LOS_TaskCreateOnly
736  Description : Create a task and suspend
737  Input       : taskInitParam --- Task init parameters
738  Output      : taskID        --- Save task ID
739  Return      : LOS_OK on success or error code on failure
740  *****************************************************************************/
LOS_TaskCreateOnly(UINT32 * taskID,TSK_INIT_PARAM_S * taskInitParam)741 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam)
742 {
743     UINT32 intSave;
744     LosTaskCB *taskCB = NULL;
745     UINT32 retVal;
746 
747     if (taskID == NULL) {
748         return LOS_ERRNO_TSK_ID_INVALID;
749     }
750 
751     retVal = OsTaskInitParamCheck(taskInitParam);
752     if (retVal != LOS_OK) {
753         return retVal;
754     }
755 
756     OsRecyleFinishedTask();
757 
758     intSave = LOS_IntLock();
759     if (LOS_ListEmpty(&g_losFreeTask)) {
760         LOS_IntRestore(intSave);
761         return LOS_ERRNO_TSK_TCB_UNAVAILABLE;
762     }
763 
764     taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&g_losFreeTask));
765     LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));
766     LOS_IntRestore(intSave);
767 
768     retVal = OsNewTaskInit(taskCB, taskInitParam);
769     if (retVal != LOS_OK) {
770         intSave = LOS_IntLock();
771         OsInsertTCBToFreeList(taskCB);
772         LOS_IntRestore(intSave);
773         return retVal;
774     }
775 
776     LOSCFG_TASK_CREATE_EXTENSION_HOOK(taskCB);
777 
778 #if (LOSCFG_BASE_CORE_CPUP == 1)
779     intSave = LOS_IntLock();
780     g_cpup[taskCB->taskID].cpupID = taskCB->taskID;
781     g_cpup[taskCB->taskID].status = taskCB->taskStatus;
782     LOS_IntRestore(intSave);
783 #endif
784     *taskID = taskCB->taskID;
785     OsHookCall(LOS_HOOK_TYPE_TASK_CREATE, taskCB);
786     return retVal;
787 }
788 
789 /*****************************************************************************
790  Function    : LOS_TaskCreate
791  Description : Create a task
792  Input       : taskInitParam --- Task init parameters
793  Output      : taskID        --- Save task ID
794  Return      : LOS_OK on success or error code on failure
795  *****************************************************************************/
LOS_TaskCreate(UINT32 * taskID,TSK_INIT_PARAM_S * taskInitParam)796 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *taskInitParam)
797 {
798     UINT32 retVal;
799     UINT32 intSave;
800     LosTaskCB *taskCB = NULL;
801 
802     retVal = LOS_TaskCreateOnly(taskID, taskInitParam);
803     if (retVal != LOS_OK) {
804         return retVal;
805     }
806     taskCB = OS_TCB_FROM_TID(*taskID);
807 
808     intSave = LOS_IntLock();
809 
810     OsSchedTaskEnQueue(taskCB);
811     LOS_IntRestore(intSave);
812 
813     if (g_taskScheduled) {
814         LOS_Schedule();
815     }
816 
817     return LOS_OK;
818 }
819 
820 /*****************************************************************************
821  Function    : LOS_TaskResume
822  Description : Resume suspend task
823  Input       : taskID --- Task ID
824  Output      : None
825  Return      : LOS_OK on success or error code on failure
826  *****************************************************************************/
LOS_TaskResume(UINT32 taskID)827 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID)
828 {
829     UINT32 intSave;
830     LosTaskCB *taskCB = NULL;
831     UINT16 tempStatus;
832     UINT32 retErr = OS_ERROR;
833     BOOL needSched = FALSE;
834 
835     if (taskID > LOSCFG_BASE_CORE_TSK_LIMIT) {
836         return LOS_ERRNO_TSK_ID_INVALID;
837     }
838 
839     taskCB = OS_TCB_FROM_TID(taskID);
840     intSave = LOS_IntLock();
841     tempStatus = taskCB->taskStatus;
842 
843     if (tempStatus & OS_TASK_STATUS_UNUSED) {
844         retErr = LOS_ERRNO_TSK_NOT_CREATED;
845         OS_GOTO_ERREND();
846     } else if (!(tempStatus & OS_TASK_STATUS_SUSPEND)) {
847         retErr = LOS_ERRNO_TSK_NOT_SUSPENDED;
848         OS_GOTO_ERREND();
849     }
850 
851     needSched = OsSchedResume(taskCB);
852     if (needSched && g_taskScheduled) {
853         LOS_IntRestore(intSave);
854         LOS_Schedule();
855         return LOS_OK;
856     }
857 
858     LOS_IntRestore(intSave);
859     return LOS_OK;
860 
861 LOS_ERREND:
862     LOS_IntRestore(intSave);
863     return retErr;
864 }
865 
866 /*****************************************************************************
867  Function    : LOS_TaskSuspend
868  Description : Suspend task
869  Input       : taskID --- Task ID
870  Output      : None
871  Return      : LOS_OK on success or error code on failure
872  *****************************************************************************/
LOS_TaskSuspend(UINT32 taskID)873 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskID)
874 {
875     UINT32 intSave;
876     LosTaskCB *taskCB = NULL;
877     UINT16 tempStatus;
878     UINT32 retErr;
879 
880     retErr = OsCheckTaskIDValid(taskID);
881     if (retErr != LOS_OK) {
882         return retErr;
883     }
884 
885     taskCB = OS_TCB_FROM_TID(taskID);
886     intSave = LOS_IntLock();
887     tempStatus = taskCB->taskStatus;
888 
889     if (tempStatus & OS_TASK_STATUS_UNUSED) {
890         retErr = LOS_ERRNO_TSK_NOT_CREATED;
891         OS_GOTO_ERREND();
892     }
893 
894     if (tempStatus & OS_TASK_FLAG_SYSTEM_TASK) {
895         retErr = LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
896         OS_GOTO_ERREND();
897     }
898 
899     if (tempStatus & OS_TASK_STATUS_SUSPEND) {
900         retErr = LOS_ERRNO_TSK_ALREADY_SUSPENDED;
901         OS_GOTO_ERREND();
902     }
903 
904     if ((tempStatus & OS_TASK_STATUS_RUNNING) && (g_losTaskLock != 0)) {
905         retErr = LOS_ERRNO_TSK_SUSPEND_LOCKED;
906         OS_GOTO_ERREND();
907     }
908 
909     OsSchedSuspend(taskCB);
910 
911     if (taskID == g_losTask.runTask->taskID) {
912         LOS_IntRestore(intSave);
913         LOS_Schedule();
914         return LOS_OK;
915     }
916 
917     LOS_IntRestore(intSave);
918     return LOS_OK;
919 
920 LOS_ERREND:
921     LOS_IntRestore(intSave);
922     return retErr;
923 }
924 
OsTaskJoinPostUnsafe(LosTaskCB * taskCB)925 STATIC VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB)
926 {
927     LosTaskCB *resumedTask = NULL;
928 
929     if (taskCB->taskStatus & OS_TASK_FLAG_JOINABLE) {
930         if (!LOS_ListEmpty(&taskCB->joinList)) {
931             resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(taskCB->joinList)));
932             OsSchedTaskWake(resumedTask);
933         }
934         taskCB->taskStatus |= OS_TASK_STATUS_EXIT;
935     }
936 }
937 
OsTaskJoinPendUnsafe(LosTaskCB * taskCB)938 STATIC UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB)
939 {
940     if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) {
941         return LOS_OK;
942     } else if ((taskCB->taskStatus & OS_TASK_FLAG_JOINABLE) && LOS_ListEmpty(&taskCB->joinList)) {
943         OsSchedTaskWait(&taskCB->joinList, LOS_WAIT_FOREVER);
944         return LOS_OK;
945     }
946 
947     return LOS_NOK;
948 }
949 
OsTaskSetDetachUnsafe(LosTaskCB * taskCB)950 STATIC UINT32 OsTaskSetDetachUnsafe(LosTaskCB *taskCB)
951 {
952     if (taskCB->taskStatus & OS_TASK_FLAG_JOINABLE) {
953         if (LOS_ListEmpty(&(taskCB->joinList))) {
954             LOS_ListDelete(&(taskCB->joinList));
955             taskCB->taskStatus &= ~OS_TASK_FLAG_JOINABLE;
956             return LOS_OK;
957         }
958         /* This error code has a special purpose and is not allowed to appear again on the interface */
959         return LOS_ERRNO_TSK_NOT_JOIN;
960     }
961 
962     return LOS_NOK;
963 }
964 
LOS_TaskJoin(UINT32 taskID,UINTPTR * retval)965 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskJoin(UINT32 taskID, UINTPTR *retval)
966 {
967     LosTaskCB *taskCB = NULL;
968     UINTPTR stackPtr = 0;
969     UINT32 intSave;
970     UINT32 ret;
971 
972     ret = OsCheckTaskIDValid(taskID);
973     if (ret != LOS_OK) {
974         return ret;
975     }
976 
977     if (OS_INT_ACTIVE) {
978         return LOS_ERRNO_TSK_NOT_ALLOW_IN_INT;
979     }
980 
981     if (g_losTaskLock != 0) {
982         return LOS_ERRNO_TSK_SCHED_LOCKED;
983     }
984 
985     if (taskID == LOS_CurTaskIDGet()) {
986         return LOS_ERRNO_TSK_NOT_JOIN_SELF;
987     }
988 
989     taskCB = OS_TCB_FROM_TID(taskID);
990     intSave = LOS_IntLock();
991     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
992         LOS_IntRestore(intSave);
993         return LOS_ERRNO_TSK_NOT_CREATED;
994     }
995 
996     ret = OsTaskJoinPendUnsafe(taskCB);
997     LOS_IntRestore(intSave);
998     if (ret == LOS_OK) {
999         LOS_Schedule();
1000 
1001         if (retval != NULL) {
1002             *retval = taskCB->joinRetval;
1003         }
1004 
1005         intSave = LOS_IntLock();
1006         taskCB->taskStatus &= ~OS_TASK_STATUS_EXIT;
1007         OsRecycleTaskResources(taskCB, &stackPtr);
1008         LOS_IntRestore(intSave);
1009         (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)stackPtr);
1010         return LOS_OK;
1011     }
1012 
1013     return ret;
1014 }
1015 
LOS_TaskDetach(UINT32 taskID)1016 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDetach(UINT32 taskID)
1017 {
1018     UINT32 intSave;
1019     UINT32 ret;
1020     LosTaskCB *taskCB = NULL;
1021 
1022     ret = OsCheckTaskIDValid(taskID);
1023     if (ret != LOS_OK) {
1024         return ret;
1025     }
1026 
1027     if (OS_INT_ACTIVE) {
1028         return LOS_ERRNO_TSK_NOT_ALLOW_IN_INT;
1029     }
1030 
1031     taskCB = OS_TCB_FROM_TID(taskID);
1032     intSave = LOS_IntLock();
1033     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1034         LOS_IntRestore(intSave);
1035         return LOS_ERRNO_TSK_NOT_CREATED;
1036     }
1037 
1038     if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) {
1039         LOS_IntRestore(intSave);
1040         return LOS_TaskJoin(taskID, NULL);
1041     }
1042 
1043     ret = OsTaskSetDetachUnsafe(taskCB);
1044     LOS_IntRestore(intSave);
1045     return ret;
1046 }
1047 
OsRunningTaskDelete(UINT32 taskID,LosTaskCB * taskCB)1048 LITE_OS_SEC_TEXT_INIT STATIC_INLINE VOID OsRunningTaskDelete(UINT32 taskID, LosTaskCB *taskCB)
1049 {
1050     LOS_ListTailInsert(&g_taskRecycleList, &taskCB->pendList);
1051     g_losTask.runTask = &g_taskCBArray[g_taskMaxNum];
1052     g_losTask.runTask->taskID = taskID;
1053     g_losTask.runTask->taskStatus = taskCB->taskStatus | OS_TASK_STATUS_RUNNING;
1054     g_losTask.runTask->topOfStack = taskCB->topOfStack;
1055     g_losTask.runTask->taskName = taskCB->taskName;
1056 }
1057 /*****************************************************************************
1058  Function    : LOS_TaskDelete
1059  Description : Delete a task
1060  Input       : taskID --- Task ID
1061  Output      : None
1062  Return      : LOS_OK on success or error code on failure
1063  *****************************************************************************/
LOS_TaskDelete(UINT32 taskID)1064 LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskID)
1065 {
1066     UINT32 intSave;
1067     UINTPTR stackPtr = 0;
1068     LosTaskCB *taskCB = NULL;
1069 
1070     UINT32 ret = OsCheckTaskIDValid(taskID);
1071     if (ret != LOS_OK) {
1072         return ret;
1073     }
1074 
1075     taskCB = OS_TCB_FROM_TID(taskID);
1076     intSave = LOS_IntLock();
1077     if (taskCB->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1078         LOS_IntRestore(intSave);
1079         return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
1080     }
1081 
1082     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1083         LOS_IntRestore(intSave);
1084         return LOS_ERRNO_TSK_NOT_CREATED;
1085     }
1086 
1087     if (taskCB->taskStatus & OS_TASK_STATUS_EXIT) {
1088         LOS_IntRestore(intSave);
1089         return LOS_ERRNO_TSK_ALREADY_EXIT;
1090     }
1091 
1092     if (taskCB->taskStatus & OS_TASK_FLAG_SIGNAL) {
1093         LOS_IntRestore(intSave);
1094         return LOS_ERRNO_TSK_PROCESS_SIGNAL;
1095     }
1096 
1097     /* If the task is running and scheduler is locked then you can not delete it */
1098     if (((taskCB->taskStatus) & OS_TASK_STATUS_RUNNING) && (g_losTaskLock != 0)) {
1099         PRINT_INFO("In case of task lock, task deletion is not recommended\n");
1100         g_losTaskLock = 0;
1101     }
1102 
1103     OsHookCall(LOS_HOOK_TYPE_TASK_DELETE, taskCB);
1104     OsSchedTaskExit(taskCB);
1105     OsTaskJoinPostUnsafe(taskCB);
1106 
1107     LOS_EventDestroy(&(taskCB->event));
1108     taskCB->event.uwEventID = OS_NULL_INT;
1109     taskCB->eventMask = 0;
1110 #if (LOSCFG_BASE_CORE_CPUP == 1)
1111     // Ignore the return code when matching CSEC rule 6.6(4).
1112     (VOID)memset_s((VOID *)&g_cpup[taskCB->taskID], sizeof(OsCpupCB), 0, sizeof(OsCpupCB));
1113 #endif
1114 
1115 #if (LOSCFG_KERNEL_SIGNAL == 1)
1116     if (taskCB->sig != NULL) {
1117         LOS_MemFree(OS_SYS_MEM_ADDR, taskCB->sig);
1118         taskCB->sig = NULL;
1119     }
1120 #endif
1121 
1122     LOSCFG_TASK_DELETE_EXTENSION_HOOK(taskCB);
1123 
1124     if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
1125         if (!(taskCB->taskStatus & OS_TASK_STATUS_EXIT)) {
1126             taskCB->taskStatus |= OS_TASK_STATUS_UNUSED;
1127             OsRunningTaskDelete(taskID, taskCB);
1128         }
1129         LOS_IntRestore(intSave);
1130         LOS_Schedule();
1131         return LOS_OK;
1132     }
1133 
1134     taskCB->joinRetval = LOS_CurTaskIDGet();
1135     OsRecycleTaskResources(taskCB, &stackPtr);
1136     LOS_IntRestore(intSave);
1137     (VOID)LOS_MemFree(OS_TASK_STACK_ADDR, (VOID *)stackPtr);
1138     return LOS_OK;
1139 }
1140 
1141 /*****************************************************************************
1142  Function    : LOS_TaskDelay
1143  Description : delay the current task
1144  Input       : tick    --- time
1145  Output      : None
1146  Return      : LOS_OK on success or error code on failure
1147  *****************************************************************************/
LOS_TaskDelay(UINT32 tick)1148 LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
1149 {
1150     UINT32 intSave;
1151 
1152     if (OS_INT_ACTIVE) {
1153         return LOS_ERRNO_TSK_DELAY_IN_INT;
1154     }
1155 
1156     if (g_losTaskLock != 0) {
1157         return LOS_ERRNO_TSK_DELAY_IN_LOCK;
1158     }
1159 
1160     if (g_losTask.runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1161         return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
1162     }
1163     OsHookCall(LOS_HOOK_TYPE_TASK_DELAY, tick);
1164     if (tick == 0) {
1165         return LOS_TaskYield();
1166     } else {
1167         intSave = LOS_IntLock();
1168         OsSchedDelay(g_losTask.runTask, tick);
1169         OsHookCall(LOS_HOOK_TYPE_MOVEDTASKTODELAYEDLIST, g_losTask.runTask);
1170         LOS_IntRestore(intSave);
1171         LOS_Schedule();
1172     }
1173 
1174     return LOS_OK;
1175 }
1176 
LOS_TaskPriGet(UINT32 taskID)1177 LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskID)
1178 {
1179     UINT32 intSave;
1180     LosTaskCB *taskCB = NULL;
1181     UINT16 priority;
1182 
1183     if (OS_CHECK_TSK_PID_NOIDLE(taskID)) {
1184         return (UINT16)OS_INVALID;
1185     }
1186 
1187     taskCB = OS_TCB_FROM_TID(taskID);
1188 
1189     intSave = LOS_IntLock();
1190 
1191     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1192         LOS_IntRestore(intSave);
1193         return (UINT16)OS_INVALID;
1194     }
1195 
1196     priority = taskCB->priority;
1197     LOS_IntRestore(intSave);
1198     return priority;
1199 }
1200 
LOS_TaskPriSet(UINT32 taskID,UINT16 taskPrio)1201 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskID, UINT16 taskPrio)
1202 {
1203     BOOL isReady = FALSE;
1204     UINT32 intSave;
1205     LosTaskCB *taskCB = NULL;
1206     UINT16 tempStatus;
1207 
1208     if (taskPrio > OS_TASK_PRIORITY_LOWEST) {
1209         return LOS_ERRNO_TSK_PRIOR_ERROR;
1210     }
1211 
1212     if (taskID == g_idleTaskID) {
1213         return LOS_ERRNO_TSK_OPERATE_IDLE;
1214     }
1215 
1216     if (taskID == g_swtmrTaskID) {
1217         return LOS_ERRNO_TSK_OPERATE_SWTMR;
1218     }
1219 
1220     if (OS_CHECK_TSK_PID_NOIDLE(taskID)) {
1221         return LOS_ERRNO_TSK_ID_INVALID;
1222     }
1223 
1224     taskCB = OS_TCB_FROM_TID(taskID);
1225     intSave = LOS_IntLock();
1226     tempStatus = taskCB->taskStatus;
1227     if (tempStatus & OS_TASK_STATUS_UNUSED) {
1228         LOS_IntRestore(intSave);
1229         return LOS_ERRNO_TSK_NOT_CREATED;
1230     }
1231     if (tempStatus & OS_TASK_FLAG_SYSTEM_TASK) {
1232         LOS_IntRestore(intSave);
1233         return LOS_ERRNO_TSK_OPERATE_SYSTEM_TASK;
1234     }
1235 
1236     isReady = OsSchedModifyTaskSchedParam(taskCB, taskPrio);
1237     LOS_IntRestore(intSave);
1238     /* delete the task and insert with right priority into ready queue */
1239     if (isReady) {
1240         LOS_Schedule();
1241     }
1242 
1243     return LOS_OK;
1244 }
1245 
LOS_CurTaskPriSet(UINT16 taskPrio)1246 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
1247 {
1248     return LOS_TaskPriSet(g_losTask.runTask->taskID, taskPrio);
1249 }
1250 
1251 /*****************************************************************************
1252  Function    : LOS_TaskYield
1253  Description : Adjust the procedure order of specified task
1254  Input       : None
1255  Output      : None
1256  Return      : LOS_OK on success or error code on failure
1257  *****************************************************************************/
LOS_TaskYield(VOID)1258 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
1259 {
1260     UINT32 intSave;
1261 
1262     intSave = LOS_IntLock();
1263     OsSchedYield();
1264     LOS_IntRestore(intSave);
1265     LOS_Schedule();
1266     return LOS_OK;
1267 }
1268 
1269 /*****************************************************************************
1270  Function    : LOS_TaskLock
1271  Description : Task lock
1272  Input       : None
1273  Output      : None
1274  Return      : None
1275  *****************************************************************************/
LOS_TaskLock(VOID)1276 LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
1277 {
1278     UINT32 intSave;
1279 
1280     intSave = LOS_IntLock();
1281     g_losTaskLock++;
1282     LOS_IntRestore(intSave);
1283 }
1284 
1285 /*****************************************************************************
1286  Function    : LOS_TaskUnlock
1287  Description : Task unlock
1288  Input       : None
1289  Output      : None
1290  Return      : None
1291  *****************************************************************************/
LOS_TaskUnlock(VOID)1292 LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
1293 {
1294     UINT32 intSave;
1295 
1296     intSave = LOS_IntLock();
1297     if (g_losTaskLock > 0) {
1298         g_losTaskLock--;
1299         if (g_losTaskLock == 0) {
1300             LOS_IntRestore(intSave);
1301             LOS_Schedule();
1302             return;
1303         }
1304     }
1305 
1306     LOS_IntRestore(intSave);
1307 }
1308 
LOS_TaskInfoGet(UINT32 taskID,TSK_INFO_S * taskInfo)1309 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInfo)
1310 {
1311     UINT32 intSave;
1312     LosTaskCB *taskCB = NULL;
1313 
1314     if (taskInfo == NULL) {
1315         return LOS_ERRNO_TSK_PTR_NULL;
1316     }
1317 
1318     if (OS_CHECK_TSK_PID_NOIDLE(taskID)) {
1319         return LOS_ERRNO_TSK_ID_INVALID;
1320     }
1321 
1322     taskCB = OS_TCB_FROM_TID(taskID);
1323     intSave = LOS_IntLock();
1324 
1325     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1326         LOS_IntRestore(intSave);
1327         return LOS_ERRNO_TSK_NOT_CREATED;
1328     }
1329 
1330     taskInfo->uwSP = (UINT32)(UINTPTR)taskCB->stackPointer;
1331     taskInfo->usTaskStatus = taskCB->taskStatus;
1332     taskInfo->usTaskPrio = taskCB->priority;
1333     taskInfo->uwStackSize = taskCB->stackSize;
1334     taskInfo->uwTopOfStack = taskCB->topOfStack;
1335     taskInfo->uwEvent = taskCB->event;
1336     taskInfo->uwEventMask = taskCB->eventMask;
1337     taskInfo->uwSemID = (taskCB->taskSem != NULL) ? ((LosSemCB *)(taskCB->taskSem))->semID :
1338                         LOSCFG_BASE_IPC_SEM_LIMIT;
1339     taskInfo->uwMuxID = (taskCB->taskMux != NULL) ? ((LosMuxCB *)(taskCB->taskMux))->muxID :
1340                         LOSCFG_BASE_IPC_MUX_LIMIT;
1341     taskInfo->pTaskSem = taskCB->taskSem;
1342     taskInfo->pTaskMux = taskCB->taskMux;
1343     taskInfo->uwTaskID = taskID;
1344     // Ignore the return code when matching CSEC rule 6.6(4).
1345     (VOID)strncpy_s(taskInfo->acName, LOS_TASK_NAMELEN, taskCB->taskName, LOS_TASK_NAMELEN - 1);
1346     taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0';
1347 
1348     taskInfo->uwBottomOfStack = TRUNCATE(((UINT32)(taskCB->topOfStack) + (taskCB->stackSize)),
1349                                          OS_TASK_STACK_ADDR_ALIGN);
1350     taskInfo->uwCurrUsed = taskInfo->uwBottomOfStack - taskInfo->uwSP;
1351     taskInfo->uwPeakUsed = OsGetTaskWaterLine(taskID);
1352     taskInfo->bOvf = (taskInfo->uwPeakUsed == OS_NULL_INT) ? TRUE : FALSE;
1353     LOS_IntRestore(intSave);
1354 
1355     return LOS_OK;
1356 }
1357 
LOS_TaskStatusGet(UINT32 taskID,UINT32 * taskStatus)1358 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskStatusGet(UINT32 taskID, UINT32 *taskStatus)
1359 {
1360     UINT32    intSave;
1361     LosTaskCB *taskCB = NULL;
1362 
1363     if (taskStatus == NULL) {
1364         return LOS_ERRNO_TSK_PTR_NULL;
1365     }
1366 
1367     if (OS_CHECK_TSK_PID_NOIDLE(taskID)) {
1368         return LOS_ERRNO_TSK_ID_INVALID;
1369     }
1370 
1371     taskCB = OS_TCB_FROM_TID(taskID);
1372     intSave = LOS_IntLock();
1373 
1374     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1375         LOS_IntRestore(intSave);
1376         return LOS_ERRNO_TSK_NOT_CREATED;
1377     }
1378 
1379     *taskStatus = taskCB->taskStatus;
1380 
1381     LOS_IntRestore(intSave);
1382 
1383     return LOS_OK;
1384 }
1385 
1386 #if (LOSCFG_BASE_CORE_EXC_TSK_SWITCH == 1)
LOS_TaskSwitchInfoGet(UINT32 index,UINT32 * taskSwitchInfo)1387 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskSwitchInfoGet(UINT32 index, UINT32 *taskSwitchInfo)
1388 {
1389     UINT32 intSave;
1390     UINT32 curIndex;
1391 
1392     curIndex = index;
1393     if (curIndex >= OS_TASK_SWITCH_INFO_COUNT) {
1394         curIndex %= OS_TASK_SWITCH_INFO_COUNT;
1395     }
1396 
1397     if (taskSwitchInfo == NULL) {
1398         return LOS_ERRNO_TSK_PTR_NULL;
1399     }
1400 
1401     intSave = LOS_IntLock();
1402 
1403     (*taskSwitchInfo) = g_taskSwitchInfo.pid[curIndex];
1404 
1405     if (memcpy_s((VOID *)(taskSwitchInfo + 1), LOS_TASK_NAMELEN,
1406                  g_taskSwitchInfo.name[curIndex], LOS_TASK_NAMELEN) != EOK) {
1407         PRINT_ERR("LOS_TaskSwitchInfoGet copy task name failed\n");
1408     }
1409 
1410     LOS_IntRestore(intSave);
1411     return LOS_OK;
1412 }
1413 #endif
1414 
1415 /*****************************************************************************
1416 Function    : LOS_TaskInfoMonitor
1417 Description : Get all task info
1418 Input       : None
1419 Return      : LOS_OK on success ,or OS_ERROR on failure
1420 *****************************************************************************/
LOS_TaskInfoMonitor(VOID)1421 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoMonitor(VOID)
1422 {
1423     UINT32 retVal;
1424 
1425     retVal = OsGetAllTskInfo();
1426 
1427     return retVal;
1428 }
1429 
1430 /*****************************************************************************
1431  Function    : LOS_TaskIsRunning
1432  Description : Check if LiteOS has been started.
1433  Input       : VOID
1434  Output      : VOID
1435  Return      : TRUE means LiteOS was started, FALSE means not.
1436  *****************************************************************************/
LOS_TaskIsRunning(VOID)1437 LITE_OS_SEC_TEXT_MINOR BOOL LOS_TaskIsRunning(VOID)
1438 {
1439     return g_taskScheduled;
1440 }
1441 
1442 /*****************************************************************************
1443  Function    : LOS_NewTaskIDGet
1444  Description : get id of current new task.
1445  Input       : None
1446  Output      : None
1447  Return      : task id
1448  *****************************************************************************/
LOS_NewTaskIDGet(VOID)1449 LITE_OS_SEC_TEXT UINT32 LOS_NewTaskIDGet(VOID)
1450 {
1451     return LOS_NextTaskIDGet();
1452 }
1453 
1454 /*****************************************************************************
1455  Function    : LOS_TaskNameGet
1456  Description : get Name of current new task.
1457  Input       : taskID -----task id
1458  Output      : None
1459  Return      : task name
1460  *****************************************************************************/
LOS_TaskNameGet(UINT32 taskID)1461 LITE_OS_SEC_TEXT CHAR* LOS_TaskNameGet(UINT32 taskID)
1462 {
1463     UINT32    intSave;
1464     LosTaskCB *taskCB = NULL;
1465 
1466     if (OS_CHECK_TSK_PID_NOIDLE(taskID)) {
1467         return NULL;
1468     }
1469 
1470     taskCB = OS_TCB_FROM_TID(taskID);
1471 
1472     intSave = LOS_IntLock();
1473     if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
1474         LOS_IntRestore(intSave);
1475         return NULL;
1476     }
1477     LOS_IntRestore(intSave);
1478 
1479     return taskCB->taskName;
1480 }
1481 
LOS_Msleep(UINT32 mSecs)1482 LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 mSecs)
1483 {
1484     UINT32 interval;
1485 
1486     if (OS_INT_ACTIVE) {
1487         return;
1488     }
1489 
1490     if (mSecs == 0) {
1491         interval = 0;
1492     } else {
1493         interval = LOS_MS2Tick(mSecs);
1494         if (interval == 0) {
1495             interval = 1;
1496         }
1497     }
1498 
1499     (VOID)LOS_TaskDelay(interval);
1500 }
1501 
LOS_TaskResRecycle(VOID)1502 VOID LOS_TaskResRecycle(VOID)
1503 {
1504     OsRecyleFinishedTask();
1505 }
1506