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