parent
							
								
									68d83fc343
								
							
						
					
					
						commit
						53c4bf5ab7
					
				| @ -1,257 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. | ||||
|  * Description: Mutex Deadlock Check | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2013-01-01 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_mux_debug_pri.h" | ||||
| #include "los_typedef.h" | ||||
| #include "los_task.h" | ||||
| #include "arch/exception.h" | ||||
| #ifdef LOSCFG_SHELL | ||||
| #include "shcmd.h" | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| #endif /* __cplusplus */nbb | ||||
| 
 | ||||
| typedef struct { | ||||
|     LOS_DL_LIST muxListHead;    /* Task-held mutexs list */     //用于管理任务持有的互斥锁列表//
 | ||||
|     UINT64      lastAccessTime; /* The last operation time */   //记录最后一次操作的时间//
 | ||||
| } MuxDLinkCB; | ||||
| 
 | ||||
| /*管理任务持有的互斥锁列表和跟踪死锁情况*/ | ||||
| typedef struct { | ||||
|     LOS_DL_LIST muxList; /* Insert mutex into the owner task CB */  //用于将互斥锁插入到所属任务的控制块中//
 | ||||
|     VOID        *muxCB;  /* The Mutex CB pointer */ //指向互斥锁控制块的指针//
 | ||||
| } MuxDLinkNode; | ||||
| 
 | ||||
| STATIC MuxDLinkCB *g_muxDeadlockCBArray = NULL; | ||||
| 
 | ||||
| /*
 | ||||
|  * Mutex deadlock detection time threshold, will print out task information | ||||
|  * that has not been scheduled within this time. | ||||
|  * The unit is tick. | ||||
|  */ | ||||
| #define OS_MUX_DEADLOCK_CHECK_THRESHOLD 60000   //定义两次检查互斥锁死锁之间的最小时间间隔,单位为毫秒//
 | ||||
| 
 | ||||
| UINT32 OsMuxDlockCheckInit(VOID)    //用于分配内存并初始化互斥锁控制块列表//
 | ||||
| { | ||||
|     UINT32 index; | ||||
|     UINT32 size = (LOSCFG_BASE_CORE_TSK_LIMIT + 1) * sizeof(MuxDLinkCB); | ||||
| 
 | ||||
|     /* system resident memory, don't free */ | ||||
|     g_muxDeadlockCBArray = (MuxDLinkCB *)LOS_MemAlloc(m_aucSysMem1, size); | ||||
|     if (g_muxDeadlockCBArray == NULL) { | ||||
|         PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); | ||||
|         return LOS_NOK; | ||||
|     } | ||||
| 
 | ||||
|     for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT + 1; index++) { | ||||
|         g_muxDeadlockCBArray[index].lastAccessTime = 0; | ||||
|         LOS_ListInit(&g_muxDeadlockCBArray[index].muxListHead); | ||||
|     } | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| VOID OsMuxDlockNodeInsert(UINT32 taskId, VOID *muxCB)   //用于向指定任务的互斥锁链表中插入一个互斥锁节点//
 | ||||
| { | ||||
|     MuxDLinkNode *muxDLNode = NULL; | ||||
| 
 | ||||
|     if ((taskId > LOSCFG_BASE_CORE_TSK_LIMIT) || (muxCB == NULL)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     muxDLNode = (MuxDLinkNode *)LOS_MemAlloc(m_aucSysMem1, sizeof(MuxDLinkNode)); | ||||
|     if (muxDLNode == NULL) { | ||||
|         return; | ||||
|     } | ||||
|     (VOID)memset_s(muxDLNode, sizeof(MuxDLinkNode), 0, sizeof(MuxDLinkNode)); | ||||
|     muxDLNode->muxCB = muxCB; | ||||
| 
 | ||||
|     LOS_ListTailInsert(&g_muxDeadlockCBArray[taskId].muxListHead, &muxDLNode->muxList); | ||||
| } | ||||
| 
 | ||||
| VOID OsMuxDlockNodeDelete(UINT32 taskId, const VOID *muxCB) //用于从指定任务的互斥锁链表中删除指定的互斥锁节点//
 | ||||
| { | ||||
|     MuxDLinkCB *muxDLCB = NULL; | ||||
|     LOS_DL_LIST *list = NULL; | ||||
|     MuxDLinkNode *muxDLNode = NULL; | ||||
| 
 | ||||
|     if ((taskId > LOSCFG_BASE_CORE_TSK_LIMIT) || (muxCB == NULL)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     muxDLCB = &g_muxDeadlockCBArray[taskId]; | ||||
|     LOS_DL_LIST_FOR_EACH(list, &muxDLCB->muxListHead) { | ||||
|         muxDLNode = LOS_DL_LIST_ENTRY(list, MuxDLinkNode, muxList); | ||||
|         if (muxDLNode->muxCB == muxCB) { | ||||
|             LOS_ListDelete(&muxDLNode->muxList); | ||||
|             (VOID)LOS_MemFree(m_aucSysMem1, muxDLNode); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| VOID OsTaskTimeUpdate(UINT32 taskId, UINT64 tickCount)  //用于更新任务的最后访问时间//
 | ||||
| { | ||||
|     if (taskId > LOSCFG_BASE_CORE_TSK_LIMIT) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     g_muxDeadlockCBArray[taskId].lastAccessTime = tickCount; | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsDeadlockBackTrace(const LosTaskCB *taskCB)    //用于打印任务的函数调用栈信息//
 | ||||
| { | ||||
|     TaskContext *context = NULL; | ||||
| 
 | ||||
|     PRINTK("*******backtrace begin*******\n"); | ||||
|     context = (TaskContext *)taskCB->stackPointer; | ||||
|     ArchBackTraceWithSp(context); | ||||
|     PRINTK("********backtrace end********\n"); | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsMutexPendTaskList(LOS_DL_LIST *list)  //用于打印互斥锁等待任务的列表信息//
 | ||||
| { | ||||
|     LOS_DL_LIST *listTmp = NULL; | ||||
|     LosTaskCB *pendedTask = NULL; | ||||
|     CHAR *name = NULL; | ||||
|     UINT32 index = 0; | ||||
|     UINT32 id, intSave; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
|     if (LOS_ListEmpty(list) == TRUE) { | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         PRINTK("Pended Task: null\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     LOS_DL_LIST_FOR_EACH(listTmp, list) { | ||||
|         pendedTask = OS_TCB_FROM_PENDLIST(listTmp); | ||||
|         name = pendedTask->taskName; | ||||
|         id = pendedTask->taskId; | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         if (index == 0) { | ||||
|             PRINTK("Pended task: %u. name:%-15s, id:0x%-5x\n", index, name, id); | ||||
|         } else { | ||||
|             PRINTK("             %u. name:%-15s, id:0x%-5x\n", index, name, id); | ||||
|         } | ||||
|         index++; | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|     } | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTaskHoldMutexList(MuxDLinkCB *muxDLCB)    //用于打印任务持有的互斥锁的信息//
 | ||||
| { | ||||
|     UINT32 index = 0; | ||||
|     MuxDLinkNode *muxDLNode = NULL; | ||||
|     CHAR *ownerName = NULL; | ||||
|     LosMuxCB *muxCB = NULL; | ||||
|     LOS_DL_LIST *list = NULL; | ||||
|     LOS_DL_LIST *listTmp = NULL; | ||||
|     UINT32 count, intSave; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
|     if (LOS_ListEmpty(&muxDLCB->muxListHead) == TRUE) { | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         PRINTK("null\n"); | ||||
|     } else { | ||||
|         LOS_DL_LIST_FOR_EACH(list, &muxDLCB->muxListHead) { | ||||
|             muxDLNode = LOS_DL_LIST_ENTRY(list, MuxDLinkNode, muxList); | ||||
|             muxCB = (LosMuxCB *)muxDLNode->muxCB; | ||||
|             count = muxCB->muxCount; | ||||
|             ownerName = muxCB->owner->taskName; | ||||
|             SCHEDULER_UNLOCK(intSave); | ||||
|             PRINTK("<Mutex%u info>\n", index); | ||||
|             PRINTK("Ptr handle:%p\n", muxCB); | ||||
|             PRINTK("Owner:%s\n", ownerName); | ||||
|             PRINTK("Count:%u\n", count); | ||||
| 
 | ||||
|             listTmp = &muxCB->muxList; | ||||
|             OsMutexPendTaskList(listTmp); | ||||
| 
 | ||||
|             index++; | ||||
|             SCHEDULER_LOCK(intSave); | ||||
|         } | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| VOID OsMutexDlockCheck(VOID)    //用于检测互斥锁死锁情况并输出相关信息//
 | ||||
| { | ||||
|     UINT32 loop, intSave; | ||||
|     UINT32 taskId; | ||||
|     CHAR *name = NULL; | ||||
|     LosTaskCB *taskCB = NULL; | ||||
|     MuxDLinkCB *muxDLCB = NULL; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
|     for (loop = 0; loop < g_taskMaxNum; loop++) { | ||||
|         taskCB = (LosTaskCB *)g_taskCBArray + loop; | ||||
|         if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         muxDLCB = &g_muxDeadlockCBArray[taskCB->taskId]; | ||||
|         if ((LOS_TickCountGet() - muxDLCB->lastAccessTime) > OS_MUX_DEADLOCK_CHECK_THRESHOLD) { | ||||
|             name = taskCB->taskName; | ||||
|             taskId = taskCB->taskId; | ||||
|             SCHEDULER_UNLOCK(intSave); | ||||
|             PRINTK("Task_name:%s, ID:0x%x, holds the Mutexs below:\n", name, taskId); | ||||
|             OsTaskHoldMutexList(muxDLCB); | ||||
|             OsDeadlockBackTrace(taskCB); | ||||
|             PRINTK("\n"); | ||||
|             SCHEDULER_LOCK(intSave); | ||||
|         } | ||||
|     } | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_SHELL     //用于在命令行中执行互斥锁死锁检查并输出相关信息//
 | ||||
| UINT32 OsShellCmdMuxDeadlockCheck(UINT32 argc, const CHAR **argv) | ||||
| { | ||||
|     if (argc > 0) { | ||||
|         PRINTK("\nUsage: dlock\n"); | ||||
|         return OS_ERROR; | ||||
|     } | ||||
|     PRINTK("Start mutexs deadlock check: \n"); | ||||
|     OsMutexDlockCheck(); | ||||
|     PRINTK("-----------End-----------\n"); | ||||
|     return LOS_OK; | ||||
| } | ||||
| SHELLCMD_ENTRY(deadlock_shellcmd, CMD_TYPE_EX, "dlock", 0, (CmdCallBackFunc)OsShellCmdMuxDeadlockCheck); | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,189 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. | ||||
|  * Description: Mutex Debug | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2013-01-01 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_mux_debug_pri.h" | ||||
| #include "los_typedef.h" | ||||
| #include "los_task.h" | ||||
| #include "los_misc_pri.h" | ||||
| #include "arch/exception.h" | ||||
| #ifdef LOSCFG_SHELL | ||||
| #include "shcmd.h" | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_DEBUG_MUTEX   //用于表示互斥锁的调试信息//
 | ||||
| typedef struct { | ||||
|     TSK_ENTRY_FUNC creator; /* The task entry who created this mutex */ | ||||
|     UINT64  lastAccessTime; /* The last access time */ | ||||
| } MuxDebugCB; | ||||
| STATIC MuxDebugCB *g_muxDebugArray = NULL; | ||||
| 
 | ||||
| //用于比较两个互斥锁调试信息的最后访问时间//
 | ||||
| STATIC BOOL MuxCompareValue(const SortParam *sortParam, UINT32 left, UINT32 right) | ||||
| { | ||||
|     return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > | ||||
|             *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); | ||||
| } | ||||
| 
 | ||||
| UINT32 OsMuxDbgInit(VOID)   //用于初始化互斥锁调试信息数组//
 | ||||
| { | ||||
|     UINT32 size = LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(MuxDebugCB); | ||||
|     /* system resident memory, don't free */ | ||||
|     g_muxDebugArray = (MuxDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); | ||||
|     if (g_muxDebugArray == NULL) { | ||||
|         PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); | ||||
|         return LOS_NOK; | ||||
|     } | ||||
|     (VOID)memset_s(g_muxDebugArray, size, 0, size); | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| VOID OsMuxDbgTimeUpdate(UINT32 muxId)   //用于更新指定互斥锁的最后访问时间//
 | ||||
| { | ||||
|     MuxDebugCB *muxDebug = &g_muxDebugArray[GET_MUX_INDEX(muxId)]; | ||||
|     muxDebug->lastAccessTime = LOS_TickCountGet(); | ||||
| } | ||||
| 
 | ||||
| VOID OsMuxDbgUpdate(UINT32 muxId, TSK_ENTRY_FUNC creator)   //用于更新指定互斥锁的创建者和最后访问时间//
 | ||||
| { | ||||
|     MuxDebugCB *muxDebug = &g_muxDebugArray[GET_MUX_INDEX(muxId)]; | ||||
|     muxDebug->creator = creator; | ||||
|     muxDebug->lastAccessTime = LOS_TickCountGet(); | ||||
| } | ||||
| 
 | ||||
| //用于对互斥锁索引数组进行排序,并检查可能存在的互斥锁泄漏//
 | ||||
| STATIC VOID SortMuxIndexArray(UINT32 *indexArray, UINT32 count) | ||||
| { | ||||
|     LosMuxCB muxNode = {{0, 0}, 0, 0, 0, 0}; | ||||
|     MuxDebugCB muxDebugNode = {0}; | ||||
|     UINT32 index, intSave; | ||||
|     SortParam muxSortParam; | ||||
|     muxSortParam.buf = (CHAR *)g_muxDebugArray; | ||||
|     muxSortParam.ctrlBlockSize = sizeof(MuxDebugCB); | ||||
|     muxSortParam.ctrlBlockCnt = LOSCFG_BASE_IPC_MUX_LIMIT; | ||||
|     muxSortParam.sortElemOff = LOS_OFF_SET_OF(MuxDebugCB, lastAccessTime); | ||||
| 
 | ||||
|     if (count > 0) { | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         OsArraySort(indexArray, 0, count - 1, &muxSortParam, MuxCompareValue); | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         for (index = 0; index < count; index++) { | ||||
|             SCHEDULER_LOCK(intSave); | ||||
|             (VOID)memcpy_s(&muxNode, sizeof(LosMuxCB), | ||||
|                            GET_MUX(indexArray[index]), sizeof(LosMuxCB)); | ||||
|             (VOID)memcpy_s(&muxDebugNode, sizeof(MuxDebugCB), | ||||
|                            &g_muxDebugArray[indexArray[index]], sizeof(MuxDebugCB)); | ||||
|             SCHEDULER_UNLOCK(intSave); | ||||
|             /*
 | ||||
|              * muxStat may be altered after the g_taskSpin is unlocked in OsMutexCheck. | ||||
|              * We should recheck the muxStat before the print. | ||||
|              */ | ||||
|             if ((muxNode.muxStat != LOS_USED) || | ||||
|                 ((muxNode.muxStat == LOS_USED) && ((muxDebugNode.creator == NULL) || (muxNode.owner == NULL)))) { | ||||
|                 continue; | ||||
|             } | ||||
|             PRINTK("Mutex ID <0x%x> may leak, TaskID of owner:0x%x, TaskEntry of owner: %p," | ||||
|                    "TaskEntry of creator: %p,Latest operation time: 0x%llx\n", | ||||
|                    muxNode.muxId, muxNode.owner->taskId, muxNode.owner->taskEntry, muxDebugNode.creator, | ||||
|                    muxDebugNode.lastAccessTime); | ||||
|         } | ||||
|     } | ||||
|     (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray); | ||||
| } | ||||
| 
 | ||||
| VOID OsMutexCheck(VOID) //用于检查互斥锁的状态并对可能存在的互斥锁泄漏进行处理//
 | ||||
| { | ||||
|     LosMuxCB muxNode = {{0, 0}, 0, 0, 0, 0}; | ||||
|     MuxDebugCB muxDebugNode = {0}; | ||||
|     UINT32 index, intSave; | ||||
|     UINT32 count = 0; | ||||
| 
 | ||||
|     /*
 | ||||
|      * This return value does not need to be judged immediately, | ||||
|      * and the following code logic has already distinguished the return value from null and non-empty, | ||||
|      * and there is no case of accessing the null pointer. | ||||
|      */ | ||||
|     UINT32 *indexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(UINT32)); | ||||
| 
 | ||||
|     for (index = 0; index < LOSCFG_BASE_IPC_MUX_LIMIT; index++) { | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         (VOID)memcpy_s(&muxNode, sizeof(LosMuxCB), GET_MUX(index), sizeof(LosMuxCB)); | ||||
|         (VOID)memcpy_s(&muxDebugNode, sizeof(MuxDebugCB), &g_muxDebugArray[index], sizeof(MuxDebugCB)); | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
| 
 | ||||
|         if ((muxNode.muxStat != LOS_USED) || | ||||
|             ((muxNode.muxStat == LOS_USED) && (muxDebugNode.creator == NULL))) { | ||||
|             continue; | ||||
|         } else if ((muxNode.muxStat == LOS_USED) && (muxNode.owner == NULL)) { | ||||
|             PRINTK("Mutex ID <0x%x> may leak, Owner is null, TaskEntry of creator: %p," | ||||
|                    "Latest operation time: 0x%llx\n", | ||||
|                    muxNode.muxId, muxDebugNode.creator, muxDebugNode.lastAccessTime); | ||||
|         } else { | ||||
|             if (indexArray != NULL) { | ||||
|                 *(indexArray + count) = index; | ||||
|                 count++; | ||||
|             } else { | ||||
|                 PRINTK("Mutex ID <0x%x> may leak, TaskID of owner:0x%x, TaskEntry of owner: %p," | ||||
|                        "TaskEntry of creator: %p,Latest operation time: 0x%llx\n", | ||||
|                        muxNode.muxId, muxNode.owner->taskId, muxNode.owner->taskEntry, muxDebugNode.creator, | ||||
|                        muxDebugNode.lastAccessTime); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (indexArray != NULL) { | ||||
|         SortMuxIndexArray(indexArray, count); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_SHELL | ||||
| //用于获取互斥锁信息//
 | ||||
| LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMuxInfoGet(UINT32 argc, const CHAR **argv) | ||||
| { | ||||
|     if (argc > 0) { | ||||
|         PRINTK("\nUsage: mutex\n"); | ||||
|         return OS_ERROR; | ||||
|     } | ||||
|     PRINTK("used mutexs information: \n"); | ||||
|     OsMutexCheck(); | ||||
|     return LOS_OK; | ||||
| } | ||||
| SHELLCMD_ENTRY(mutex_shellcmd, CMD_TYPE_EX, "mutex", 0, (CmdCallBackFunc)OsShellCmdMuxInfoGet); | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| #endif /* LOSCFG_DEBUG_MUTEX */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,206 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. | ||||
|  * Description: Queue Debug | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2013-01-01 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_queue_debug_pri.h" | ||||
| #include "los_misc_pri.h" | ||||
| #ifdef LOSCFG_SHELL | ||||
| #include "shcmd.h" | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_DEBUG_QUEUE   //用于保存队列的调试信息//
 | ||||
| typedef struct { | ||||
|     TSK_ENTRY_FUNC creator; /* The task entry who created this queue */ | ||||
|     UINT64  lastAccessTime; /* The last access time */ | ||||
| } QueueDebugCB; | ||||
| STATIC QueueDebugCB *g_queueDebugArray = NULL; | ||||
| 
 | ||||
| //用于比较队列中的元素值//
 | ||||
| STATIC BOOL QueueCompareValue(const SortParam *sortParam, UINT32 left, UINT32 right) | ||||
| { | ||||
|     return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > | ||||
|             *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); | ||||
| } | ||||
| 
 | ||||
| UINT32 OsQueueDbgInit(VOID) //用于初始化队列的调试信息//
 | ||||
| { | ||||
|     UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(QueueDebugCB); | ||||
| 
 | ||||
|     /* system resident memory, don't free */ | ||||
|     g_queueDebugArray = (QueueDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); | ||||
|     if (g_queueDebugArray == NULL) { | ||||
|         PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); | ||||
|         return LOS_NOK; | ||||
|     } | ||||
|     (VOID)memset_s(g_queueDebugArray, size, 0, size); | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| VOID OsQueueDbgTimeUpdate(UINT32 queueId)   //用于更新队列的最后访问时间//
 | ||||
| { | ||||
|     QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueId)]; | ||||
|     queueDebug->lastAccessTime = LOS_TickCountGet(); | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| VOID OsQueueDbgUpdate(UINT32 queueId, TSK_ENTRY_FUNC entry) //用于更新队列的调试信息//
 | ||||
| { | ||||
|     QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueId)]; | ||||
|     queueDebug->creator = entry; | ||||
|     queueDebug->lastAccessTime = LOS_TickCountGet(); | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| STATIC INLINE VOID OsQueueInfoOutPut(const LosQueueCB *node)    //用于输出队列的信息//
 | ||||
| { | ||||
|     PRINTK("Queue ID <0x%x> may leak, queue len is 0x%x, " | ||||
|            "readable cnt:0x%x, writeable cnt:0x%x, ", | ||||
|            node->queueId, | ||||
|            node->queueLen, | ||||
|            node->readWriteableCnt[OS_QUEUE_READ], | ||||
|            node->readWriteableCnt[OS_QUEUE_WRITE]); | ||||
| } | ||||
| 
 | ||||
| STATIC INLINE VOID OsQueueOpsOutput(const QueueDebugCB *node)   //用于输出队列操作的信息//
 | ||||
| { | ||||
|     PRINTK("TaskEntry of creator:0x%p, Latest operation time: 0x%llx\n", | ||||
|            node->creator, node->lastAccessTime); | ||||
| } | ||||
| 
 | ||||
| STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count)   //用于对队列索引数组进行排序并输出相应的队列信息//
 | ||||
| { | ||||
|     LosQueueCB queueNode = {0}; | ||||
|     QueueDebugCB queueDebugNode = {0}; | ||||
|     UINT32 index, intSave; | ||||
|     SortParam queueSortParam; | ||||
|     queueSortParam.buf = (CHAR *)g_queueDebugArray; | ||||
|     queueSortParam.ctrlBlockSize = sizeof(QueueDebugCB); | ||||
|     queueSortParam.ctrlBlockCnt = LOSCFG_BASE_IPC_QUEUE_LIMIT; | ||||
|     queueSortParam.sortElemOff = LOS_OFF_SET_OF(QueueDebugCB, lastAccessTime); | ||||
| 
 | ||||
|     if (count > 0) { | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         OsArraySort(indexArray, 0, count - 1, &queueSortParam, QueueCompareValue); | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         for (index = 0; index < count; index++) { | ||||
|             SCHEDULER_LOCK(intSave); | ||||
|             (VOID)memcpy_s(&queueNode, sizeof(LosQueueCB), | ||||
|                            GET_QUEUE_HANDLE(indexArray[index]), sizeof(LosQueueCB)); | ||||
|             (VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB), | ||||
|                            &g_queueDebugArray[indexArray[index]], sizeof(QueueDebugCB)); | ||||
|             SCHEDULER_UNLOCK(intSave); | ||||
|             if (queueNode.queueState == LOS_UNUSED) { | ||||
|                 continue; | ||||
|             } | ||||
|             OsQueueInfoOutPut(&queueNode); | ||||
|             OsQueueOpsOutput(&queueDebugNode); | ||||
|         } | ||||
|     } | ||||
|     (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray); | ||||
| } | ||||
| 
 | ||||
| VOID OsQueueCheck(VOID) //用于检查队列的状态并输出相应信息//
 | ||||
| { | ||||
|     LosQueueCB queueNode = {0}; | ||||
|     QueueDebugCB queueDebugNode = {0}; | ||||
|     UINT32 index, intSave; | ||||
|     UINT32 count = 0; | ||||
| 
 | ||||
|     /*
 | ||||
|      * This return value does not need to be judged immediately, | ||||
|      * and the following code logic has already distinguished the return value from null and non-empty, | ||||
|      * and there is no case of accessing the null pointer. | ||||
|      */ | ||||
|     UINT32 *indexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(UINT32)); | ||||
| 
 | ||||
|     for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) { | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         (VOID)memcpy_s(&queueNode, sizeof(LosQueueCB), | ||||
|                        GET_QUEUE_HANDLE(index), sizeof(LosQueueCB)); | ||||
|         (VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB), | ||||
|                        &g_queueDebugArray[index], sizeof(QueueDebugCB)); | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         if ((queueNode.queueState == LOS_UNUSED) || | ||||
|             ((queueNode.queueState == LOS_USED) && (queueDebugNode.creator == NULL))) { | ||||
|             continue; | ||||
|         } | ||||
|         if ((queueNode.queueState == LOS_USED) && | ||||
|             (queueNode.queueLen == queueNode.readWriteableCnt[OS_QUEUE_WRITE]) && | ||||
|             LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_READ]) && | ||||
|             LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_WRITE]) && | ||||
|             LOS_ListEmpty(&queueNode.memList)) { | ||||
|             PRINTK("Queue ID <0x%x> may leak, No task uses it, " | ||||
|                    "QueueLen is 0x%x, ", | ||||
|                    queueNode.queueId, | ||||
|                    queueNode.queueLen); | ||||
|             OsQueueOpsOutput(&queueDebugNode); | ||||
|         } else { | ||||
|             if (indexArray != NULL) { | ||||
|                 *(indexArray + count) = index; | ||||
|                 count++; | ||||
|             } else { | ||||
|                 OsQueueInfoOutPut(&queueNode); | ||||
|                 OsQueueOpsOutput(&queueDebugNode); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (indexArray != NULL) { | ||||
|         SortQueueIndexArray(indexArray, count); | ||||
|     } | ||||
| 
 | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_SHELL | ||||
| //当用户输入 "queue" 命令时,会输出已使用队列的信息//
 | ||||
| LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdQueueInfoGet(UINT32 argc, const CHAR **argv) | ||||
| { | ||||
|     if (argc > 0) { | ||||
|         PRINTK("\nUsage: queue\n"); | ||||
|         return OS_ERROR; | ||||
|     } | ||||
|     PRINTK("used queues information: \n"); | ||||
|     OsQueueCheck(); | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| SHELLCMD_ENTRY(queue_shellcmd, CMD_TYPE_EX, "queue", 0, (CmdCallBackFunc)OsShellCmdQueueInfoGet); | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| #endif /* LOSCFG_DEBUG_QUEUE */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,347 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. | ||||
|  * Description: Schedule Statistics | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2018-11-16 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_task_pri.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_DEBUG_SCHED_STATISTICS | ||||
| #define HIGHTASKPRI           16 | ||||
| #define NS_PER_MS             1000000 | ||||
| #define DECIMAL_TO_PERCENTAGE 100 | ||||
| 
 | ||||
| typedef struct { | ||||
|     UINT64      idleRuntime;    //空闲任务的运行时间//
 | ||||
|     UINT64      idleStarttime;  //空闲任务的启动时间//
 | ||||
|     UINT64      highTaskRuntime;    //高优先级任务的运行时间//
 | ||||
|     UINT64      highTaskStarttime;  //高优先级任务的启动时间//
 | ||||
|     UINT64      sumPriority;    //任务优先级之和//
 | ||||
|     UINT32      prioritySwitch; //任务切换次数//
 | ||||
|     UINT32      highTaskSwitch; //高优先级任务切换次数//
 | ||||
|     UINT32      contexSwitch;   //上下文切换次数//
 | ||||
|     UINT32      hwiNum; //硬件中断次数//
 | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|     UINT32      ipiIrqNum;  //中断次数(仅在多核配置下定义)//
 | ||||
| #endif | ||||
| } StatPercpu; | ||||
| 
 | ||||
| STATIC BOOL g_statisticsStartFlag = FALSE; | ||||
| STATIC UINT64 g_statisticsStartTime; | ||||
| STATIC StatPercpu g_statPercpu[LOSCFG_KERNEL_CORE_NUM]; | ||||
| 
 | ||||
| //用于在每个 CPU 核心上进行调度统计//
 | ||||
| STATIC VOID OsSchedStatisticsPerCpu(const LosTaskCB *runTask, const LosTaskCB *newTask) | ||||
| { | ||||
|     UINT32 cpuId; | ||||
|     UINT32 idleTaskId; | ||||
|     UINT64 now, runtime; | ||||
| 
 | ||||
|     if (g_statisticsStartFlag != TRUE) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     cpuId = ArchCurrCpuid(); | ||||
|     idleTaskId = OsGetIdleTaskId(); | ||||
|     now = LOS_CurrNanosec(); | ||||
| 
 | ||||
|     g_statPercpu[cpuId].contexSwitch++; | ||||
| 
 | ||||
|     if ((runTask->taskId != idleTaskId) && (newTask->taskId == idleTaskId)) { | ||||
|         g_statPercpu[cpuId].idleStarttime = now; | ||||
|     } | ||||
| 
 | ||||
|     if ((runTask->taskId == idleTaskId) && (newTask->taskId != idleTaskId)) { | ||||
|         runtime = now - g_statPercpu[cpuId].idleStarttime; | ||||
|         g_statPercpu[cpuId].idleRuntime += runtime; | ||||
|         g_statPercpu[cpuId].idleStarttime = 0; | ||||
|     } | ||||
| 
 | ||||
|     if ((runTask->priority >= HIGHTASKPRI) && (newTask->priority < HIGHTASKPRI)) { | ||||
|         g_statPercpu[cpuId].highTaskStarttime = now; | ||||
|     } | ||||
| 
 | ||||
|     if ((runTask->priority < HIGHTASKPRI) && (newTask->priority >= HIGHTASKPRI)) { | ||||
|         runtime = now - g_statPercpu[cpuId].highTaskStarttime; | ||||
|         g_statPercpu[cpuId].highTaskRuntime += runtime; | ||||
|         g_statPercpu[cpuId].highTaskStarttime = 0; | ||||
|     } | ||||
| 
 | ||||
|     if (newTask->priority < HIGHTASKPRI) { | ||||
|         g_statPercpu[cpuId].highTaskSwitch++; | ||||
|     } | ||||
| 
 | ||||
|     if (newTask->taskId != idleTaskId) { | ||||
|         g_statPercpu[cpuId].sumPriority += newTask->priority; | ||||
|         g_statPercpu[cpuId].prioritySwitch++; | ||||
|     } | ||||
| 
 | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| //用于更新调度统计信息//
 | ||||
| LITE_OS_SEC_TEXT_MINOR VOID OsSchedStatistics(LosTaskCB *runTask, LosTaskCB *newTask) | ||||
| { | ||||
|     UINT64 runtime; | ||||
|     UINT32 cpuId = ArchCurrCpuid(); | ||||
|     UINT64 now = LOS_CurrNanosec(); | ||||
| 
 | ||||
|     SchedStat *schedRun = &runTask->schedStat; | ||||
|     SchedStat *schedNew = &newTask->schedStat; | ||||
|     SchedPercpu *cpuRun = &schedRun->schedPercpu[cpuId]; | ||||
|     SchedPercpu *cpuNew = &schedNew->schedPercpu[cpuId]; | ||||
| 
 | ||||
|     /* calculate one chance of running time */ | ||||
|     runtime = now - schedRun->startRuntime; | ||||
| 
 | ||||
|     /* add running timer to running task statistics */ | ||||
|     cpuRun->runtime += runtime; | ||||
|     schedRun->allRuntime += runtime; | ||||
| 
 | ||||
|     /* add context switch counters and schedule start time */ | ||||
|     cpuNew->contexSwitch++; | ||||
|     schedNew->allContextSwitch++; | ||||
|     schedNew->startRuntime = now; | ||||
|     OsSchedStatisticsPerCpu(runTask, newTask); | ||||
| } | ||||
| 
 | ||||
| LITE_OS_SEC_TEXT_MINOR VOID OsHwiStatistics(size_t intNum)  //用于更新硬中断的统计信息//
 | ||||
| { | ||||
|     UINT32 cpuId = ArchCurrCpuid(); | ||||
| 
 | ||||
|     if ((g_statisticsStartFlag != TRUE) || (intNum == OS_TICK_INT_NUM)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     g_statPercpu[cpuId].hwiNum++; | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|     /* 16: 0~15 is ipi interrupts */ | ||||
|     if (intNum < 16) { | ||||
|         g_statPercpu[cpuId].ipiIrqNum++; | ||||
|     } | ||||
| #endif | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdDumpSched(VOID)   //用于打印任务的调度统计信息//
 | ||||
| { | ||||
|     LosTaskCB *taskCB = NULL; | ||||
|     UINT32 loop; | ||||
|     UINT32 cpuId; | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|     UINT32 affinity; | ||||
| #endif | ||||
| 
 | ||||
|     PRINTK("\n"); | ||||
|     PRINTK("Task                          TID              Total Time     Total CST     " | ||||
|            "CPU                   Time           CST\n"); | ||||
|     PRINTK("----                          ---      ------------------    ----------    -" | ||||
|            "---     ------------------    ----------\n"); | ||||
| 
 | ||||
|     for (loop = 0; loop < g_taskMaxNum; loop++) { | ||||
|         taskCB = (((LosTaskCB *)g_taskCBArray) + loop); | ||||
|         if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { | ||||
|             continue; | ||||
|         } | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|         affinity = (UINT32)taskCB->cpuAffiMask; | ||||
| #endif | ||||
|         PRINTK("%-30s0x%-6x%+16lf ms  %10u\n", taskCB->taskName, taskCB->taskId, | ||||
|                (DOUBLE)(taskCB->schedStat.allRuntime) / NS_PER_MS, | ||||
|                taskCB->schedStat.allContextSwitch); | ||||
| 
 | ||||
|         for (cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) { | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|             if (!((1U << cpuId) & affinity)) { | ||||
|                 continue; | ||||
|             } | ||||
| #endif | ||||
|             PRINTK("                                                                           " | ||||
|                    "CPU%u    %+16lf ms  %12u\n", cpuId, | ||||
|                    (DOUBLE)(taskCB->schedStat.schedPercpu[cpuId].runtime) / NS_PER_MS, | ||||
|                    taskCB->schedStat.schedPercpu[cpuId].contexSwitch); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     PRINTK("\n"); | ||||
| } | ||||
| 
 | ||||
| LITE_OS_SEC_TEXT_MINOR VOID OsStatisticsShow(UINT64 statisticsPastTime) //用于显示系统的统计信息//
 | ||||
| { | ||||
|     UINT32 cpuId; | ||||
|     PRINTK("\n"); | ||||
|     PRINTK("Passed Time: %+16lf ms\n", ((DOUBLE)statisticsPastTime / NS_PER_MS)); | ||||
|     PRINTK("--------------------------------\n"); | ||||
|     PRINTK("CPU       Idle(%%)      ContexSwitch    HwiNum       " | ||||
|            "Avg Pri      HiTask(%%)	   HiTask SwiNum       HiTask P(ms)" | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|            "      MP Hwi\n"); | ||||
| #else | ||||
|            "\n"); | ||||
| #endif | ||||
|     PRINTK("----    ---------      -----------    --------    ---------     " | ||||
|            "----------         ------------       ----------" | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|            "        ------\n"); | ||||
| #else | ||||
|            "\n"); | ||||
| #endif | ||||
| 
 | ||||
|     for (cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) { | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|         PRINTK("CPU%u   %+10lf%14u%14u   %+11lf   %+11lf%14u              %+11lf  %11u\n", cpuId, | ||||
| #else | ||||
|         PRINTK("CPU%u   %+10lf%14u%14u   %+11lf   %+11lf%14u              %+11lf\n", cpuId, | ||||
| #endif | ||||
|                ((DOUBLE)(g_statPercpu[cpuId].idleRuntime) / statisticsPastTime) * DECIMAL_TO_PERCENTAGE, | ||||
|                g_statPercpu[cpuId].contexSwitch, | ||||
|                g_statPercpu[cpuId].hwiNum, | ||||
|                (g_statPercpu[cpuId].prioritySwitch == 0) ? OS_TASK_PRIORITY_LOWEST : | ||||
|                ((DOUBLE)(g_statPercpu[cpuId].sumPriority) / (g_statPercpu[cpuId].prioritySwitch)), | ||||
|                ((DOUBLE)(g_statPercpu[cpuId].highTaskRuntime) / statisticsPastTime) * DECIMAL_TO_PERCENTAGE, | ||||
|                g_statPercpu[cpuId].highTaskSwitch, | ||||
|                (g_statPercpu[cpuId].highTaskSwitch == 0) ? 0 : | ||||
|                ((DOUBLE)(g_statPercpu[cpuId].highTaskRuntime) / (g_statPercpu[cpuId].highTaskSwitch)) / NS_PER_MS | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|                , g_statPercpu[cpuId].ipiIrqNum); | ||||
| #else | ||||
|                ); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     PRINTK("\n"); | ||||
| } | ||||
| 
 | ||||
| LITE_OS_SEC_TEXT_MINOR VOID OsShellStatisticsStart(VOID)    //用于在多核系统中启动统计功能//
 | ||||
| { | ||||
|     LosTaskCB *taskCB = NULL; | ||||
|     UINT32 loop; | ||||
|     UINT32 cpuId = 0; | ||||
|     UINT32 intSave; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
| 
 | ||||
|     if (g_statisticsStartFlag) { | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         PRINT_WARN("mp static has started\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     g_statisticsStartTime = LOS_CurrNanosec(); | ||||
| 
 | ||||
|     for (loop = 0; loop < g_taskMaxNum; loop++) { | ||||
|         taskCB = (((LosTaskCB *)g_taskCBArray) + loop); | ||||
|         if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|             cpuId = taskCB->currCpu; | ||||
| #endif | ||||
|             if ((UINT32)(OS_TASK_INVALID_CPUID) == cpuId) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (!strcmp(taskCB->taskName, "IdleCore000")) { | ||||
|                 g_statPercpu[cpuId].idleStarttime = g_statisticsStartTime; | ||||
|             } | ||||
|             if (taskCB->priority < HIGHTASKPRI) { | ||||
|                 g_statPercpu[cpuId].highTaskStarttime = g_statisticsStartTime; | ||||
|                 g_statPercpu[cpuId].highTaskSwitch++; | ||||
|             } | ||||
|             if (strcmp(taskCB->taskName, "IdleCore000")) { | ||||
|                 g_statPercpu[cpuId].sumPriority += taskCB->priority; | ||||
|                 g_statPercpu[cpuId].prioritySwitch++; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     g_statisticsStartFlag = TRUE; | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
| 
 | ||||
|     PRINTK("mp static start\n"); | ||||
| 
 | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| //用于在多核系统中停止统计功能,并进行统计数据的处理和展示//
 | ||||
| LITE_OS_SEC_TEXT_MINOR VOID OsShellStatisticsStop(VOID) | ||||
| { | ||||
|     LosTaskCB *taskCB = NULL; | ||||
|     UINT32 loop; | ||||
|     UINT32 cpuId = 0; | ||||
|     UINT64 statisticsStopTime; | ||||
|     UINT64 statisticsPastTime; | ||||
|     UINT64 runtime; | ||||
|     UINT32 intSave; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
| 
 | ||||
|     if (g_statisticsStartFlag != TRUE) { | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         PRINT_WARN("Please set mp static start\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     g_statisticsStartFlag = FALSE; | ||||
|     statisticsStopTime = LOS_CurrNanosec(); | ||||
|     statisticsPastTime = statisticsStopTime - g_statisticsStartTime; | ||||
| 
 | ||||
|     for (loop = 0; loop < g_taskMaxNum; loop++) { | ||||
|         taskCB = (((LosTaskCB *)g_taskCBArray) + loop); | ||||
|         if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|             cpuId = taskCB->currCpu; | ||||
| #endif | ||||
|             if (cpuId == (UINT32)(OS_TASK_INVALID_CPUID)) { | ||||
|                 continue; | ||||
|             } | ||||
|             if (!strcmp(taskCB->taskName, "IdleCore000")) { | ||||
|                 runtime = statisticsStopTime - g_statPercpu[cpuId].idleStarttime; | ||||
|                 g_statPercpu[cpuId].idleRuntime += runtime; | ||||
|                 g_statPercpu[cpuId].idleStarttime = 0; | ||||
|             } | ||||
|             if (taskCB->priority < HIGHTASKPRI) { | ||||
|                 runtime = statisticsStopTime - g_statPercpu[cpuId].highTaskStarttime; | ||||
|                 g_statPercpu[cpuId].highTaskRuntime += runtime; | ||||
|                 g_statPercpu[cpuId].highTaskStarttime = 0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
|     OsStatisticsShow(statisticsPastTime); | ||||
| 
 | ||||
|     (VOID)memset_s(g_statPercpu, sizeof(g_statPercpu), 0, sizeof(g_statPercpu)); | ||||
|     g_statisticsStartTime = 0; | ||||
|     return; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,299 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. | ||||
|  * Description: Sem Debug | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2013-01-01 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_sem_debug_pri.h" | ||||
| #include "stdlib.h" | ||||
| #include "los_typedef.h" | ||||
| #include "los_task_pri.h" | ||||
| #include "los_misc_pri.h" | ||||
| #ifdef LOSCFG_SHELL | ||||
| #include "shcmd.h" | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_DEBUG_SEMAPHORE | ||||
| #define OS_ALL_SEM_MASK 0xffffffff | ||||
| 
 | ||||
| STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode) //用于打印等待某个信号量的任务列表//
 | ||||
| { | ||||
|     LosTaskCB *tskCB = NULL; | ||||
|     CHAR *nameArr[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; | ||||
|     UINT32 i, intSave; | ||||
|     UINT32 num = 0; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
|     if ((semNode->semStat == LOS_UNUSED) || (LOS_ListEmpty(&semNode->semList))) { | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &semNode->semList, LosTaskCB, pendList) { | ||||
|         nameArr[num++] = tskCB->taskName; | ||||
|         if (num == LOSCFG_BASE_CORE_TSK_LIMIT) { | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
| 
 | ||||
|     PRINTK("Pended task list : "); | ||||
|     for (i = 0; i < num; i++) { | ||||
|         if (i == 0) { | ||||
|             PRINTK("%s\n", nameArr[i]); | ||||
|         } else { | ||||
|             PRINTK(", %s", nameArr[i]); | ||||
|         } | ||||
|     } | ||||
|     PRINTK("\n"); | ||||
| } | ||||
| 
 | ||||
| typedef struct {    //用于记录信号量的调试信息//
 | ||||
|     UINT16  origSemCount;   /* Number of original available semaphores */ | ||||
|     UINT64  lastAccessTime; /* The last operation time */ | ||||
|     TSK_ENTRY_FUNC creator; /* The task entry who created this sem */ | ||||
| } SemDebugCB; | ||||
| STATIC SemDebugCB *g_semDebugArray = NULL;  //用于存储所有信号量的调试信息//
 | ||||
| 
 | ||||
| //用于比较两个排序元素的值//
 | ||||
| STATIC BOOL SemCompareValue(const SortParam *sortParam, UINT32 left, UINT32 right) | ||||
| { | ||||
|     return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > | ||||
|             *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); | ||||
| } | ||||
| 
 | ||||
| UINT32 OsSemDbgInit(VOID)   //用于初始化信号量的调试信息数组//
 | ||||
| { | ||||
|     UINT32 size = LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(SemDebugCB); | ||||
|     /* system resident memory, don't free */ | ||||
|     g_semDebugArray = (SemDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); | ||||
|     if (g_semDebugArray == NULL) { | ||||
|         PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); | ||||
|         return LOS_NOK; | ||||
|     } | ||||
|     (VOID)memset_s(g_semDebugArray, size, 0, size); | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| VOID OsSemDbgTimeUpdate(UINT32 semId)   //用于更新指定信号量的最后一次访问时间//
 | ||||
| { | ||||
|     SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semId)]; | ||||
|     semDebug->lastAccessTime = LOS_TickCountGet(); | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| VOID OsSemDbgUpdate(UINT32 semId, TSK_ENTRY_FUNC creator, UINT16 count) //用于更新指定信号量的调试信息//
 | ||||
| { | ||||
|     SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semId)]; | ||||
|     semDebug->creator = creator; | ||||
|     semDebug->lastAccessTime = LOS_TickCountGet(); | ||||
|     semDebug->origSemCount = count; | ||||
|     return; | ||||
| } | ||||
| 
 | ||||
| /*用于按照信号量的最后访问时间对当前正在使用的信号量进行排序,*/ | ||||
| /*并打印每个信号量的调试信息和等待该信号量的任务名*/ | ||||
| STATIC VOID OsSemSort(UINT32 *semIndexArray, UINT32 usedCount)   | ||||
| { | ||||
|     UINT32 i, intSave; | ||||
|     LosSemCB *semCB = NULL; | ||||
|     LosSemCB semNode = {0}; | ||||
|     SemDebugCB semDebug = {0}; | ||||
|     SortParam semSortParam; | ||||
|     semSortParam.buf = (CHAR *)g_semDebugArray; | ||||
|     semSortParam.ctrlBlockSize = sizeof(SemDebugCB); | ||||
|     semSortParam.ctrlBlockCnt = LOSCFG_BASE_IPC_SEM_LIMIT; | ||||
|     semSortParam.sortElemOff = LOS_OFF_SET_OF(SemDebugCB, lastAccessTime); | ||||
| 
 | ||||
|     /* It will Print out ALL the Used Semaphore List. */ | ||||
|     PRINTK("Used Semaphore List: \n"); | ||||
|     PRINTK("\r\n   SemID    Count    OriginalCount   Creater(TaskEntry)    LastAccessTime\n"); | ||||
|     PRINTK("   ------   ------   -------------   ------------------    --------------   \n"); | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
|     OsArraySort(semIndexArray, 0, usedCount - 1, &semSortParam, SemCompareValue); | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
|     for (i = 0; i < usedCount; i++) { | ||||
|         semCB = GET_SEM(semIndexArray[i]); | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); | ||||
|         (VOID)memcpy_s(&semDebug, sizeof(SemDebugCB), &g_semDebugArray[semIndexArray[i]], sizeof(SemDebugCB)); | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         if ((semNode.semStat != LOS_USED) || (semDebug.creator == NULL)) { | ||||
|             continue; | ||||
|         } | ||||
|         PRINTK("   0x%-07x0x%-07u0x%-14u%-22p0x%llx\n", semNode.semId, semDebug.origSemCount, | ||||
|                semNode.semCount, semDebug.creator, semDebug.lastAccessTime); | ||||
|         if (!LOS_ListEmpty(&semNode.semList)) { | ||||
|             OsSemPendedTaskNamePrint(semCB); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| /*用于获取当前正在使用的信号量信息,并按照信号量的最后访问时间对信号量进行排序*/ | ||||
| UINT32 OsSemInfoGetFullData(VOID) | ||||
| { | ||||
|     UINT32 usedSemCnt = 0; | ||||
|     LosSemCB *semNode = NULL; | ||||
|     SemDebugCB *semDebug = NULL; | ||||
|     UINT32 i; | ||||
|     UINT32 *semIndexArray = NULL; | ||||
|     UINT32 count, intSave; | ||||
| 
 | ||||
|     SCHEDULER_LOCK(intSave); | ||||
|     /* Get the used semaphore count. */ | ||||
|     for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { | ||||
|         semNode = GET_SEM(i); | ||||
|         semDebug = &g_semDebugArray[i]; | ||||
|         if ((semNode->semStat == LOS_USED) && (semDebug->creator != NULL)) { | ||||
|             usedSemCnt++; | ||||
|         } | ||||
|     } | ||||
|     SCHEDULER_UNLOCK(intSave); | ||||
| 
 | ||||
|     if (usedSemCnt > 0) { | ||||
|         semIndexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, usedSemCnt * sizeof(UINT32)); | ||||
|         if (semIndexArray == NULL) { | ||||
|             PRINTK("LOS_MemAlloc failed in %s \n", __func__); | ||||
|             return LOS_NOK; | ||||
|         } | ||||
| 
 | ||||
|         /* Fill the semIndexArray with the real index. */ | ||||
|         count = 0; | ||||
| 
 | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) { | ||||
|             semNode = GET_SEM(i); | ||||
|             semDebug = &g_semDebugArray[i]; | ||||
|             if ((semNode->semStat != LOS_USED) || (semDebug->creator == NULL)) { | ||||
|                 continue; | ||||
|             } | ||||
|             *(semIndexArray + count) = i; | ||||
|             count++; | ||||
|             /* if the count is touched usedSemCnt break. */ | ||||
|             if (count >= usedSemCnt) { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         OsSemSort(semIndexArray, count); | ||||
| 
 | ||||
|         /* free the index array. */ | ||||
|         (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, semIndexArray); | ||||
|     } | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_SHELL | ||||
| STATIC UINT32 OsSemInfoOutput(size_t semId)     //用于输出信号量信息//
 | ||||
| { | ||||
|     UINT32 loop, semCnt, intSave; | ||||
|     LosSemCB *semCB = NULL; | ||||
|     LosSemCB semNode = {0}; | ||||
| 
 | ||||
|     if (semId == OS_ALL_SEM_MASK) { | ||||
|         for (loop = 0, semCnt = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) { | ||||
|             semCB = GET_SEM(loop); | ||||
|             SCHEDULER_LOCK(intSave); | ||||
|             if (semCB->semStat == LOS_USED) { | ||||
|                 (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); | ||||
|                 SCHEDULER_UNLOCK(intSave); | ||||
|                 semCnt++; | ||||
|                 PRINTK("\r\n   SemID       Count\n   ----------  -----\n"); | ||||
|                 PRINTK("   0x%08x  %u\n", semNode.semId, semNode.semCount); | ||||
|                 continue; | ||||
|             } | ||||
|             SCHEDULER_UNLOCK(intSave); | ||||
|         } | ||||
|         PRINTK("   SemUsingNum    :  %u\n\n", semCnt); | ||||
|         return LOS_OK; | ||||
|     } else { | ||||
|         semCB = GET_SEM(semId); | ||||
|         SCHEDULER_LOCK(intSave); | ||||
|         (VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB)); | ||||
|         SCHEDULER_UNLOCK(intSave); | ||||
|         if ((semNode.semId != semId) || (semNode.semStat != LOS_USED)) { | ||||
|             PRINTK("\nThe semaphore is not in use!\n"); | ||||
|             return LOS_OK; | ||||
|         } | ||||
| 
 | ||||
|         PRINTK("\r\n   SemID       Count\n   ----------  -----\n"); | ||||
|         PRINTK("   0x%08x      0x%u\n", semNode.semId, semNode.semCount); | ||||
| 
 | ||||
|         if (LOS_ListEmpty(&semNode.semList)) { | ||||
|             PRINTK("No task is pended on this semaphore!\n"); | ||||
|             return LOS_OK; | ||||
|         } else { | ||||
|             OsSemPendedTaskNamePrint(semCB); | ||||
|         } | ||||
|     } | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| //用于获取信号量信息//
 | ||||
| LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSemInfoGet(UINT32 argc, const CHAR **argv) | ||||
| { | ||||
|     size_t semId; | ||||
|     CHAR *endPtr = NULL; | ||||
|     UINT32 ret; | ||||
| 
 | ||||
|     if (argc > 1) { | ||||
|         PRINTK("\nUsage: sem [fulldata|ID]\n"); | ||||
|         return OS_ERROR; | ||||
|     } | ||||
| 
 | ||||
|     if (argc == 0) { | ||||
|         semId = OS_ALL_SEM_MASK; | ||||
|     } else { | ||||
|         if (strcmp(argv[0], "fulldata") == 0) { | ||||
|             ret = OsSemInfoGetFullData(); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         semId = strtoul(argv[0], &endPtr, 0); | ||||
|         if ((*endPtr != 0) || (GET_SEM_INDEX(semId) >= LOSCFG_BASE_IPC_SEM_LIMIT)) { | ||||
|             PRINTK("\nsem ID can't access %s.\n", argv[0]); | ||||
|             return OS_ERROR; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     ret = OsSemInfoOutput(semId); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet); | ||||
| #endif /* LOSCFG_SHELL */ | ||||
| #endif /* LOSCFG_DEBUG_SEMAPHORE */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif | ||||
| #endif /* __cplusplus */ | ||||
											
												Binary file not shown.
											
										
									
								| @ -1,53 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. | ||||
|  * Description: Cpp Support HeadFile | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2013-01-01 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _LOS_CPPSUPPORT_PRI_H | ||||
| #define _LOS_CPPSUPPORT_PRI_H       //防止多次包含同一个头文件//
 | ||||
| 
 | ||||
| #include "los_cppsupport.h" | ||||
| 
 | ||||
| #ifdef __cplusplus					//根据编译器是否为C++//
 | ||||
| #if __cplusplus						//来使用“extern 'C'”//
 | ||||
| extern "C" {						//对以下代码块内容进行//
 | ||||
| #endif /* __cplusplus */			//正确处理函数名//
 | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| extern CHAR __fast_end;				//声明一个_fast_end的CHAR类型变量//
 | ||||
| 
 | ||||
| #ifdef LOSCFG_AARCH64				//条件编译//
 | ||||
| extern UINT8 __EH_FRAME_BEGIN__[];	//声明一个UINT8类型的数组//
 | ||||
| VOID __register_frame(VOID *begin);	 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */			//关闭extern'C'作用域//
 | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #endif /* _LOS_CPPSUPPORT_PRI_H */ | ||||
| @ -1,150 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Module Private HeadFile | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2019-08-30 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _LOS_TRACE_PRI_H | ||||
| #define _LOS_TRACE_PRI_H | ||||
| 
 | ||||
| #include "los_trace.h" | ||||
| #include "los_task_pri.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CONTROL_AGENT | ||||
| #define TRACE_CMD_END_CHAR                  0xD | ||||
| #endif | ||||
| 
 | ||||
| #define TRACE_ERROR                         PRINT_ERR | ||||
| #define TRACE_MODE_OFFLINE                  0 | ||||
| #define TRACE_MODE_ONLINE                   1 | ||||
| 
 | ||||
| /* just task and hwi were traced */ | ||||
| #define TRACE_DEFAULT_MASK                  (TRACE_HWI_FLAG | TRACE_TASK_FLAG) | ||||
| #define TRACE_CTL_MAGIC_NUM                 0xDEADBEEF | ||||
| #define TRACE_BIGLITTLE_WORD                0x12345678 | ||||
| #define TRACE_VERSION(MODE)                 (0xFFFFFFFF & (MODE)) | ||||
| #define TRACE_MASK_COMBINE(c1, c2, c3, c4)  (((c1) << 24) | ((c2) << 16) | ((c3) << 8) | (c4)) | ||||
| 
 | ||||
| #define TRACE_GET_MODE_FLAG(type)           ((type) & 0xFFFFFFF0) | ||||
| 
 | ||||
| extern SPIN_LOCK_S g_traceSpin; | ||||
| #define TRACE_LOCK(state)                   LOS_SpinLockSave(&g_traceSpin, &(state)) | ||||
| #define TRACE_UNLOCK(state)                 LOS_SpinUnlockRestore(&g_traceSpin, (state)) | ||||
| 
 | ||||
| typedef VOID (*TRACE_DUMP_HOOK)(BOOL toClient); | ||||
| extern TRACE_DUMP_HOOK g_traceDumpHook; | ||||
| 
 | ||||
| enum TraceCmd { | ||||
|     TRACE_CMD_START = 1, | ||||
|     TRACE_CMD_STOP, | ||||
|     TRACE_CMD_SET_EVENT_MASK, | ||||
|     TRACE_CMD_RECODE_DUMP, | ||||
|     TRACE_CMD_MAX_CODE, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup los_trace | ||||
|  * struct to store the trace cmd from traceClient. | ||||
|  */ | ||||
| typedef struct { | ||||
|     UINT8 cmd; | ||||
|     UINT8 param1; | ||||
|     UINT8 param2; | ||||
|     UINT8 param3; | ||||
|     UINT8 param4; | ||||
|     UINT8 param5; | ||||
|     UINT8 end; | ||||
| } TraceClientCmd; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup los_trace | ||||
|  * struct to store the event infomation | ||||
|  */ | ||||
| typedef struct { | ||||
|     UINT32 cmd;     /* trace start or stop cmd */ | ||||
|     UINT32 param;   /* magic numb stand for notify msg */ | ||||
| } TraceNotifyFrame; | ||||
| 
 | ||||
| /**
 | ||||
|  * @ingroup los_trace | ||||
|  * struct to store the trace config information. | ||||
|  */ | ||||
| typedef struct { | ||||
|     struct WriteCtrl { | ||||
|         UINT16 curIndex;            /* The current record index */ | ||||
|         UINT16 maxRecordCount;      /* The max num of track items */ | ||||
|         UINT16 curObjIndex;         /* The current obj index */ | ||||
|         UINT16 maxObjCount;         /* The max num of obj index */ | ||||
|         ObjData *objBuf;            /* Pointer to obj info data */ | ||||
|         TraceEventFrame *frameBuf;  /* Pointer to the track items */ | ||||
|     } ctrl; | ||||
|     OfflineHead *head; | ||||
| } TraceOfflineHeaderInfo; | ||||
| 
 | ||||
| extern UINT32 OsTraceGetMaskTid(UINT32 taskId); | ||||
| extern VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb); | ||||
| extern VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame); | ||||
| extern UINT32 OsTraceBufInit(VOID *buf, UINT32 size); | ||||
| extern VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId); | ||||
| extern BOOL OsTraceIsEnable(VOID); | ||||
| extern OfflineHead *OsTraceRecordGet(VOID); | ||||
| 
 | ||||
| #ifdef LOSCFG_RECORDER_MODE_ONLINE | ||||
| extern VOID OsTraceSendHead(VOID); | ||||
| extern VOID OsTraceSendObjTable(VOID); | ||||
| extern VOID OsTraceSendNotify(UINT32 type, UINT32 value); | ||||
| 
 | ||||
| #define OsTraceNotifyStart() do {                                \ | ||||
|         OsTraceSendNotify(SYS_START, TRACE_CTL_MAGIC_NUM);       \ | ||||
|         OsTraceSendHead();                                       \ | ||||
|         OsTraceSendObjTable();                                   \ | ||||
|     } while (0) | ||||
| 
 | ||||
| #define OsTraceNotifyStop() do {                                 \ | ||||
|         OsTraceSendNotify(SYS_STOP, TRACE_CTL_MAGIC_NUM);        \ | ||||
|     } while (0) | ||||
| 
 | ||||
| #define OsTraceReset() | ||||
| #define OsTraceRecordDump(toClient) | ||||
| #else | ||||
| extern VOID OsTraceReset(VOID); | ||||
| extern VOID OsTraceRecordDump(BOOL toClient); | ||||
| #define OsTraceNotifyStart() | ||||
| #define OsTraceNotifyStop() | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #endif /* _LOS_TRACE_PRI_H */ | ||||
| @ -1,424 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Implementation | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2019-08-31 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| #include "uart.h" | ||||
| #include "los_trace_pri.h" | ||||
| #include "trace_pipeline.h" | ||||
| 
 | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
| #include "los_mp_pri.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LOSCFG_SHELL | ||||
| #include "shcmd.h" | ||||
| #include "shell.h" | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_KERNEL_TRACE | ||||
| LITE_OS_SEC_BSS STATIC UINT32 g_traceEventCount;    //追踪事件计数//
 | ||||
| LITE_OS_SEC_BSS STATIC volatile enum TraceState g_traceState = TRACE_UNINIT;    //追踪状态//
 | ||||
| LITE_OS_SEC_DATA_INIT STATIC volatile BOOL g_enableTrace = FALSE;   //是否启用追踪功能//
 | ||||
| LITE_OS_SEC_BSS STATIC UINT32 g_traceMask = TRACE_DEFAULT_MASK; //追踪掩码,用于过滤追踪事件//
 | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CONTROL_AGENT | ||||
| LITE_OS_SEC_BSS STATIC UINT32 g_traceTaskId;    //追踪任务的ID//
 | ||||
| #endif | ||||
| 
 | ||||
| #define EVENT_MASK            0xFFFFFFF0 | ||||
| #define MIN(x, y)             ((x) < (y) ? (x) : (y)) | ||||
| 
 | ||||
| LITE_OS_SEC_BSS STATIC TRACE_HWI_FILTER_HOOK g_traceHwiFliterHook = NULL; | ||||
| 
 | ||||
| LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_traceSpin); | ||||
| 
 | ||||
| STATIC_INLINE BOOL OsTraceHwiFilter(UINT32 hwiNum)  //用于判断是否需要过滤某个硬件中断//
 | ||||
| { | ||||
|     BOOL ret = ((hwiNum == NUM_HAL_INTERRUPT_UART) || (hwiNum == OS_TICK_INT_NUM)); | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|     ret |= (hwiNum == LOS_MP_IPI_SCHEDULE); | ||||
| #endif | ||||
|     if (g_traceHwiFliterHook != NULL) { | ||||
|         ret |= g_traceHwiFliterHook(hwiNum); | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| //用于设置追踪事件的帧信息//
 | ||||
| STATIC VOID OsTraceSetFrame(TraceEventFrame *frame, UINT32 eventType, UINTPTR identity, const UINTPTR *params, | ||||
|     UINT16 paramCount) | ||||
| { | ||||
|     INT32 i; | ||||
|     UINT32 intSave; | ||||
| 
 | ||||
|     (VOID)memset_s(frame, sizeof(TraceEventFrame), 0, sizeof(TraceEventFrame)); | ||||
| 
 | ||||
|     if (paramCount > LOSCFG_TRACE_FRAME_MAX_PARAMS) { | ||||
|         paramCount = LOSCFG_TRACE_FRAME_MAX_PARAMS; | ||||
|     } | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     frame->curTask   = OsTraceGetMaskTid(OsCurrTaskGet()->taskId); | ||||
|     frame->identity  = identity; | ||||
|     frame->curTime   = HalClockGetCycles(); | ||||
|     frame->eventType = eventType; | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_FRAME_CORE_MSG | ||||
|     frame->core.cpuId      = ArchCurrCpuid();   //CPU的ID//
 | ||||
|     frame->core.hwiActive  = OS_INT_ACTIVE ? TRUE : FALSE;  //硬件中断活动状态//
 | ||||
|     frame->core.taskLockCnt = MIN(OsPercpuGet()->taskLockCnt, 0xF); /* taskLockCnt is 4 bits, max vaule = 0xF */    //任务锁计数//
 | ||||
|     frame->core.paramCount = paramCount;    //参数数目//
 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT | ||||
|     frame->eventCount = g_traceEventCount;  //追踪事件的计数//
 | ||||
|     g_traceEventCount++; | ||||
| #endif | ||||
|     TRACE_UNLOCK(intSave); | ||||
| 
 | ||||
|     for (i = 0; i < paramCount; i++) { | ||||
|         frame->params[i] = params[i]; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceSetObj(ObjData *obj, const LosTaskCB *tcb)  //设置对象的追踪信息//
 | ||||
| { | ||||
|     errno_t ret; | ||||
|     (VOID)memset_s(obj, sizeof(ObjData), 0, sizeof(ObjData)); | ||||
| 
 | ||||
|     obj->id   = OsTraceGetMaskTid(tcb->taskId); //获取任务ID//
 | ||||
|     obj->prio = tcb->priority;  //获取任务优先级//
 | ||||
| 
 | ||||
|     ret = strncpy_s(obj->name, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE, tcb->taskName, LOSCFG_TRACE_OBJ_MAX_NAME_SIZE - 1); | ||||
|     if (ret != EOK) { | ||||
|         TRACE_ERROR("Task name copy failed!\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| //处理追踪事件钩子//
 | ||||
| VOID OsTraceHook(UINT32 eventType, UINTPTR identity, const UINTPTR *params, UINT16 paramCount) | ||||
| { | ||||
|     if ((eventType == TASK_CREATE) || (eventType == TASK_PRIOSET)) { | ||||
|         OsTraceObjAdd(eventType, identity); /* handle important obj info, these can not be filtered */ | ||||
|     } | ||||
| 
 | ||||
|     if ((g_enableTrace == TRUE) && (eventType & g_traceMask)) { | ||||
|         UINTPTR id = identity; | ||||
|         if (TRACE_GET_MODE_FLAG(eventType) == TRACE_HWI_FLAG) { | ||||
|             if (OsTraceHwiFilter(identity)) {    | ||||
|                 return; | ||||
|             } | ||||
|         } else if (TRACE_GET_MODE_FLAG(eventType) == TRACE_TASK_FLAG) { | ||||
|             id = OsTraceGetMaskTid(identity); | ||||
|         } else if (eventType == MEM_INFO_REQ) { | ||||
|             LOS_MEM_POOL_STATUS status; | ||||
|             LOS_MemInfoGet((VOID *)identity, &status); | ||||
|             LOS_TRACE(MEM_INFO, identity, status.uwTotalUsedSize, status.uwTotalFreeSize); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         TraceEventFrame frame; | ||||
|         OsTraceSetFrame(&frame, eventType, id, params, paramCount); | ||||
| 
 | ||||
|         OsTraceWriteOrSendEvent(&frame); //将追踪事件信息写入或发送出去//
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| BOOL OsTraceIsEnable(VOID)  //判断追踪是否处于启用状态//
 | ||||
| { | ||||
|     return g_enableTrace == TRUE; | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceHookInstall(VOID)    //安装追踪钩子//
 | ||||
| { | ||||
|     g_traceEventHook = OsTraceHook; | ||||
| #ifdef LOSCFG_RECORDER_MODE_OFFLINE | ||||
|     g_traceDumpHook = OsTraceRecordDump;    //在离线记录模式下设置追踪转储钩子//
 | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CONTROL_AGENT | ||||
| STATIC BOOL OsTraceCmdIsValid(const TraceClientCmd *msg)    //判断传入的TraceClientCmd结构体是否有效//
 | ||||
| { | ||||
|     return ((msg->end == TRACE_CMD_END_CHAR) && (msg->cmd < TRACE_CMD_MAX_CODE)); | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceCmdHandle(const TraceClientCmd *msg) //处理传入的TraceClientCmd结构体//
 | ||||
| { | ||||
|     if (!OsTraceCmdIsValid(msg)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     switch (msg->cmd) { | ||||
|         case TRACE_CMD_START:   //启动追踪//
 | ||||
|             LOS_TraceStart(); | ||||
|             break; | ||||
|         case TRACE_CMD_STOP:    //停止追踪//
 | ||||
|             LOS_TraceStop(); | ||||
|             break; | ||||
|         case TRACE_CMD_SET_EVENT_MASK:  //设置事件掩码//
 | ||||
|             /* 4 params(UINT8) composition the mask(UINT32) */ | ||||
|             LOS_TraceEventMaskSet(TRACE_MASK_COMBINE(msg->param1, msg->param2, msg->param3, msg->param4)); | ||||
|             break; | ||||
|         case TRACE_CMD_RECODE_DUMP: //追踪记录转储//
 | ||||
|             LOS_TraceRecordDump(TRUE); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| VOID TraceAgent(VOID)   //不断等待追踪数据的到达,并处理接收到的追踪命令//
 | ||||
| { | ||||
|     UINT32 ret; | ||||
|     TraceClientCmd msg; | ||||
| 
 | ||||
|     while (1) { | ||||
|         (VOID)memset_s(&msg, sizeof(TraceClientCmd), 0, sizeof(TraceClientCmd)); | ||||
|         ret = OsTraceDataWait(); | ||||
|         if (ret == LOS_OK) { | ||||
|             OsTraceDataRecv((UINT8 *)&msg, sizeof(TraceClientCmd), 0); | ||||
|             OsTraceCmdHandle(&msg); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| STATIC UINT32 OsCreateTraceAgentTask(VOID)      //创建一个追踪代理任务,用于执行追踪逻辑//
 | ||||
| { | ||||
|     UINT32 ret; | ||||
|     TSK_INIT_PARAM_S taskInitParam; | ||||
| 
 | ||||
|     (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); | ||||
|     taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)TraceAgent; | ||||
|     taskInitParam.usTaskPrio = LOSCFG_TRACE_TASK_PRIORITY; | ||||
|     taskInitParam.pcName = "TraceAgent"; | ||||
|     taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|     taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(ArchCurrCpuid()); | ||||
| #endif | ||||
|     ret = LOS_TaskCreate(&g_traceTaskId, &taskInitParam); | ||||
|     return ret; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| UINT32 LOS_TraceInit(VOID *buf, UINT32 size)    //初始化追踪功能//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
|     UINT32 ret; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     if (g_traceState != TRACE_UNINIT) { | ||||
|         TRACE_ERROR("trace has been initialized already, the current state is :%d\n", g_traceState); | ||||
|         ret = LOS_ERRNO_TRACE_ERROR_STATUS; | ||||
|         goto LOS_ERREND; | ||||
|     } | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CLIENT_INTERACT //判断是否需要初始化追踪管道//
 | ||||
|     ret = OsTracePipelineInit(); | ||||
|     if (ret != LOS_OK) { | ||||
|         goto LOS_ERREND; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CONTROL_AGENT   //判断是否需要创建追踪代理任务//
 | ||||
|     ret = OsCreateTraceAgentTask(); | ||||
|     if (ret != LOS_OK) { | ||||
|         TRACE_ERROR("trace init create agentTask error :0x%x\n", ret); | ||||
|         goto LOS_ERREND; | ||||
|     } | ||||
| #endif | ||||
| 
 | ||||
|     ret = OsTraceBufInit(buf, size);    //初始化追踪缓冲区//
 | ||||
|     if (ret != LOS_OK) { | ||||
|         goto LOS_RELEASE; | ||||
|     } | ||||
| 
 | ||||
|     OsTraceHookInstall();   //安装追踪钩子//
 | ||||
| 
 | ||||
|     g_traceEventCount = 0; | ||||
| 
 | ||||
|     /*判断是否需要等待追踪客户端启动追踪*/ | ||||
| #ifdef LOSCFG_RECORDER_MODE_ONLINE  /* Wait trace client to start trace */ | ||||
|     g_enableTrace = FALSE; | ||||
|     g_traceState = TRACE_INITED; | ||||
| #else | ||||
|     g_enableTrace = TRUE; | ||||
|     g_traceState = TRACE_STARTED; | ||||
| #endif | ||||
|     TRACE_UNLOCK(intSave); | ||||
|     return LOS_OK; | ||||
| LOS_RELEASE: | ||||
| #ifdef LOSCFG_TRACE_CONTROL_AGENT   //判断是否需要删除追踪代理任务//
 | ||||
|     LOS_TaskDelete(g_traceTaskId); | ||||
| #endif | ||||
| LOS_ERREND: | ||||
|     TRACE_UNLOCK(intSave); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| UINT32 LOS_TraceStart(VOID)     //用于启动追踪功能//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
|     UINT32 ret = LOS_OK; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     if (g_traceState == TRACE_STARTED) { | ||||
|         goto START_END; | ||||
|     } | ||||
| 
 | ||||
|     if (g_traceState == TRACE_UNINIT) { | ||||
|         TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n"); | ||||
|         ret = LOS_ERRNO_TRACE_ERROR_STATUS; | ||||
|         goto START_END; | ||||
|     } | ||||
| 
 | ||||
|     OsTraceNotifyStart();       //通知追踪功能开始工作//
 | ||||
| 
 | ||||
|     g_enableTrace = TRUE; | ||||
|     g_traceState = TRACE_STARTED; | ||||
| 
 | ||||
|     TRACE_UNLOCK(intSave); | ||||
|     LOS_TRACE(MEM_INFO_REQ, m_aucSysMem0);  //发送追踪信息//
 | ||||
|     return ret; | ||||
| START_END: | ||||
|     TRACE_UNLOCK(intSave); | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| VOID LOS_TraceStop(VOID)    //用于停止追踪功能//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     if (g_traceState != TRACE_STARTED) { | ||||
|         goto STOP_END; | ||||
|     } | ||||
| 
 | ||||
|     g_enableTrace = FALSE; | ||||
|     g_traceState = TRACE_STOPED; | ||||
|     OsTraceNotifyStop();    //通知追踪功能停止工作//
 | ||||
| STOP_END: | ||||
|     TRACE_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| VOID LOS_TraceEventMaskSet(UINT32 mask) //设置追踪事件掩码//
 | ||||
| { | ||||
|     g_traceMask = mask & EVENT_MASK; | ||||
| } | ||||
| 
 | ||||
| VOID LOS_TraceRecordDump(BOOL toClient) //转储追踪记录//
 | ||||
| { | ||||
|     if (g_traceState != TRACE_STOPED) { | ||||
|         TRACE_ERROR("trace dump must after trace stopped , the current state is : %d\n", g_traceState); | ||||
|         return; | ||||
|     } | ||||
|     OsTraceRecordDump(toClient); | ||||
| } | ||||
| 
 | ||||
| OfflineHead *LOS_TraceRecordGet(VOID)   //获取追踪记录//
 | ||||
| { | ||||
|     return OsTraceRecordGet(); | ||||
| } | ||||
| 
 | ||||
| VOID LOS_TraceReset(VOID)   //重置追踪功能//
 | ||||
| { | ||||
|     if (g_traceState == TRACE_UNINIT) { | ||||
|         TRACE_ERROR("trace not inited, be sure LOS_TraceInit excute success\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     OsTraceReset(); | ||||
| } | ||||
| 
 | ||||
| VOID LOS_TraceHwiFilterHookReg(TRACE_HWI_FILTER_HOOK hook)  //注册中断过滤钩子//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     g_traceHwiFliterHook = hook; | ||||
|     TRACE_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_SHELL | ||||
| LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceSetMask(INT32 argc, const CHAR **argv) //设置追踪事件掩码//
 | ||||
| { | ||||
|     size_t mask; | ||||
|     CHAR *endPtr = NULL; | ||||
| 
 | ||||
|     if (argc >= 2) { /* 2:Just as number of parameters */ | ||||
|         PRINTK("\nUsage: trace_mask or trace_mask ID\n"); | ||||
|         return OS_ERROR; | ||||
|     } | ||||
| 
 | ||||
|     if (argc == 0) { | ||||
|         mask = TRACE_DEFAULT_MASK; | ||||
|     } else { | ||||
|         mask = strtoul(argv[0], &endPtr, 0); | ||||
|     } | ||||
|     LOS_TraceEventMaskSet((UINT32)mask); | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTraceDump(INT32 argc, const CHAR **argv)    //进行追踪记录的转储//
 | ||||
| { | ||||
|     BOOL toClient; | ||||
|     CHAR *endPtr = NULL; | ||||
| 
 | ||||
|     if (argc >= 2) { /* 2:Just as number of parameters */ | ||||
|         PRINTK("\nUsage: trace_dump or trace_dump [1/0]\n"); | ||||
|         return OS_ERROR; | ||||
|     } | ||||
| 
 | ||||
|     if (argc == 0) { | ||||
|         toClient = FALSE; | ||||
|     } else { | ||||
|         toClient = strtoul(argv[0], &endPtr, 0) != 0 ? TRUE : FALSE; | ||||
|     } | ||||
|     LOS_TraceRecordDump(toClient); | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| /*命令行函数的注册*/ | ||||
| SHELLCMD_ENTRY(tracestart_shellcmd,   CMD_TYPE_EX, "trace_start", 0, (CmdCallBackFunc)LOS_TraceStart);  //追踪功能的启动//
 | ||||
| SHELLCMD_ENTRY(tracestop_shellcmd,    CMD_TYPE_EX, "trace_stop",  0, (CmdCallBackFunc)LOS_TraceStop);   //追踪功能的停止//
 | ||||
| SHELLCMD_ENTRY(tracesetmask_shellcmd, CMD_TYPE_EX, "trace_mask",  1, (CmdCallBackFunc)OsShellCmdTraceSetMask);  //设置追踪事件掩码//
 | ||||
| SHELLCMD_ENTRY(tracereset_shellcmd,   CMD_TYPE_EX, "trace_reset", 0, (CmdCallBackFunc)LOS_TraceReset);  //重置追踪记录//
 | ||||
| SHELLCMD_ENTRY(tracedump_shellcmd,    CMD_TYPE_EX, "trace_dump", 1, (CmdCallBackFunc)OsShellCmdTraceDump);  //转储追踪记录//
 | ||||
| #endif | ||||
| 
 | ||||
| #endif /* LOSCFG_KERNEL_TRACE */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,50 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Pipeline of Serial Implementation HeadFile | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2020-03-16 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _TRACE_PIPELINE_SERIAL_H | ||||
| #define _TRACE_PIPELINE_SERIAL_H | ||||
| 
 | ||||
| #include "los_typedef.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| extern INT32 uart_putc(CHAR c);			//用于向串口发送一个字符//
 | ||||
| 
 | ||||
| #define UART_PUTC(c) uart_putc((c))		//调用uart_putc函数//
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #endif /* _TRACE_PIPELINE_SERIAL_H */ | ||||
| @ -1,156 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Pipeline Implementation | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2020-03-31 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "trace_pipeline.h" | ||||
| #include "trace_tlv.h" | ||||
| #include "los_trace_pri.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| //防止缓冲区溢出//
 | ||||
| LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_pipeSpin);         //初始化一个自旋锁//
 | ||||
| #define PIPE_LOCK(state)                   LOS_SpinLockSave(&g_pipeSpin, &(state))          //对自旋锁加锁操作//
 | ||||
| #define PIPE_UNLOCK(state)                 LOS_SpinUnlockRestore(&g_pipeSpin, (state))      //对自旋锁解锁操作//
 | ||||
| 
 | ||||
| STATIC TlvTable g_traceTlvTblNotify[] = {   //定义结构体的成员变量类型和大小//
 | ||||
|     { CMD,    LOS_OFF_SET_OF(TraceNotifyFrame, cmd),   sizeof(UINT32) }, | ||||
|     { PARAMS, LOS_OFF_SET_OF(TraceNotifyFrame, param), sizeof(UINT32) }, | ||||
|     { TRACE_TLV_TYPE_NULL, 0, 0 }, | ||||
| }; | ||||
| 
 | ||||
| STATIC TlvTable g_traceTlvTblHead[] = {   //定义结构体的成员变量类型和大小//
 | ||||
|     { ENDIAN,     LOS_OFF_SET_OF(TraceBaseHeaderInfo, bigLittleEndian), sizeof(UINT32) }, | ||||
|     { VERSION,    LOS_OFF_SET_OF(TraceBaseHeaderInfo, version),         sizeof(UINT32) }, | ||||
|     { CLOCK_FREQ, LOS_OFF_SET_OF(TraceBaseHeaderInfo, clockFreq),       sizeof(UINT32) }, | ||||
|     { TRACE_TLV_TYPE_NULL, 0, 0 }, | ||||
| }; | ||||
| 
 | ||||
| STATIC TlvTable g_traceTlvTblObj[] = {   //定义结构体的成员变量类型、偏移位置和大小//
 | ||||
|     { ADDR, LOS_OFF_SET_OF(ObjData, id),   sizeof(UINT32) }, | ||||
|     { PRIO, LOS_OFF_SET_OF(ObjData, prio), sizeof(UINT32) }, | ||||
|     { NAME, LOS_OFF_SET_OF(ObjData, name), sizeof(CHAR) * LOSCFG_TRACE_OBJ_MAX_NAME_SIZE }, | ||||
|     { TRACE_TLV_TYPE_NULL, 0, 0 }, | ||||
| }; | ||||
| 
 | ||||
| STATIC TlvTable g_traceTlvTblEvent[] = {    //定义结构体的成员变量类型和大小//
 | ||||
| #ifdef LOSCFG_TRACE_FRAME_CORE_MSG | ||||
|     { CORE,         LOS_OFF_SET_OF(TraceEventFrame, core),       sizeof(UINT32) }, | ||||
| #endif | ||||
|     { EVENT_CODE,   LOS_OFF_SET_OF(TraceEventFrame, eventType),  sizeof(UINT32) }, | ||||
|     { CUR_TIME,     LOS_OFF_SET_OF(TraceEventFrame, curTime),    sizeof(UINT64) }, | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT | ||||
|     { EVENT_COUNT,  LOS_OFF_SET_OF(TraceEventFrame, eventCount), sizeof(UINT32) }, | ||||
| #endif | ||||
|     { CUR_TASK,     LOS_OFF_SET_OF(TraceEventFrame, curTask),    sizeof(UINT32) }, | ||||
|     { IDENTITY,     LOS_OFF_SET_OF(TraceEventFrame, identity),   sizeof(UINTPTR) }, | ||||
|     { EVENT_PARAMS, LOS_OFF_SET_OF(TraceEventFrame, params),     sizeof(UINTPTR) * LOSCFG_TRACE_FRAME_MAX_PARAMS }, | ||||
|     { TRACE_TLV_TYPE_NULL, 0, 0 }, | ||||
| }; | ||||
| 
 | ||||
| STATIC TlvTable *g_traceTlvTbl[] = { | ||||
|     g_traceTlvTblNotify, | ||||
|     g_traceTlvTblHead, | ||||
|     g_traceTlvTblObj, | ||||
|     g_traceTlvTblEvent | ||||
| }; | ||||
| 
 | ||||
| STATIC UINT32 DefaultPipelineInit(VOID) | ||||
| { | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| STATIC VOID DefaultDataSend(UINT16 len, UINT8 *data)     | ||||
| {                                                      //将len和data参数标记为"未使用"//
 | ||||
|     (VOID)len;                                           //避免编译器产生警告//
 | ||||
|     (VOID)data; | ||||
| } | ||||
| 
 | ||||
| STATIC UINT32 DefaultDataReceive(UINT8 *data, UINT32 size, UINT32 timeout) | ||||
| { | ||||
|     (VOID)data;                                     //将data、size和timeout参数标记为"未使用"//
 | ||||
|     (VOID)size;                                       | ||||
|     (VOID)timeout; | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| STATIC UINT32 DefaultWait(VOID) | ||||
| { | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| STATIC TracePipelineOps g_defaultOps = { | ||||
|     .init = DefaultPipelineInit, | ||||
|     .dataSend = DefaultDataSend, | ||||
|     .dataRecv = DefaultDataReceive, | ||||
|     .wait = DefaultWait, | ||||
| }; | ||||
| 
 | ||||
| STATIC const TracePipelineOps *g_tracePipelineOps = &g_defaultOps; | ||||
| 
 | ||||
| VOID OsTracePipelineReg(const TracePipelineOps *ops) | ||||
| { | ||||
|     g_tracePipelineOps = ops;   //用于注册一个TracePipelineOps结构体指针//
 | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data)   //用于发送追踪数据//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
|     UINT8 outBuf[LOSCFG_TRACE_TLV_BUF_SIZE] = {0}; | ||||
| 
 | ||||
|     if ((type > TRACE_MSG_MAX) || (len > LOSCFG_TRACE_TLV_BUF_SIZE)) {  //输入参数的合法性检查//
 | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     //对数据进行编码//
 | ||||
|     len = OsTraceDataEncode(type, g_traceTlvTbl[type], data, &outBuf[0], sizeof(outBuf)); | ||||
| 
 | ||||
|     PIPE_LOCK(intSave); //获取管道锁,防止多线程并发访问//
 | ||||
|     g_tracePipelineOps->dataSend(len, &outBuf[0]);  //发送编码后的数据//
 | ||||
|     PIPE_UNLOCK(intSave);   //释放管道锁//
 | ||||
| } | ||||
| 
 | ||||
| UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout)    //用于接收追踪数据//
 | ||||
| { | ||||
|     return g_tracePipelineOps->dataRecv(data, size, timeout); | ||||
| } | ||||
| 
 | ||||
| UINT32 OsTraceDataWait(VOID)    //用于等待追踪数据//
 | ||||
| { | ||||
|     return g_tracePipelineOps->wait(); | ||||
| } | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,104 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Pipeline Implementation HeadFile | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2020-03-16 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #ifndef _TRACE_PIPELINE_H | ||||
| #define _TRACE_PIPELINE_H | ||||
| 
 | ||||
| #include "los_typedef.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| /*用于实现追踪流水线的功能*/ | ||||
| typedef struct { | ||||
|     UINT32 (*init)(VOID);       //用于初始化//
 | ||||
|     VOID (*dataSend)(UINT16 len, UINT8 *data);      //用于发送数据//
 | ||||
|     UINT32 (*dataRecv)(UINT8 *data, UINT32 size, UINT32 timeout);   //用于接收数据//
 | ||||
|     UINT32 (*wait)(VOID);       //用于等待操作//
 | ||||
| } TracePipelineOps; | ||||
| 
 | ||||
| /* used as tlv's tag */ | ||||
| enum TraceMsgType {         //用于表示追踪消息的类型//
 | ||||
|     //类型如下//
 | ||||
|     NOTIFY, //通知//
 | ||||
|     HEAD,   //头部//
 | ||||
|     OBJ,    //对象//
 | ||||
|     EVENT,  //事件//
 | ||||
| 
 | ||||
|     TRACE_MSG_MAX,  //最大值//
 | ||||
| }; | ||||
| 
 | ||||
| enum TraceNotifySubType {   //用于表示通知消息的子类型//
 | ||||
|     CMD = 0x1, | ||||
|     PARAMS, | ||||
| }; | ||||
| 
 | ||||
| enum TraceHeadSubType {     //用于表示追踪头部信息的子类型//
 | ||||
|     ENDIAN = 0x1,   //字节序//
 | ||||
|     VERSION,        //版本//
 | ||||
|     OBJ_SIZE,       //对象大小//
 | ||||
|     OBJ_COUNT,      //对象计数//
 | ||||
|     CUR_INDEX,      //当前索引//
 | ||||
|     MAX_RECODE, | ||||
|     CUR_OBJ_INDEX, | ||||
|     CLOCK_FREQ, | ||||
| }; | ||||
| 
 | ||||
| enum TraceObjSubType {      //用于表示追踪对象的子类型//
 | ||||
|     ADDR = 0x1,     //地址//
 | ||||
|     PRIO,           //优先级/
 | ||||
|     NAME,           //名称//
 | ||||
| }; | ||||
| 
 | ||||
| enum TraceEvtSubType {      //用于表示追踪事件的子类型//
 | ||||
|     CORE = 0x1,     //核心编号//
 | ||||
|     EVENT_CODE,     //事件码//
 | ||||
|     CUR_TIME,       //当前时间//
 | ||||
|     EVENT_COUNT,    //事件计数//
 | ||||
|     CUR_TASK,       //当前任务//
 | ||||
|     IDENTITY,       //身份信息//
 | ||||
|     EVENT_PARAMS,   //事件参数//
 | ||||
| }; | ||||
| 
 | ||||
| extern VOID OsTracePipelineReg(const TracePipelineOps *ops);    //用于注册追踪管道操作//
 | ||||
| extern UINT32 OsTracePipelineInit(VOID);            //用于初始化追踪管道//
 | ||||
| 
 | ||||
| extern VOID OsTraceDataSend(UINT8 type, UINT16 len, UINT8 *data);   //用于发送追踪数据//
 | ||||
| extern UINT32 OsTraceDataRecv(UINT8 *data, UINT32 size, UINT32 timeout);    //用于接收追踪数据//
 | ||||
| extern UINT32 OsTraceDataWait(VOID);        //用于等待追踪数据//
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #endif /* _TRACE_PIPELINE_H */ | ||||
| @ -1,264 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Offline Mode Implementation | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2020-03-31 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_trace_pri.h" | ||||
| #include "trace_pipeline.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_RECORDER_MODE_OFFLINE | ||||
| #define BITS_NUM_FOR_TASK_ID 16 //指定了任务ID的位数//
 | ||||
| 
 | ||||
| LITE_OS_SEC_BSS STATIC TraceOfflineHeaderInfo g_traceRecoder;   //用来记录离线跟踪记录的相关信息//
 | ||||
| LITE_OS_SEC_BSS STATIC UINT32 g_tidMask[LOSCFG_BASE_CORE_TSK_LIMIT] = {0};  //用于存储任务ID的掩码//
 | ||||
| 
 | ||||
| UINT32 OsTraceGetMaskTid(UINT32 tid)    //用于获取掩码后的任务ID//
 | ||||
| { | ||||
|     return tid | ((tid < LOSCFG_BASE_CORE_TSK_LIMIT) ? g_tidMask[tid] << BITS_NUM_FOR_TASK_ID : 0); /* tid < 65535 */ | ||||
| } | ||||
| 
 | ||||
| UINT32 OsTraceBufInit(VOID *buf, UINT32 size)   //用于初始化离线跟踪缓冲区//
 | ||||
| { | ||||
|     UINT32 headSize; | ||||
| 
 | ||||
|     headSize = sizeof(OfflineHead) + sizeof(ObjData) * LOSCFG_TRACE_OBJ_MAX_NUM;    //用于存储离线跟踪记录头部信息//
 | ||||
|     if (size <= headSize) { | ||||
|         TRACE_ERROR("trace buf size not enough than 0x%x\n", headSize); | ||||
|         return LOS_ERRNO_TRACE_BUF_TOO_SMALL; | ||||
|     } | ||||
| 
 | ||||
|     if (buf == NULL) { | ||||
|         buf = LOS_MemAlloc(m_aucSysMem1, size); | ||||
|         if (buf == NULL) { | ||||
|             return LOS_ERRNO_TRACE_NO_MEMORY; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     (VOID)memset_s(buf, size, 0, size); | ||||
|     g_traceRecoder.head = (OfflineHead *)buf; | ||||
|     g_traceRecoder.head->baseInfo.bigLittleEndian = TRACE_BIGLITTLE_WORD; | ||||
|     g_traceRecoder.head->baseInfo.version         = TRACE_VERSION(TRACE_MODE_OFFLINE); | ||||
|     g_traceRecoder.head->baseInfo.clockFreq       = GET_SYS_CLOCK(); | ||||
|     g_traceRecoder.head->objSize                  = sizeof(ObjData); | ||||
|     g_traceRecoder.head->frameSize                = sizeof(TraceEventFrame); | ||||
|     g_traceRecoder.head->objOffset                = sizeof(OfflineHead); | ||||
|     g_traceRecoder.head->frameOffset              = headSize; | ||||
|     g_traceRecoder.head->totalLen                 = size; | ||||
| 
 | ||||
|     g_traceRecoder.ctrl.curIndex       = 0; | ||||
|     g_traceRecoder.ctrl.curObjIndex    = 0; | ||||
|     g_traceRecoder.ctrl.maxObjCount    = LOSCFG_TRACE_OBJ_MAX_NUM; | ||||
|     g_traceRecoder.ctrl.maxRecordCount = (size - headSize) / sizeof(TraceEventFrame); | ||||
|     g_traceRecoder.ctrl.objBuf         = (ObjData *)((UINTPTR)buf + g_traceRecoder.head->objOffset); | ||||
|     g_traceRecoder.ctrl.frameBuf       = (TraceEventFrame *)((UINTPTR)buf + g_traceRecoder.head->frameOffset); | ||||
| 
 | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) //用于向离线跟踪缓冲区中添加对象数据//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
|     UINT32 index; | ||||
|     ObjData *obj = NULL; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     /* add obj begin */ | ||||
|     index = g_traceRecoder.ctrl.curObjIndex; | ||||
|     if (index >= LOSCFG_TRACE_OBJ_MAX_NUM) { /* do nothing when config LOSCFG_TRACE_OBJ_MAX_NUM = 0 */ | ||||
|         TRACE_UNLOCK(intSave); | ||||
|         return; | ||||
|     } | ||||
|     obj = &g_traceRecoder.ctrl.objBuf[index]; | ||||
| 
 | ||||
|     if (taskId < LOSCFG_BASE_CORE_TSK_LIMIT) { | ||||
|         g_tidMask[taskId]++; | ||||
|     } | ||||
| 
 | ||||
|     OsTraceSetObj(obj, OS_TCB_FROM_TID(taskId)); | ||||
| 
 | ||||
|     g_traceRecoder.ctrl.curObjIndex++; | ||||
|     if (g_traceRecoder.ctrl.curObjIndex >= g_traceRecoder.ctrl.maxObjCount) { | ||||
|         g_traceRecoder.ctrl.curObjIndex = 0; /* turn around */ | ||||
|     } | ||||
|     /* add obj end */ | ||||
|     TRACE_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame)  //用于向离线跟踪缓冲区中写入或发送事件帧数据//
 | ||||
| { | ||||
|     UINT16 index; | ||||
|     UINT32 intSave; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     index = g_traceRecoder.ctrl.curIndex; | ||||
|     (VOID)memcpy_s(&g_traceRecoder.ctrl.frameBuf[index], sizeof(TraceEventFrame), frame, sizeof(TraceEventFrame)); | ||||
| 
 | ||||
|     g_traceRecoder.ctrl.curIndex++; | ||||
|     if (g_traceRecoder.ctrl.curIndex >= g_traceRecoder.ctrl.maxRecordCount) { | ||||
|         g_traceRecoder.ctrl.curIndex = 0; | ||||
|     } | ||||
|     TRACE_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceReset(VOID) //用于重置离线跟踪缓冲区//
 | ||||
| { | ||||
|     UINT32 intSave; | ||||
|     UINT32 bufLen; | ||||
| 
 | ||||
|     TRACE_LOCK(intSave); | ||||
|     bufLen = sizeof(TraceEventFrame) * g_traceRecoder.ctrl.maxRecordCount; | ||||
|     (VOID)memset_s(g_traceRecoder.ctrl.frameBuf, bufLen, 0, bufLen); | ||||
|     g_traceRecoder.ctrl.curIndex = 0; | ||||
|     TRACE_UNLOCK(intSave); | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceInfoObj(VOID)    //用于打印离线跟踪对象信息//
 | ||||
| { | ||||
|     UINT32 i; | ||||
|     ObjData *obj = &g_traceRecoder.ctrl.objBuf[0]; | ||||
| 
 | ||||
|     if (g_traceRecoder.ctrl.maxObjCount > 0) { | ||||
|         PRINTK("CurObjIndex = %u\n", g_traceRecoder.ctrl.curObjIndex); | ||||
|         PRINTK("Index   TaskID   TaskPrio   TaskName \n"); | ||||
|         for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++, obj++) { | ||||
|             PRINTK("%-7u 0x%-6x %-10u %s\n", i, obj->id, obj->prio, obj->name); | ||||
|         } | ||||
|         PRINTK("\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceInfoEventTitle(VOID) //用于打印离线跟踪事件标题//
 | ||||
| { | ||||
|     PRINTK("CurEvtIndex = %u\n", g_traceRecoder.ctrl.curIndex); | ||||
| 
 | ||||
|     PRINTK("Index   Time(cycles)      EventType      CurTask   Identity      "); | ||||
| #ifdef LOSCFG_TRACE_FRAME_CORE_MSG | ||||
|     PRINTK("cpuId    hwiActive    taskLockCnt    "); | ||||
| #endif | ||||
| #ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT | ||||
|     PRINTK("eventCount    "); | ||||
| #endif | ||||
|     if (LOSCFG_TRACE_FRAME_MAX_PARAMS > 0) { | ||||
|         PRINTK("params    "); | ||||
|     } | ||||
|     PRINTK("\n"); | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceInfoEventData(VOID)  //用于打印离线跟踪事件数据//
 | ||||
| { | ||||
|     UINT32 i, j; | ||||
|     TraceEventFrame *frame = &g_traceRecoder.ctrl.frameBuf[0]; | ||||
| 
 | ||||
|     for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++, frame++) { | ||||
|         PRINTK("%-7u 0x%-15llx 0x%-12x 0x%-7x 0x%-11x ", i, frame->curTime, frame->eventType, | ||||
|             frame->curTask, frame->identity); | ||||
| #ifdef LOSCFG_TRACE_FRAME_CORE_MSG | ||||
|         UINT32 taskLockCnt = frame->core.taskLockCnt; | ||||
| #ifdef LOSCFG_KERNEL_SMP | ||||
|         /*
 | ||||
|          * For smp systems, TRACE_LOCK will requst taskLock, and this counter | ||||
|          * will increase by 1 in that case. | ||||
|          */ | ||||
|         taskLockCnt -= 1; | ||||
| #endif | ||||
|         PRINTK("%-11u %-11u %-11u", frame->core.cpuId, frame->core.hwiActive, taskLockCnt); | ||||
| #endif | ||||
| #ifdef LOSCFG_TRACE_FRAME_EVENT_COUNT | ||||
|         PRINTK("%-11u", frame->eventCount); | ||||
| #endif | ||||
|         for (j = 0; j < LOSCFG_TRACE_FRAME_MAX_PARAMS; j++) { | ||||
|             PRINTK("0x%-11x", frame->params[j]); | ||||
|         } | ||||
|         PRINTK("\n"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceInfoDisplay(VOID)    //用于显示离线跟踪信息//
 | ||||
| { | ||||
|     OfflineHead *head = g_traceRecoder.head; | ||||
| 
 | ||||
|     PRINTK("*******TraceInfo begin*******\n"); | ||||
|     PRINTK("clockFreq = %u\n", head->baseInfo.clockFreq); | ||||
| 
 | ||||
|     OsTraceInfoObj(); | ||||
| 
 | ||||
|     OsTraceInfoEventTitle(); | ||||
|     OsTraceInfoEventData(); | ||||
| 
 | ||||
|     PRINTK("*******TraceInfo end*******\n"); | ||||
| } | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CLIENT_INTERACT | ||||
| STATIC VOID OsTraceSendInfo(VOID)   //用于发送离线跟踪信息//
 | ||||
| { | ||||
|     UINT32 i; | ||||
|     ObjData *obj = NULL; | ||||
|     TraceEventFrame *frame = NULL; | ||||
| 
 | ||||
|     OsTraceDataSend(HEAD, sizeof(OfflineHead), (UINT8 *)g_traceRecoder.head); | ||||
| 
 | ||||
|     obj = &g_traceRecoder.ctrl.objBuf[0]; | ||||
|     for (i = 0; i < g_traceRecoder.ctrl.maxObjCount; i++) { | ||||
|         OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)(obj + i)); | ||||
|     } | ||||
| 
 | ||||
|     frame = &g_traceRecoder.ctrl.frameBuf[0]; | ||||
|     for (i = 0; i < g_traceRecoder.ctrl.maxRecordCount; i++) { | ||||
|         OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)(frame + i)); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| VOID OsTraceRecordDump(BOOL toClient)   //用于输出或发送离线跟踪信息//
 | ||||
| { | ||||
|     if (!toClient) {    //用于指示是输出还是发送离线跟踪信息//
 | ||||
|         OsTraceInfoDisplay(); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| #ifdef LOSCFG_TRACE_CLIENT_INTERACT | ||||
|     OsTraceSendInfo(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| OfflineHead *OsTraceRecordGet(VOID) //用于获取离线跟踪记录的头信息//
 | ||||
| { | ||||
|     return g_traceRecoder.head; | ||||
| } | ||||
| 
 | ||||
| #endif /* LOSCFG_RECORDER_MODE_OFFLINE */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| @ -1,117 +0,0 @@ | ||||
| /* ----------------------------------------------------------------------------
 | ||||
|  * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. | ||||
|  * Description: LiteOS Trace Online Mode Implementation | ||||
|  * Author: Huawei LiteOS Team | ||||
|  * Create: 2020-03-31 | ||||
|  * Redistribution and use in source and binary forms, with or without modification, | ||||
|  * are permitted provided that the following conditions are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this list of | ||||
|  * conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, this list | ||||
|  * of conditions and the following disclaimer in the documentation and/or other materials | ||||
|  * provided with the distribution. | ||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors may be used | ||||
|  * to endorse or promote products derived from this software without specific prior written | ||||
|  * permission. | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||||
|  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||||
|  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||||
|  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||||
|  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||||
|  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||||
|  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||||
|  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||||
|  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||||
|  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  * --------------------------------------------------------------------------- */ | ||||
| 
 | ||||
| #include "los_trace_pri.h" | ||||
| #include "trace_pipeline.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| #ifdef LOSCFG_RECORDER_MODE_ONLINE | ||||
| UINT32 OsTraceGetMaskTid(UINT32 taskId) //用于获取任务ID的掩码//
 | ||||
| { | ||||
|     return taskId; | ||||
| } | ||||
| 
 | ||||
| UINT32 OsTraceBufInit(VOID *buf, UINT32 size)   //初始化跟踪缓冲区//
 | ||||
| { | ||||
|     (VOID)buf; | ||||
|     (VOID)size; | ||||
|     return LOS_OK; | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceSendHead(VOID)      //发送跟踪数据的头信息//
 | ||||
| { | ||||
|     TraceBaseHeaderInfo head = { | ||||
|         .bigLittleEndian = TRACE_BIGLITTLE_WORD, | ||||
|         .version         = TRACE_VERSION(TRACE_MODE_ONLINE), | ||||
|         .clockFreq       = GET_SYS_CLOCK(), | ||||
|     }; | ||||
| 
 | ||||
|     OsTraceDataSend(HEAD, sizeof(TraceBaseHeaderInfo), (UINT8 *)&head); | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceSendNotify(UINT32 type, UINT32 value)   //发送通知类型的跟踪数据//
 | ||||
| { | ||||
|     TraceNotifyFrame frame = { | ||||
|         .cmd   = type, | ||||
|         .param = value, | ||||
|     }; | ||||
| 
 | ||||
|     OsTraceDataSend(NOTIFY, sizeof(TraceNotifyFrame), (UINT8 *)&frame); | ||||
| } | ||||
| 
 | ||||
| STATIC VOID OsTraceSendObj(const LosTaskCB *tcb)    //发送对象类型为obj的跟踪数据//
 | ||||
| { | ||||
|     ObjData obj; | ||||
| 
 | ||||
|     OsTraceSetObj(&obj, tcb); | ||||
|     OsTraceDataSend(OBJ, sizeof(ObjData), (UINT8 *)&obj); | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceSendObjTable(VOID)  //发送对象表类型的跟踪数据//
 | ||||
| { | ||||
|     UINT32 loop; | ||||
|     LosTaskCB *tcb = NULL; | ||||
| 
 | ||||
|     for (loop = 0; loop < g_taskMaxNum; ++loop) { | ||||
|         tcb = g_taskCBArray + loop; | ||||
|         if (tcb->taskStatus & OS_TASK_STATUS_UNUSED) { | ||||
|             continue; | ||||
|         } | ||||
|         OsTraceSendObj(tcb); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceObjAdd(UINT32 eventType, UINT32 taskId) //向跟踪记录中添加对象//
 | ||||
| { | ||||
|     if (OsTraceIsEnable()) { | ||||
|         OsTraceSendObj(OS_TCB_FROM_TID(taskId)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| VOID OsTraceWriteOrSendEvent(const TraceEventFrame *frame)  //发送事件数据//
 | ||||
| { | ||||
|     OsTraceDataSend(EVENT, sizeof(TraceEventFrame), (UINT8 *)frame); | ||||
| } | ||||
| 
 | ||||
| OfflineHead *OsTraceRecordGet(VOID) //获取离线跟踪记录头//
 | ||||
| { | ||||
|     return NULL;    //表示没有离线跟踪记录可用//
 | ||||
| } | ||||
| 
 | ||||
| #endif /* LOSCFG_RECORDER_MODE_ONLINE */ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| #if __cplusplus | ||||
| } | ||||
| #endif /* __cplusplus */ | ||||
| #endif /* __cplusplus */ | ||||
					Loading…
					
					
				
		Reference in new issue