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