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