1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: Task Info implementation
14 */
15 #include "prt_task_internal.h"
16
17 #if defined(OS_OPTION_TASK_INFO)
OsTaskSpPcInfoReady(struct TagTskCb * taskCb)18 OS_SEC_ALW_INLINE INLINE bool OsTaskSpPcInfoReady(struct TagTskCb *taskCb)
19 {
20 return (bool)(((taskCb->taskStatus & OS_TSK_RUNNING) == 0) || (OS_INT_ACTIVE));
21 }
22
OsTaskSpInfoGet(struct TagTskCb * taskCb)23 OS_SEC_L2_TEXT uintptr_t OsTaskSpInfoGet(struct TagTskCb *taskCb)
24 {
25 uintptr_t sp;
26
27 if (OsTaskSpPcInfoReady(taskCb)) {
28 sp = (uintptr_t)taskCb->stackPointer;
29 } else {
30 sp = OsGetSp();
31 }
32
33 return sp;
34 }
35
OsTaskSpPcGet(struct TagTskCb * taskCb,struct TskInfo * taskInfo)36 OS_SEC_L2_TEXT void OsTaskSpPcGet(struct TagTskCb *taskCb, struct TskInfo *taskInfo)
37 {
38 if (OsTaskSpPcInfoReady(taskCb)) {
39 taskInfo->sp = (uintptr_t)taskCb->stackPointer;
40 taskInfo->pc = OsTskGetInstrAddr((uintptr_t)taskCb->stackPointer);
41 }
42 /* 非中断时, 任务若处于运行态, 其控制块的stackPointer值不准确,不能据此获取SP,PC */
43 return;
44 }
45
OsTaskInfoGetChk(TskHandle taskPid,struct TskInfo * taskInfo)46 OS_SEC_ALW_INLINE INLINE U32 OsTaskInfoGetChk(TskHandle taskPid, struct TskInfo *taskInfo)
47 {
48 if (taskInfo == NULL) {
49 return OS_ERRNO_TSK_PTR_NULL;
50 }
51
52 if (CHECK_TSK_PID_OVERFLOW(taskPid)) {
53 return OS_ERRNO_TSK_ID_INVALID;
54 }
55 return OS_OK;
56 }
57
OsTaskInfoCommonGet(struct TskInfo * taskInfo,struct TagTskCb * taskCb,TskHandle taskPid)58 OS_SEC_ALW_INLINE INLINE void OsTaskInfoCommonGet(struct TskInfo *taskInfo, struct TagTskCb *taskCb, TskHandle taskPid)
59 {
60 char *name = NULL;
61
62 taskInfo->taskStatus = (TskStatus)taskCb->taskStatus;
63 taskInfo->taskPrio = taskCb->priority;
64 taskInfo->stackSize = taskCb->stackSize;
65 taskInfo->topOfStack = taskCb->topOfStack;
66
67 if (g_taskNameGet != NULL) {
68 g_taskNameGet(taskPid, &name);
69
70 if (strncpy_s(taskInfo->name, sizeof(taskInfo->name), name, (sizeof(taskInfo->name) - 1)) != EOK) {
71 OS_GOTO_SYS_ERROR1();
72 }
73 taskInfo->name[OS_TSK_NAME_LEN - 1] = '\0';
74 }
75
76 taskInfo->entry = taskCb->taskEntry;
77 taskInfo->tcbAddr = taskCb;
78 }
79
OsTaskStackPeakGet(struct TskStackInfo * stackInfo)80 OS_SEC_L4_TEXT void OsTaskStackPeakGet(struct TskStackInfo *stackInfo)
81 {
82 U32 *stack = NULL;
83 if (*(U32 *)stackInfo->top == OS_TSK_STACK_TOP_MAGIC) {
84 stack = (U32 *)(stackInfo->top + sizeof(U32));
85 while ((stack < (U32 *)stackInfo->sp) && (*stack == OS_TSK_STACK_MAGIC)) {
86 stack += 1;
87 }
88
89 stackInfo->peakUsed = (U32)(stackInfo->bottom - (uintptr_t)stack);
90 stackInfo->ovf = FALSE;
91 } else {
92 stackInfo->peakUsed = OS_MAX_U32;
93 stackInfo->ovf = TRUE;
94 }
95 }
96 /*
97 * 描述:获取指定任务的堆栈信息
98 */
OsTaskStackInfoGet(TskHandle taskPid,struct TskStackInfo * stackInfo)99 OS_SEC_L4_TEXT U32 OsTaskStackInfoGet(TskHandle taskPid, struct TskStackInfo *stackInfo)
100 {
101 uintptr_t intSave;
102 struct TagTskCb *taskCb = NULL;
103
104 if (stackInfo == NULL) {
105 return OS_ERRNO_TSK_PTR_NULL;
106 }
107
108 if (CHECK_TSK_PID_OVERFLOW(taskPid)) {
109 return OS_ERRNO_TSK_ID_INVALID;
110 }
111
112 taskCb = GET_TCB_HANDLE(taskPid);
113 intSave = OsIntLock();
114
115 if (TSK_IS_UNUSED(taskCb)) {
116 OsIntRestore(intSave);
117 return OS_ERRNO_TSK_NOT_CREATED;
118 }
119
120 /* 获取SP */
121 stackInfo->sp = OsTaskSpInfoGet(taskCb);
122
123 stackInfo->top = (uintptr_t)taskCb->topOfStack;
124 stackInfo->bottom = TRUNCATE(((uintptr_t)(taskCb->topOfStack) + (taskCb->stackSize)), OS_TSK_STACK_ADDR_ALIGN);
125 stackInfo->currUsed = (U32)(stackInfo->bottom - stackInfo->sp);
126 OsTaskStackPeakGet(stackInfo);
127 OsIntRestore(intSave);
128
129 return OS_OK;
130 }
OsTaskInfoStackGet(TskHandle taskPid,struct TskInfo * taskInfo)131 OS_SEC_ALW_INLINE INLINE U32 OsTaskInfoStackGet(TskHandle taskPid, struct TskInfo *taskInfo)
132 {
133 U32 ret;
134 struct TskStackInfo stackInfo = {0};
135
136 ret = OsTaskStackInfoGet(taskPid, &stackInfo);
137 if (ret != OS_OK) {
138 return ret;
139 }
140
141 taskInfo->bottom = stackInfo.bottom;
142 taskInfo->currUsed = stackInfo.currUsed;
143 taskInfo->peakUsed = stackInfo.peakUsed;
144 taskInfo->ovf = stackInfo.ovf;
145 return OS_OK;
146 }
147
148 /*
149 * 描述:获取指定任务的信息
150 */
PRT_TaskGetInfo(TskHandle taskPid,struct TskInfo * taskInfo)151 OS_SEC_L4_TEXT U32 PRT_TaskGetInfo(TskHandle taskPid, struct TskInfo *taskInfo)
152 {
153 U32 ret;
154 uintptr_t intSave;
155 struct TagTskCb *taskCb = NULL;
156
157 ret = OsTaskInfoGetChk(taskPid, taskInfo);
158 if (ret != OS_OK) {
159 return ret;
160 }
161
162 taskCb = GET_TCB_HANDLE(taskPid);
163 intSave = OsIntLock();
164
165 if (TSK_IS_UNUSED(taskCb)) {
166 OsIntRestore(intSave);
167 return OS_ERRNO_TSK_NOT_CREATED;
168 }
169
170 OsTaskSpPcGet(taskCb, taskInfo);
171
172 OsTaskInfoCommonGet(taskInfo, taskCb, taskPid);
173
174 /* 当前在中断中或者不是当前rq的运行任务 */
175 if (OS_INT_ACTIVE || (taskPid != RUNNING_TASK->taskPid)) {
176 OsTskContextGet((uintptr_t)taskCb->stackPointer, &taskInfo->context);
177 }
178 OsIntRestore(intSave);
179
180 return OsTaskInfoStackGet(taskPid, taskInfo);
181 }
182
183 /*
184 * 描述:获取指定的任务名
185 */
PRT_TaskGetName(TskHandle taskId,char ** name)186 OS_SEC_L4_TEXT U32 PRT_TaskGetName(TskHandle taskId, char **name)
187 {
188 uintptr_t intSave;
189 struct TagTskCb *taskCb = NULL;
190
191 if (CHECK_TSK_PID_OVERFLOW(taskId)) {
192 return OS_ERRNO_TSK_ID_INVALID;
193 }
194
195 if (name == NULL) {
196 return OS_ERRNO_TSK_PTR_NULL;
197 }
198
199 taskCb = GET_TCB_HANDLE(taskId);
200
201 intSave = OsIntLock();
202
203 if (TSK_IS_UNUSED(taskCb)) {
204 OsIntRestore(intSave);
205 return OS_ERRNO_TSK_NOT_CREATED;
206 }
207
208 if (g_taskNameGet != NULL) {
209 g_taskNameGet(taskId, name);
210 }
211
212 OsIntRestore(intSave);
213
214 return OS_OK;
215 }
216 #endif
217