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