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