master
p2gpamesw 11 months ago
commit 3370bcc0b2

@ -0,0 +1,8 @@
{
"files.associations": {
"los_queue_pri.h": "c",
"los_trace.h": "c",
"los_task_pri.h": "c",
"los_mux_debug_pri.h": "c"
}
}

@ -0,0 +1,257 @@
/* ----------------------------------------------------------------------------
* 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 */

@ -0,0 +1,189 @@
/* ----------------------------------------------------------------------------
* 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 */

@ -0,0 +1,206 @@
/* ----------------------------------------------------------------------------
* 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 */

@ -0,0 +1,347 @@
/* ----------------------------------------------------------------------------
* 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 */

@ -0,0 +1,299 @@
/* ----------------------------------------------------------------------------
* 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.

Binary file not shown.

Binary file not shown.

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了与二叉树相关的结构体和函数,用于实现对数据的快速查找和插入。
#ifndef _LOS_BINARYTREE_PRI_H
#define _LOS_BINARYTREE_PRI_H
@ -35,67 +35,76 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//定义二叉树节点的模型
typedef struct tagBinNode {
struct tagBinNode *left;
struct tagBinNode *right;
UINT32 nodeId;
CHAR keyValue[0];
struct tagBinNode *left;//左子树节点
struct tagBinNode *right;//右子树节点
UINT32 nodeId;//节点的编号
CHAR keyValue[0];//节点记录的值(柔性数组,动态分配内存)
} BinNode;
//链接二叉树节点
typedef struct {
BinNode leaf;
UINTPTR linkReg1;
BinNode leaf;//一个二叉树
UINTPTR linkReg1;//无符号数的指针,可连接三个节点
UINTPTR linkReg2;
UINTPTR linkReg3;
} LinkRegNode;
#define LR_COUNT 4096
extern LinkRegNode g_linkRegNode[LR_COUNT];
extern UINT32 g_linkRegNodeIndex;
extern LinkRegNode *g_linkRegRoot;
extern LinkRegNode g_linkRegNode[LR_COUNT];//4096个链接二叉树节点
extern UINT32 g_linkRegNodeIndex;//链接二叉树节点的索引
extern LinkRegNode *g_linkRegRoot;//链接二叉树节点的指针
//地址二叉树节点
typedef struct {
BinNode leaf;
UINTPTR addr;
BinNode leaf;//一个二叉树节点
UINTPTR addr;//二叉树节点记录的地址
} AddrNode;
#define ADDR_COUNT 40960
extern AddrNode g_addrNode[ADDR_COUNT];
extern UINT32 g_addrNodeIndex;
extern AddrNode *g_addrRoot;
extern AddrNode g_addrNode[ADDR_COUNT];//40960个地址二叉树节点
extern UINT32 g_addrNodeIndex;//地址二叉树节点的索引
extern AddrNode *g_addrRoot;//地址二叉树节点的指针
//请求大小二叉树节点
typedef struct {
BinNode leaf;
UINT32 reqSize;
BinNode leaf;//一个二叉树
UINT32 reqSize;//请求数据大小
} ReqSizeNode;
#define REQ_SIZE_COUNT 4096
extern ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT];
extern UINT32 g_reqSizeNodeIndex;
extern ReqSizeNode *g_reqSizeRoot;
extern ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT];//4096个请求大小二叉树节点
extern UINT32 g_reqSizeNodeIndex;//请求大小二叉树节点的索引
extern ReqSizeNode *g_reqSizeRoot;//请求大小二叉树节点的指针
//任务编号二叉树节点
typedef struct {
BinNode leaf;
UINT32 taskId;
} TaskIDNode;
#define TASK_ID_COUNT 1024
#define TASK_ID_COUNT 1024//1024个任务编号
//将节点插入二叉树的函数
extern UINT32 OsBinTreeInsert(const VOID *node, UINT32 nodeLen, BinNode **leaf,
BinNode *(*GetMyBinNode)(UINT32 *nodeId),
INT32 (*CompareNode)(const VOID *node1, const VOID *node2));
//比较两个二叉树节点
extern INT32 OsCompareLRNode(const VOID *node1, const VOID *node2);
//通过二叉树节点的编号得到二叉树
extern BinNode *OsGetLRBinNode(UINT32 *nodeId);
//比较两个地址二叉树节点
extern INT32 OsCompareAddrNode(const VOID *node1, const VOID *node2);
//通过地址二叉树节点的编号得到地址二叉树
extern BinNode *OsGetAddrBinNode(UINT32 *nodeId);
//比较两个请求大小二叉树节点
extern INT32 OsCompareReqSizeNode(const VOID *node1, const VOID *node2);
//通过请求大小二叉树节点的编号得到请求大小二叉树
extern BinNode *OsGetReqSizeBinNode(UINT32 *nodeId);
//比较两个任务编号二叉树节点
extern INT32 OsCompareTaskIDNode(const VOID *node1, const VOID *node2);
//通过任务编号二叉树节点的编号得到任务编号二叉树
extern BinNode *OsGetTaskIDBinNode(UINT32 *nodeId);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//用于定义一些错误处理相关的宏和函数。
#ifndef _LOS_ERR_PRI_H
#define _LOS_ERR_PRI_H
@ -40,6 +40,7 @@ extern "C" {
#define OS_ERR_MAGIC_WORD 0xa1b2c3f8
/* used to call the error handling function by using an error code and return the same error code. */
//通过调用处理异常的错误码返回错误码
#define OS_RETURN_ERROR(errNo) do { \
(VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \
return errNo; \
@ -49,12 +50,14 @@ extern "C" {
* Call the error handling function by using an error code and the line number of
* the erroneous line, and return the same error code.
*/
//通过调用异常发生行的位置返回错误码
#define OS_RETURN_ERROR_P2(errLine, errNo) do { \
(VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \
return errNo; \
} while (0)
/* Used to call the error handling function by using an error code. */
//通过错误码进行调用处理异常的函数
#define OS_GOTO_ERR_HANDLER(errorNo) do { \
errNo = errorNo; \
errLine = OS_ERR_MAGIC_WORD; \

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了一些与事件操作相关的私有函数和结构体。
#ifndef _LOS_EVENT_PRI_H
#define _LOS_EVENT_PRI_H
@ -38,10 +38,11 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_COMPAT_POSIX
//定义时间状态的结构体
typedef struct {
volatile INT32 *realValue;
INT32 value;
UINT32 clearEvent;
volatile INT32 *realValue;//指向的是一个共享资源的计数器
INT32 value;//条件变量的值
UINT32 clearEvent;//需要清除的事件标志
} EventCond;
extern UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB,

@ -25,12 +25,14 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了一些与异常处理相关的私有函数和宏
//防止同一个头文件被多次包含
#ifndef _LOS_EXC_PRI_H
#define _LOS_EXC_PRI_H
#include "los_exc.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@ -38,17 +40,28 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
//用于设置异常信息读写函数的指针。
extern VOID OsSetExcInfoRW(LogReadWriteFunc func);
extern LogReadWriteFunc OsGetExcInfoRW(VOID);
//用于设置异常信息缓冲区的指针。
extern VOID OsSetExcInfoBuf(CHAR *buf);
//用于获取异常信息缓冲区的指针。
extern CHAR *OsGetExcInfoBuf(VOID);
//用于设置异常信息在缓冲区中的偏移量。
extern VOID OsSetExcInfoOffset(UINT32 offset);
//用于获取异常信息在缓冲区中的偏移量。
extern UINT32 OsGetExcInfoOffset(VOID);
//用于设置异常信息转储地址。
extern VOID OsSetExcInfoDumpAddr(UINTPTR addr);
//用于获取异常信息转储地址。
extern UINTPTR OsGetExcInfoDumpAddr(VOID);
//用于设置异常信息的长度。
extern VOID OsSetExcInfoLen(UINT32 len);
//用于获取异常信息的长度。
extern UINT32 OsGetExcInfoLen(VOID);
//用于记录异常信息的时间戳。
extern VOID OsRecordExcInfoTime(VOID);
//用于将格式化的字符串写入异常信息缓冲区。
extern VOID WriteExcBufVa(const CHAR *format, va_list arg);
extern VOID WriteExcInfoToBuf(const CHAR *format, ...);
#endif

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了一些与硬件中断处理相关的数据结构和函数接口,用于操作和管理系统中的硬件中断。
#ifndef _LOS_HWI_PRI_H
#define _LOS_HWI_PRI_H
@ -67,9 +67,11 @@ typedef struct {
} HwiControllerOps;
extern const HwiControllerOps *g_hwiOps;
//用于初始化硬件中断
extern VOID OsHwiInit(VOID);
//用于获取当前中断嵌套的计数值,可以用于检查当前是否处于中断嵌套状态。
extern size_t OsIrqNestingCntGet(VOID);
//用于设置中断嵌套的计数值。
extern VOID OsIrqNestingCntSet(size_t val);
/**
@ -77,8 +79,9 @@ extern VOID OsIrqNestingCntSet(size_t val);
* by the kernel. The handleIrq hook function MUST be registered in the interrupt controller driver layer, otherwise it
* will not respond. eg: Used for arm(cortex-a/r)/arm64.
*/
//一个汇编入口函数由汇编代码在dispatch.S中调用用于统一处理外部中断的入口由内核接管中断处理流程。
extern VOID OsIntEntry(VOID);
//根据中断号获取中断处理信息的指针
STATIC INLINE HwiHandleInfo *OsGetHwiForm(UINT32 hwiNum)
{
if ((g_hwiOps == NULL) || (g_hwiOps->getHandleForm == NULL)) {
@ -86,7 +89,7 @@ STATIC INLINE HwiHandleInfo *OsGetHwiForm(UINT32 hwiNum)
}
return g_hwiOps->getHandleForm(hwiNum);
}
//用于获取指定中断的响应计数值
STATIC INLINE UINT32 OsGetHwiFormCnt(UINT32 hwiNum)
{
HwiHandleInfo *hwiForm = OsGetHwiForm(hwiNum);
@ -96,7 +99,7 @@ STATIC INLINE UINT32 OsGetHwiFormCnt(UINT32 hwiNum)
}
return hwiForm->respCount;
}
//用于获取当前正在处理的中断号。
STATIC INLINE UINT32 OsIntNumGet(VOID)
{
if ((g_hwiOps == NULL) || (g_hwiOps->getCurIrqNum == NULL)) {
@ -104,7 +107,7 @@ STATIC INLINE UINT32 OsIntNumGet(VOID)
}
return g_hwiOps->getCurIrqNum();
}
//用于判断指定的中断号是否已经注册了相应的处理函数。
STATIC INLINE BOOL OsIntIsRegisted(UINT32 num)
{
HwiHandleInfo *hwiForm = OsGetHwiForm(num);
@ -118,7 +121,7 @@ STATIC INLINE BOOL OsIntIsRegisted(UINT32 num)
return (hwiForm->hook != NULL);
#endif
}
//用于获取指定中断的注册参数信息。
STATIC INLINE HWI_ARG_T OsIntGetPara(UINT32 num)
{
HwiHandleInfo *hwiForm = OsGetHwiForm(num);
@ -128,7 +131,7 @@ STATIC INLINE HWI_ARG_T OsIntGetPara(UINT32 num)
}
return hwiForm->registerInfo;
}
//用于获取中断版本信息。
STATIC INLINE CHAR *OsIntVersionGet(VOID)
{
if ((g_hwiOps == NULL) || (g_hwiOps->getIrqVersion == NULL)) {
@ -143,6 +146,7 @@ STATIC INLINE CHAR *OsIntVersionGet(VOID)
* handleForm to this interface.
* eg: Used for arm(cortex-m),xtensa,riscv.
*/
//在中断控制器驱动层实现通用的中断处理入口,用于传递中断号和处理信息给相应的处理函数。
extern VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *handleForm);
/**
@ -151,6 +155,7 @@ extern VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *handleForm);
* HwiControllerOps need to be registered. If this function is not supported, you can call the LOS_Panic interface in
* the implementation of the stub function to report an error in time.
*/
//用于注册中断控制器相关的操作函数,需要在中断控制器初始化时被调用。
STATIC INLINE VOID OsHwiControllerReg(const HwiControllerOps *ops)
{
g_hwiOps = ops;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件的作用是定义了与内存池相关的私有函数和数据结构。
#ifndef _LOS_MEMBOX_PRI_H
#define _LOS_MEMBOX_PRI_H

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义内存管理的私有接口和数据结构。
#ifndef _LOS_MEMORY_PRI_H
#define _LOS_MEMORY_PRI_H
@ -35,6 +35,8 @@
#include "los_spinlock.h"
#include "los_misc_pri.h"
//关于内存管理的私有接口声明
#ifdef __cplusplus
#if __cplusplus
extern "C" {
@ -60,6 +62,7 @@ typedef struct {
struct LosSlabControlHeader slabCtrlHdr;
#endif
} LosMemPoolInfo;
//用于描述内存池的信息,包括内存池的起始地址、大小等信息。
#elif defined(LOSCFG_KERNEL_MEM_BESTFIT_LITTLE)
@ -90,6 +93,7 @@ extern SPIN_LOCK_S g_memSpin;
#define MEM_LOCK(state) LOS_SpinLockSave(&g_memSpin, &(state))
#define MEM_UNLOCK(state) LOS_SpinUnlockRestore(&g_memSpin, (state))
//用于系统内存的初始化。
extern UINTPTR g_sys_mem_addr_end;
extern UINT32 OsMemSystemInit(UINTPTR memStart);
@ -104,11 +108,12 @@ extern UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size);
extern UINT32 OsMemMulPoolDeinit(const VOID *pool);
extern VOID *OsMemMulPoolHeadGet(VOID);
#else /* LOSCFG_MEM_MUL_POOL */
//用于初始化多内存池,接受内存池的起始地址和大小作为参数。
STATIC INLINE UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size)
{
return LOS_OK;
}
//用于反初始化多内存池,接受内存池的指针作为参数。
STATIC INLINE UINT32 OsMemMulPoolDeinit(const VOID *pool)
{
return LOS_OK;
@ -116,16 +121,21 @@ STATIC INLINE UINT32 OsMemMulPoolDeinit(const VOID *pool)
#endif /* LOSCFG_MEM_MUL_POOL */
#ifdef LOSCFG_EXC_INTERACTION
//于初始化内存异常交互,接受内存起始地址作为参数。
extern UINT32 OsMemExcInteractionInit(UINTPTR memStart);
#endif
#ifdef LOSCFG_MEM_LEAKCHECK
//用于展示已使用的内存节点信息,接受内存池指针作为参数。
extern VOID OsMemUsedNodeShow(VOID *pool);
#endif
//用于重置内存池的结束节点,接受内存池指针和前一个地址作为参数。
extern VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr);
//用于打印内存信息,接受内存池指针作为参数。
extern VOID OsMemInfoPrint(const VOID *pool);
//用于执行内存检查的 shell 命令,接受命令参数作为输入。
extern UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[]);
//用于执行多重内存完整性检查。
extern VOID OsMemIntegrityMultiCheck(VOID);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了一些用于内存统计的数据结构和函数接口,用于跟踪和管理任务使用的内存情况。
#ifndef _LOS_MEMSTAT_PRI_H
#define _LOS_MEMSTAT_PRI_H
@ -43,19 +43,22 @@ extern "C" {
#ifdef LOSCFG_MEM_TASK_STAT
typedef struct {
UINT32 memUsed;
UINT32 memPeak;
UINT32 memUsed;//内存使用
UINT32 memPeak;//内存峰值
} TaskMemUsedInfo;
typedef struct {
UINT32 memTotalUsed;
UINT32 memTotalPeak;
TaskMemUsedInfo taskMemstats[TASK_NUM];
UINT32 memTotalUsed;//内存使用量
UINT32 memTotalPeak;//内存使用峰值
TaskMemUsedInfo taskMemstats[TASK_NUM];//使用内存的任务列表
} Memstat;
//用于增加任务的内存使用量和峰值。
extern VOID OsMemstatTaskUsedInc(Memstat *stat, UINT32 usedSize, UINT32 taskId);
//用于减少任务的内存使用量和峰值。
extern VOID OsMemstatTaskUsedDec(Memstat *stat, UINT32 usedSize, UINT32 taskId);
//用于清除任务的内存统计信息。
extern VOID OsMemstatTaskClear(Memstat *stat, UINT32 taskId);
//用于获取任务的内存使用率。
extern UINT32 OsMemstatTaskUsage(const Memstat *stat, UINT32 taskId);
#endif
@ -63,9 +66,13 @@ extern VOID OsMemTaskClear(UINT32 taskId);
extern UINT32 OsMemTaskUsage(UINT32 taskId);
#ifdef LOSCFG_MEM_TASK_STAT
//增加任务的内存使用量和峰值。
#define OS_MEM_ADD_USED(stat, usedSize, taskId) OsMemstatTaskUsedInc(stat, usedSize, taskId)
//减少任务的内存使用量和峰值。
#define OS_MEM_REDUCE_USED(stat, usedSize, taskId) OsMemstatTaskUsedDec(stat, usedSize, taskId)
//清除任务的内存统计信息。
#define OS_MEM_CLEAR(taskId) OsMemTaskClear(taskId)
//获取任务的内存使用率。
#define OS_MEM_USAGE(taskId) OsMemTaskUsage(taskId)
#else
#define OS_MEM_ADD_USED(stat, usedSize, taskId)

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了一些私有接口和数据结构,主要涉及与内存相关的功能和调试功能。
#ifndef _LOS_MISC_PRI_H
#define _LOS_MISC_PRI_H
@ -36,7 +36,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//定义了一个用于将指定地址开始的连续内存字节进行转储的函数。可以用于调试和观察内存中的数据。
VOID OsDumpMemByte(size_t length, UINTPTR addr);
#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_DEBUG_MUTEX) || defined(LOSCFG_DEBUG_QUEUE)
@ -48,13 +48,16 @@ typedef struct {
} SortParam;
/* Compare the size of the last access time */
//用于排序时比较控制块成员的大小。
typedef BOOL (*OsCompareFunc)(const SortParam *sortParam, UINT32 left, UINT32 right);
/* Get the address of the comparison member variable */
//用于获取控制块成员变量的地址。
#define SORT_ELEM_ADDR(sortParam, index) \
((sortParam)->buf + ((index) * (sortParam)->ctrlBlockSize) + (sortParam)->sortElemOff)
/* Sort this index array. */
//用于对索引数组进行排序。
extern VOID OsArraySort(UINT32 *sortArray, UINT32 start, UINT32 end, const SortParam *sortParam,
OsCompareFunc compareFunc);
#endif

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//定义了一些私有接口、数据结构和宏主要涉及多处理器MP相关的功能。
#ifndef _LOS_MP_PRI_H
#define _LOS_MP_PRI_H
@ -56,10 +56,15 @@ typedef enum {
typedef VOID (*SMP_FUNC_CALL)(VOID *args);
#ifdef LOSCFG_KERNEL_SMP
//定义了一个用于在多处理器系统中切换调度目标的函数。
extern VOID LOS_MpSchedule(UINT32 target);
//定义了一个用于处理多处理器唤醒事件的函数。
extern VOID OsMpWakeHandler(VOID);
//定义了一个用于处理多处理器调度事件的函数。
extern VOID OsMpScheduleHandler(VOID);
//定义了一个用于处理多处理器停机事件的函数。
extern VOID OsMpHaltHandler(VOID);
//定义了一个用于初始化多处理器相关功能的函数。
extern UINT32 OsMpInit(VOID);
#else
STATIC INLINE VOID LOS_MpSchedule(UINT32 target)
@ -69,7 +74,7 @@ STATIC INLINE VOID LOS_MpSchedule(UINT32 target)
#endif
#ifdef LOSCFG_KERNEL_SMP_CALL
//用于在目标 CPU 上调用函数
typedef struct {
LOS_DL_LIST node;
SMP_FUNC_CALL func;
@ -82,6 +87,7 @@ typedef struct {
extern VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args);
extern VOID OsMpFuncCallHandler(VOID);
#else
//用于处理多处理器函数调用事件。
STATIC INLINE VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
{
(VOID)target;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了一个多重双向链表头的私有接口和数据结构。
#ifndef _LOS_MULTIPLE_DLINK_HEAD_PRI_H
#define _LOS_MULTIPLE_DLINK_HEAD_PRI_H
@ -37,25 +37,30 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//表示最大的多重双向链表的大小的对数值。
#define OS_MAX_MULTI_DLNK_LOG2 29
//表示最小的多重双向链表的大小的对数值。
#define OS_MIN_MULTI_DLNK_LOG2 4
//表示多重双向链表的数量,通过最大和最小的对数值计算得到。
#define OS_MULTI_DLNK_NUM ((OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2) + 1)
//表示多重双向链表头的大小。
#define OS_DLNK_HEAD_SIZE OS_MULTI_DLNK_HEAD_SIZE
//表示多重双向链表头结构体的大小。
#define OS_MULTI_DLNK_HEAD_SIZE sizeof(LosMultipleDlinkHead)
//用于存储多重双向链表的头指针数组。
typedef struct {
LOS_DL_LIST listHead[OS_MULTI_DLNK_NUM];
} LosMultipleDlinkHead;
//根据给定的头地址和链表节点头指针,返回下一个多重链表的头指针。
STATIC INLINE LOS_DL_LIST *OsDLnkNextMultiHead(VOID *headAddr, LOS_DL_LIST *listNodeHead)
{
LosMultipleDlinkHead *head = (LosMultipleDlinkHead *)headAddr;
return (&head->listHead[OS_MULTI_DLNK_NUM - 1] == listNodeHead) ? NULL : (listNodeHead + 1);
}
//对给定的头地址进行初始化,将多重双向链表的头指针数组中的所有指针置为 NULL。
extern VOID OsDLnkInitMultiHead(VOID *headAddr);
//根据给定的头地址和大小,返回对应的多重双向链表的头指针。
extern LOS_DL_LIST *OsDLnkMultiHead(VOID *headAddr, UINT32 size);
#ifdef __cplusplus

@ -26,6 +26,9 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这个头文件定义了一些用于互斥锁mutex调试的接口和函数包括死锁检测、互斥锁状态跟踪、互斥锁泄漏检查等。
使*/
#ifndef _LOS_MUX_DEBUG_PRI_H
#define _LOS_MUX_DEBUG_PRI_H
@ -35,7 +38,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//初始化死锁检测机制
/* Deadlock detection initialization interface */
extern UINT32 OsMuxDlockCheckInit(VOID);
STATIC INLINE UINT32 OsMuxDlockCheckInitHook(VOID)
@ -46,7 +49,7 @@ STATIC INLINE UINT32 OsMuxDlockCheckInitHook(VOID)
return LOS_OK;
#endif
}
//向死锁检测机制中添加任务持有的互斥锁信息
/* Add holding mutex lock node information */
extern VOID OsMuxDlockNodeInsert(UINT32 taskId, VOID *muxCB);
STATIC INLINE VOID OsMuxDlockNodeInsertHook(UINT32 taskId, VOID *muxCB)
@ -55,6 +58,7 @@ STATIC INLINE VOID OsMuxDlockNodeInsertHook(UINT32 taskId, VOID *muxCB)
OsMuxDlockNodeInsert(taskId, muxCB);
#endif
}
//从死锁检测机制中删除任务持有的互斥锁信息
/* Delete holding mutex lock node information */
extern VOID OsMuxDlockNodeDelete(UINT32 taskId, const VOID *muxCB);
STATIC INLINE VOID OsMuxDlockNodeDeleteHook(UINT32 taskId, const VOID *muxCB)
@ -63,6 +67,7 @@ STATIC INLINE VOID OsMuxDlockNodeDeleteHook(UINT32 taskId, const VOID *muxCB)
OsMuxDlockNodeDelete(taskId, muxCB);
#endif
}
//更新任务最后执行的时间
/* Update the last time the task was executed */
extern VOID OsTaskTimeUpdate(UINT32 taskId, UINT64 tickCount);
STATIC INLINE VOID OsTaskTimeUpdateHook(UINT32 taskId, UINT64 tickCount)
@ -71,7 +76,7 @@ STATIC INLINE VOID OsTaskTimeUpdateHook(UINT32 taskId, UINT64 tickCount)
OsTaskTimeUpdate(taskId, tickCount);
#endif
}
//初始化互斥锁状态跟踪机制
/* mutex debug initialization interface */
extern UINT32 OsMuxDbgInit(VOID);
STATIC INLINE UINT32 OsMuxDbgInitHook(VOID)
@ -82,6 +87,7 @@ STATIC INLINE UINT32 OsMuxDbgInitHook(VOID)
return LOS_OK;
#endif
}
//更新互斥锁最后执行的时间
/* Update the last time the mutex was executed */
extern VOID OsMuxDbgTimeUpdate(UINT32 muxId);
STATIC INLINE VOID OsMuxDbgTimeUpdateHook(UINT32 muxId)
@ -90,6 +96,7 @@ STATIC INLINE VOID OsMuxDbgTimeUpdateHook(UINT32 muxId)
OsMuxDbgTimeUpdate(muxId);
#endif
}
//在创建或删除互斥锁时更新互斥锁的状态跟踪信息
/* Update the MUX_DEBUG_CB of the mutex when created or deleted */
extern VOID OsMuxDbgUpdate(UINT32 muxID, TSK_ENTRY_FUNC creator);
STATIC INLINE VOID OsMuxDbgUpdateHook(UINT32 muxId, TSK_ENTRY_FUNC creator)
@ -98,6 +105,7 @@ STATIC INLINE VOID OsMuxDbgUpdateHook(UINT32 muxId, TSK_ENTRY_FUNC creator)
OsMuxDbgUpdate(muxId, creator);
#endif
}
//检查互斥锁是否泄漏
/* check the leak of mutex */
extern VOID OsMutexCheck(VOID);
STATIC INLINE VOID OsMutexCheckHook(VOID)

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//一个关于互斥锁的内部实现的头文件
#ifndef _LOS_MUX_PRI_H
#define _LOS_MUX_PRI_H
@ -45,12 +45,13 @@ extern "C" {
* Mutex base object must be the same as the first three member names of LosMuxCB,
* so that pthread_mutex_t can share the kernel mutex mechanism.
*/
//这是互斥锁的基本控制块,包含了互斥锁的一些基本信息
typedef struct {
LOS_DL_LIST muxList; /* Mutex linked list */
LosTaskCB *owner; /* The current thread that is locking a mutex */
UINT16 muxCount; /* Times of locking a mutex */
LOS_DL_LIST muxList;//连接列表 /* Mutex linked list */
LosTaskCB *owner; //互斥锁的拥有者 /* The current thread that is locking a mutex */
UINT16 muxCount; //被锁定的次数 /* Times of locking a mutex */
} MuxBaseCB;
//这是互斥锁的控制块,包含了更多的互斥锁信息
typedef struct {
LOS_DL_LIST muxList; /* Mutex linked list */
LosTaskCB *owner; /* The current thread that is locking a mutex */
@ -60,21 +61,29 @@ typedef struct {
} LosMuxCB;
/* Mutex global array address, which can be obtained by using a handle ID. */
//全局变量:这是一个互斥锁的全局数组地址,可以通过互斥锁的 ID 来获取对应的互斥锁对象。
extern LosMuxCB *g_allMux;
/* COUNT | INDEX split bit */
#define MUX_SPLIT_BIT 16
/* Set the mutex id */
//设置互斥锁的 ID
#define SET_MUX_ID(count, muxId) (((count) << MUX_SPLIT_BIT) | (muxId))
//根据互斥锁的 ID 获取索引
#define GET_MUX_INDEX(muxId) ((muxId) & ((1U << MUX_SPLIT_BIT) - 1))
//根据互斥锁的 ID 获取计数值
#define GET_MUX_COUNT(muxId) ((muxId) >> MUX_SPLIT_BIT)
/* Obtain the pointer to a mutex object of the mutex that has a specified handle. */
//根据互斥锁的 ID 获取对应的互斥锁对象指针
#define GET_MUX(muxId) (((LosMuxCB *)g_allMux) + GET_MUX_INDEX(muxId))
//初始化互斥锁
extern UINT32 OsMuxInit(VOID);
//执行互斥锁的等待操作
extern UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UINT32 timeout, UINT32 *intSave);
//执行互斥锁的释放操作
extern UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted);
#ifdef __cplusplus
#if __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了关于每个CPU的私有数据结构这个结构体存储了与每个 CPU 相关的一些信息。
#ifndef _LOS_PERCPU_PRI_H
#define _LOS_PERCPU_PRI_H
@ -47,35 +47,34 @@ typedef enum {
CPU_EXC /* cpu in the exc */
} ExcFlag;
#endif
//排序链表的属性结构体,用于表示任务链表和软件定时器链表
typedef struct {
SortLinkAttribute taskSortLink; /* task sort link */
#ifdef LOSCFG_BASE_CORE_SWTMR
SortLinkAttribute swtmrSortLink; /* swtmr sort link */
#endif
UINT32 idleTaskId; /* idle task id */
UINT32 taskLockCnt; /* task lock flag */
UINT32 swtmrHandlerQueue; /* software timer timeout queue id */
UINT32 swtmrTaskId; /* software timer task id */
UINT32 schedFlag; /* pending scheduler flag */
UINT32 idleTaskId;//空闲任务的任务 ID /* idle task id */
UINT32 taskLockCnt;//任务锁计数,用于标记任务是否被锁定 /* task lock flag */
UINT32 swtmrHandlerQueue;//软件定时器的超时队列 ID /* software timer timeout queue id */
UINT32 swtmrTaskId;//软件定时器任务的 ID /* software timer task id */
UINT32 schedFlag;//调度标志,用于表示是否需要进行调度 /* pending scheduler flag */
#ifdef LOSCFG_KERNEL_SMP
UINT32 excFlag; /* cpu halt or exc flag */
UINT32 excFlag;//CPU 异常标志,用于表示 CPU 的运行状态,包括运行、休眠和异常状态 /* cpu halt or exc flag */
#ifdef LOSCFG_KERNEL_SMP_CALL
LOS_DL_LIST funcLink; /* mp function call link */
LOS_DL_LIST funcLink;//多处理器函数调用链表,用于多处理器间的函数调用 /* mp function call link */
#endif
#endif
} Percpu;
/* the kernel per-cpu structure */
extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
//用于获取当前CPU
STATIC INLINE Percpu *OsPercpuGet(VOID)
{
return &g_percpu[ArchCurrCpuid()];
}
//用于获取指定CPU的Percpu结构体指针
STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid)
{
return &g_percpu[cpuid];

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//关于打印函数的私有头文件
#ifndef _LOS_PRINTF_PRI_H
#define _LOS_PRINTF_PRI_H
@ -36,13 +36,16 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//在控制台上打印格式化字符串
extern VOID ConsoleVprintf(const CHAR *fmt, va_list ap);
//在串口上打印格式化字符串
extern VOID UartVprintf(const CHAR *fmt, va_list ap);
//打印异常信息
extern VOID PrintExcInfo(const CHAR *fmt, ...);
//打印内核调试信息
extern VOID LkDprintf(const CHAR *fmt, va_list ap);
#ifdef LOSCFG_SHELL_DMESG
//打印系统日志信息
extern VOID DmesgPrintf(const CHAR *fmt, va_list ap);
#endif

@ -25,7 +25,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这个头文件定义了优先级队列的相关操作函数,
*/
#ifndef _LOS_PRIQUEUE_PRI_H
#define _LOS_PRIQUEUE_PRI_H
@ -57,6 +58,7 @@ extern "C" {
* @see none.
* @since Huawei LiteOS V100R001C00
*/
//初始化优先级队列
extern UINT32 OsPriQueueInit(VOID);
/**
@ -79,6 +81,7 @@ extern UINT32 OsPriQueueInit(VOID);
* @see OsPriQueueDequeue.
* @since Huawei LiteOS V100R001C00
*/
//根据项目的优先级将项目插入到优先级队列中
extern VOID OsPriQueueEnqueue(LOS_DL_LIST *priqueueItem, UINT32 priority);
/**
@ -99,6 +102,7 @@ extern VOID OsPriQueueEnqueue(LOS_DL_LIST *priqueueItem, UINT32 priority);
* @see OsPriQueueEnqueue.
* @since Huawei LiteOS V100R001C00
*/
//从优先级队列中删除一个项目
extern VOID OsPriQueueDequeue(LOS_DL_LIST *priqueueItem);
/**
@ -120,6 +124,7 @@ extern VOID OsPriQueueDequeue(LOS_DL_LIST *priqueueItem);
* @see none.
* @since Huawei LiteOS V100R001C00
*/
//获取优先级队列中具有最高优先级的项目
extern LOS_DL_LIST *OsPriQueueTop(VOID);
/**
@ -140,6 +145,7 @@ extern LOS_DL_LIST *OsPriQueueTop(VOID);
* @see none.
* @since Huawei LiteOS V100R001C00
*/
//获取具有指定优先级的项目数量
extern UINT32 OsPriQueueSize(UINT32 priority);
/**
@ -159,6 +165,7 @@ extern UINT32 OsPriQueueSize(UINT32 priority);
* @see none.
* @since Huawei LiteOS V100R001C00
*/
//获取优先级队列中项目的总数
extern UINT32 OsPriQueueTotalSize(VOID);
/**
@ -181,6 +188,7 @@ extern UINT32 OsPriQueueTotalSize(VOID);
* @see OsPriQueueDequeue.
* @since Huawei LiteOS V100R001C00
*/
//根据项目的优先级将项目插入到优先级队列的头部
extern VOID OsPriQueueEnqueueHead(LOS_DL_LIST *priqueueItem, UINT32 priority);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件提供了针对队列调试的相关函数声明
#ifndef _LOS_QUEUE_DEBUG_PRI_H
#define _LOS_QUEUE_DEBUG_PRI_H
@ -40,7 +40,9 @@ extern "C" {
#endif /* __cplusplus */
/* queue debug initialization interface */
//队列调试初始化接口
extern UINT32 OsQueueDbgInit(VOID);
//队列调试初始化的钩子函数根据配置是否开启队列调试功能来调用OsQueueDbgInit
STATIC INLINE UINT32 OsQueueDbgInitHook(VOID)
{
#ifdef LOSCFG_DEBUG_QUEUE
@ -50,7 +52,9 @@ STATIC INLINE UINT32 OsQueueDbgInitHook(VOID)
#endif
}
/* Update the last time the queue was executed */
//更新队列上次执行的时间
extern VOID OsQueueDbgTimeUpdate(UINT32 queueId);
//更新队列执行时间的钩子函数
STATIC INLINE VOID OsQueueDbgTimeUpdateHook(UINT32 queueId)
{
#ifdef LOSCFG_DEBUG_QUEUE
@ -58,7 +62,9 @@ STATIC INLINE VOID OsQueueDbgTimeUpdateHook(UINT32 queueId)
#endif
}
/* Update the task entry of the queue debug info when created or deleted */
//当队列被创建或删除时,更新队列调试信息中的任务入口信息
extern VOID OsQueueDbgUpdate(UINT32 queueId, TSK_ENTRY_FUNC entry);
//新队列调试信息的钩子函数
STATIC INLINE VOID OsQueueDbgUpdateHook(UINT32 queueId, TSK_ENTRY_FUNC entry)
{
#ifdef LOSCFG_DEBUG_QUEUE
@ -66,7 +72,9 @@ STATIC INLINE VOID OsQueueDbgUpdateHook(UINT32 queueId, TSK_ENTRY_FUNC entry)
#endif
}
/* check the leak of queue */
//检查队列内存泄漏
extern VOID OsQueueCheck(VOID);
//检查队列内存泄漏的钩子函数
STATIC INLINE VOID OsQueueCheckHook(VOID)
{
#ifdef LOSCFG_DEBUG_QUEUE

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了私有队列相关的一些结构体、宏和函数声明
#ifndef _LOS_QUEUE_PRI_H
#define _LOS_QUEUE_PRI_H
@ -42,12 +42,12 @@ typedef enum {
OS_QUEUE_WRITE = 1,
OS_QUEUE_N_RW = 2
} QueueReadWrite;
//枚举类型,分别表示队列的读写操作和队列头尾操作
typedef enum {
OS_QUEUE_HEAD = 0,
OS_QUEUE_TAIL = 1
} QueueHeadTail;
//用于生成或获取队列操作类型和读写类型
#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite))
#define OS_QUEUE_READ_WRITE_GET(type) ((type) & 0x01U)
#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1))
@ -73,6 +73,7 @@ typedef enum {
#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE])
/* Queue information block structure */
//队列信息块结构体,包含了队列的各种属性和状态信息
typedef struct {
UINT8 *queueHandle; /* Pointer to a queue handle */
UINT8 queueState; /* state */
@ -88,12 +89,16 @@ typedef struct {
} LosQueueCB;
/* Queue information control block */
//全局变量,指向所有队列信息块的起始地址
extern LosQueueCB *g_allQueue;
/* alloc a stationary memory for a mail according to queueId */
//用于在指定的内存池中为邮件分配内存
extern VOID *OsQueueMailAlloc(UINT32 queueId, VOID *mailPool, UINT32 timeout);
/* free a stationary memory for a mail according to queueId. */
//释放邮件占用的内存
extern UINT32 OsQueueMailFree(UINT32 queueId, VOID *mailPool, VOID *mailMem);
//列初始化函数,用于初始化队列池
extern UINT32 OsQueueInit(VOID);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了调度器相关的一些结构体和函数声明
#ifndef __LOS_SCHED_DEBUG_PRI_H
#define __LOS_SCHED_DEBUG_PRI_H
@ -34,19 +34,19 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//表示单个CPU的运行时间和上下文切换次数
typedef struct {
UINT64 runtime;
UINT32 contexSwitch;
} SchedPercpu;
//表示整个系统的调度统计信息
typedef struct {
UINT64 startRuntime;
UINT64 allRuntime;
UINT32 allContextSwitch;
SchedPercpu schedPercpu[LOSCFG_KERNEL_CORE_NUM];
UINT64 startRuntime;//开始运行的时间
UINT64 allRuntime;//所有CPU的总共运行时间
UINT32 allContextSwitch;//上下文切换次数
SchedPercpu schedPercpu[LOSCFG_KERNEL_CORE_NUM];//每个CPU的具体情况
} SchedStat;
//用于统计中断处理的时间和次数
extern VOID OsHwiStatistics(size_t intNum);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了调度器相关的一些结构体和函数声明
#ifndef _LOS_SCHED_PRI_H
#define _LOS_SCHED_PRI_H
@ -37,21 +37,22 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//表示任务调度标志位每个位代表一个核心用于防止在OSStartToRun之前进行内核调度
extern UINT32 g_taskScheduled;
/*
* Schedule flag, one bit represents one core.
* This flag is used to prevent kernel scheduling before OSStartToRun.
*/
//设置对应核心的调度标志位
#define OS_SCHEDULER_SET(cpuid) do { \
g_taskScheduled |= (1U << (cpuid)); \
} while (0);
//清除对应核心的调度标志位
#define OS_SCHEDULER_CLR(cpuid) do { \
g_taskScheduled &= ~(1U << (cpuid)); \
} while (0);
//判断当前核心的调度标志位是否激活
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
typedef enum {
@ -60,6 +61,7 @@ typedef enum {
} SchedFlag;
/* Check if preemptable with counter flag */
//用于判断当前任务是否可以被抢占
STATIC INLINE BOOL OsPreemptable(VOID)
{
/*
@ -76,7 +78,7 @@ STATIC INLINE BOOL OsPreemptable(VOID)
LOS_IntRestore(intSave);
return preemptable;
}
//用于判断当前任务是否可以在调度过程中被抢占
STATIC INLINE BOOL OsPreemptableInSched(VOID)
{
BOOL preemptable = FALSE;
@ -104,6 +106,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID)
* Current task needs to already be in the right state or the right
* queues it needs to be in.
*/
//选择下一个任务并切换到它
extern VOID OsSchedResched(VOID);
/*
@ -111,12 +114,14 @@ extern VOID OsSchedResched(VOID);
* try to do the schedule. However, the schedule won't be definitely
* taken place while there're no other higher priority tasks or locked.
*/
//将当前任务放回就绪队列,并尝试进行调度
extern VOID OsSchedPreempt(VOID);
/*
* Just like OsSchedPreempt, except this function will do the OS_INT_ACTIVE
* check, in case the schedule taken place in the middle of an interrupt.
*/
//触发调度,如果在中断中则设置调度标志位
STATIC INLINE VOID LOS_Schedule(VOID)
{
if (OS_INT_ACTIVE) {
@ -138,6 +143,7 @@ STATIC INLINE VOID LOS_Schedule(VOID)
* This API is used to check time slices. If the number of Ticks equals to the time for task switch,
* tasks are switched. Otherwise, the Tick counting continues.
*/
//检查时间片,如果满足任务切换的条件则进行切换
extern VOID OsTimesliceCheck(VOID);
#endif

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了一些用于调试信号量的接口和函数声明
#ifndef _LOS_SEM_DEBUG_PRI_H
#define _LOS_SEM_DEBUG_PRI_H
@ -39,7 +39,9 @@ extern "C" {
#endif /* __cplusplus */
/* semaphore debug initialization interface */
//信号量调试初始化接口
extern UINT32 OsSemDbgInit(VOID);
//更新信号量最后一次执行的时间
STATIC INLINE UINT32 OsSemDbgInitHook(VOID)
{
#ifdef LOSCFG_DEBUG_SEMAPHORE
@ -49,6 +51,7 @@ STATIC INLINE UINT32 OsSemDbgInitHook(VOID)
#endif
}
/* Update the last time the semaphore was executed */
//更新信号量最后一次执行的时间
extern VOID OsSemDbgTimeUpdate(UINT32 semId);
STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semId)
{
@ -58,6 +61,7 @@ STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semId)
return;
}
/* Update the SEM_DEBUG_CB of the semaphore when created or deleted */
//在创建或删除信号量时更新SEM_DEBUG_CB的信息
extern VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count);
STATIC INLINE VOID OsSemDbgUpdateHook(UINT32 semId, TSK_ENTRY_FUNC creator, UINT16 count)
{
@ -67,6 +71,7 @@ STATIC INLINE VOID OsSemDbgUpdateHook(UINT32 semId, TSK_ENTRY_FUNC creator, UINT
return;
}
/* get the full data of SEM_DFX_CB */
//取SEM_DFX_CB的完整数据
extern UINT32 OsSemInfoGetFullData(VOID);
STATIC INLINE VOID OsSemInfoGetFullDataHook(VOID)
{

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件定义了一些关于信号量的数据结构和函数声明,用于信号量的控制和管理。
#ifndef _LOS_SEM_PRI_H
#define _LOS_SEM_PRI_H
@ -38,24 +38,28 @@ extern "C" {
#endif /* __cplusplus */
/* Semaphore control structure. */
//信号量控制块的数据结构
typedef struct {
UINT8 semStat; /* Semaphore state, enum LosSemState */
UINT8 semType; /* Semaphore Type, enum LosSemType */
UINT16 semCount; /* number of available semaphores */
UINT32 semId; /* Semaphore control structure ID, COUNT(UINT16)|INDEX(UINT16) */
UINT8 semStat;//信号量的状态 /* Semaphore state, enum LosSemState */
UINT8 semType;//信号量的类型 /* Semaphore Type, enum LosSemType */
UINT16 semCount;//信号量可用数量 /* number of available semaphores */
UINT32 semId;//信号量ID /* Semaphore control structure ID, COUNT(UINT16)|INDEX(UINT16) */
LOS_DL_LIST semList; /* List of tasks that are waiting on a semaphore */
} LosSemCB;
/* Semaphore type */
//信号量类型的枚举值:包括计数信号量和二进制信号量
enum {
OS_SEM_COUNTING, /* The semaphore is a counting semaphore which max count is LOS_SEM_COUNT_MAX */
OS_SEM_BINARY, /* The semaphore is a binary semaphore which max count is OS_SEM_BINARY_COUNT_MAX */
};
/* Max count of binary semaphores */
//二进制信号量的最大计数值
#define OS_SEM_BINARY_COUNT_MAX 1
/* Semaphore information control block */
//信号量信息控制块的全局指针
extern LosSemCB *g_allSem;
#define GET_SEM_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosSemCB, semList)
@ -75,6 +79,7 @@ extern LosSemCB *g_allSem;
/* This API is used to create a semaphore control structure according to the initial number of available semaphores
* specified by count and return the ID of this semaphore control structure. */
extern UINT32 OsSemInit(VOID);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件是操作系统中关于 Slab 内存分配的底层实现和接口声明
/**
* @defgroup los_slab Slab
* @ingroup kernel
@ -53,7 +53,7 @@ extern "C" {
/* max slab block size */
#define SLAB_MEM_MAX_SIZE (SLAB_MEM_CALSS_STEP_SIZE << (SLAB_MEM_COUNT - 1))
//描述 Slab 内存分配器状态的结构体
typedef struct tagLosSlabStatus {
UINT32 totalSize;
UINT32 usedSize;
@ -61,13 +61,13 @@ typedef struct tagLosSlabStatus {
UINT32 allocCount;
UINT32 freeCount;
} LosSlabStatus;
//Slab 块的节点结构体
typedef struct tagOsSlabBlockNode {
UINT16 magic;
UINT8 blkSz;
UINT8 recordId;
} OsSlabBlockNode;
//原子位图结构体,用于表示 Slab 内存分配器中的位图
struct AtomicBitset {
UINT32 numBits;
UINT32 words[0];
@ -144,25 +144,25 @@ extern UINT32 OsSlabGetMaxFreeBlkSize(const VOID *pool);
extern VOID *OsSlabCtrlHdrGet(const VOID *pool);
#else /* !LOSCFG_KERNEL_MEM_SLAB_EXTENTION */
//初始化 Slab 内存池
STATIC INLINE VOID OsSlabMemInit(VOID *pool, UINT32 size)
{
}
//销毁 Slab 内存池
STATIC INLINE VOID OsSlabMemDeinit(VOID *pool)
{
}
//从 Slab 内存池中分配内存
STATIC INLINE VOID *OsSlabMemAlloc(VOID *pool, UINT32 size)
{
return NULL;
}
//释放 Slab 内存池中的内存
STATIC INLINE BOOL OsSlabMemFree(VOID *pool, VOID *ptr)
{
return FALSE;
}
//检查指针是否属于 Slab 内存池
STATIC INLINE UINT32 OsSlabMemCheck(const VOID *pool, const VOID *ptr)
{
return (UINT32)-1;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//一个用于操作排序链表SortLink的私有头文件。
#ifndef _LOS_SORTLINK_PRI_H
#define _LOS_SORTLINK_PRI_H
@ -118,13 +118,17 @@ typedef struct {
UINT16 cursor;
UINT16 reserved;
} SortLinkAttribute;
//初始化排序链表
extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader);
//一个节点添加到排序链表中
extern VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList);
//从排序链表中删除一个节点
extern VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList);
//获取下一个到期时间
extern UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader);
//获取目标节点的到期时间
extern UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader,
const SortLinkList *targetSortList);
//更新到期时间 const SortLinkList *targetSortList);
extern VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//一个用于处理堆栈信息的私有头文件
#ifndef _LOS_STACK_INFO_PRI_H
#define _LOS_STACK_INFO_PRI_H
@ -37,20 +37,25 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//堆栈信息结构体
typedef struct {
VOID *stackTop;
UINT32 stackSize;
CHAR *stackName;
VOID *stackTop;//堆栈的顶部
UINT32 stackSize;//堆栈的大小
CHAR *stackName;//堆栈的名称
} StackInfo;
//表示无效的水位线值
#define OS_INVALID_WATERLINE 0xFFFFFFFF
//于检查堆栈顶部的魔术字是否有效的宏定义
#define OS_STACK_MAGIC_CHECK(topstack) (*(UINTPTR *)(topstack) == OS_STACK_MAGIC_WORD) /* 1:magic valid 0:unvalid */
//用于异常时获取堆栈信息的函数
extern VOID OsExcStackInfo(VOID);
//用于注册异常时获取的堆栈信息的函数
extern VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum);
//用于初始化堆栈的函数
extern VOID OsStackInit(VOID *stacktop, UINT32 stacksize);
//用于获取堆栈的水位线和使用峰值的函数
extern UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed);
//用于获取堆栈信息的函数
extern VOID OsGetStackInfo(const StackInfo **stackInfo, UINT32 *stackNum);
#ifdef __cplusplus

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//一个用于实现软件定时器的私有头文件。
#ifndef _LOS_SWTMR_PRI_H
#define _LOS_SWTMR_PRI_H
@ -40,7 +40,7 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_BASE_CORE_SWTMR
//软件定时器的状态枚举,包括未使用、已创建和计时中
enum SwtmrState {
OS_SWTMR_STATUS_UNUSED, /* The software timer is not used. */
OS_SWTMR_STATUS_CREATED, /* The software timer is created. */
@ -48,12 +48,13 @@ enum SwtmrState {
};
/* Structure of the callback function that handles software timer timeout */
//处理软件定时器超时回调的回调函数结构体
typedef struct {
SWTMR_PROC_FUNC handler; /* Callback function that handles software timer timeout */
UINTPTR arg; /* Parameter passed in when the callback function
that handles software timer timeout is called */
} SwtmrHandlerItem;
//软件定时器控制块结构体
typedef struct {
SortLinkList sortList;
UINT8 state; /* Software timer state */
@ -71,22 +72,28 @@ typedef struct {
} LosSwtmrCB;
/* Type of the pointer to the structure of the callback function that handles software timer timeout */
//指向处理软件定时器超时回调的回调函数结构体的指针类型
typedef SwtmrHandlerItem *SwtmrHandlerItemPtr;
//软件定时器控制块数组
extern LosSwtmrCB *g_swtmrCBArray;
/* The software timer count list */
//软件定时器排序链表
extern SortLinkAttribute g_swtmrSortLink;
#define OS_SWT_FROM_SWTID(swtmrId) ((LosSwtmrCB *)g_swtmrCBArray + ((swtmrId) % KERNEL_SWTMR_LIMIT))
/* This API is used to scan a software timer when a Tick interrupt occurs and determine whether
* the software timer expires. */
//在Tick中断发生时扫描软件定时器判断是否到达超时时间
extern VOID OsSwtmrScan(VOID);
//初始化软件定时器
extern UINT32 OsSwtmrInit(VOID);
//软件定时器任务,用于处理软件定时器的超时事件
extern VOID OsSwtmrTask(VOID);
//软件定时器自旋锁
extern SPIN_LOCK_S g_swtmrSpin;
#ifdef LOSCFG_EXC_INTERACTION
//判断当前任务是否为软件定时器任务
extern BOOL IsSwtmrTask(UINT32 taskId);
#endif
#endif /* LOSCFG_BASE_CORE_SWTMR */

@ -25,7 +25,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这是关于LiteOS中任务调度相关的头文件其中定义了任务控制块的数据结构和一些任务管理的接口函数。
*/
#ifndef _LOS_TASK_PRI_H
#define _LOS_TASK_PRI_H

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//这个头文件是关于系统时钟中断tick的定义和操作。
#ifndef _LOS_TICK_PRI_H
#define _LOS_TICK_PRI_H
@ -40,30 +40,41 @@ extern "C" {
#endif /* __cplusplus */
/* spinlock for tick */
//用于保护tick相关操作的自旋锁
extern SPIN_LOCK_S g_tickSpin;
//获取tick自旋锁并保存状态
#define TICK_LOCK(state) LOS_SpinLockSave(&g_tickSpin, &(state))
//释放tick自旋锁并恢复状态
#define TICK_UNLOCK(state) LOS_SpinUnlockRestore(&g_tickSpin, (state))
/* Count of Ticks */
//全局变量保存系统tick的计数值
extern volatile UINT64 g_tickCount[];
/* Cycle to nanosecond scale */
//循环周期到纳秒的转换比例
extern DOUBLE g_cycle2NsScale;
/* This API is called when the system tick timeout and triggers the interrupt. */
//系统tick中断处理函数当系统tick超时触发中断时调用
extern VOID OsTickHandler(VOID);
//初始化系统tick相关配置
extern UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond);
//启动系统tick中断
extern VOID OsTickStart(VOID);
/* Convert from the cycle count to nanosecond. */
//将循环周期转换为纳秒
#define CYCLE_TO_NS(cycles) ((cycles) * g_cycle2NsScale)
/**
* Current system timer register is 32 bit, therefore TIMER_MAXLOAD define just in order to avoid ambiguity.
*/
//定时器最大加载值,用于避免歧义
#define TIMER_MAXLOAD 0xffffffff
#ifdef LOSCFG_KERNEL_TICKLESS
//tick中断标志在LOSCFG_KERNEL_TICKLESS选项开启时使用
#define LOS_TICK_INT_FLAG 0x80000000
#endif

@ -26,6 +26,10 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这是一个位图bitmap的实现用于对位图进行设置、清除和获取最高/最低位的操作。
使32UINT32
*/
#include "los_bitmap.h"
#include "los_toolchain.h"
@ -36,7 +40,7 @@ extern "C" {
#endif /* __cplusplus */
#define OS_BITMAP_MASK 0x1FU
//LOS_BitmapSet将指定位置的位设置为1
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
@ -45,7 +49,7 @@ VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
*bitmap |= 1U << (pos & OS_BITMAP_MASK);
}
//LOS_BitmapClr将指定位置的位清除为0
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
@ -54,7 +58,7 @@ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));
}
//LOS_HighBitGet获取位图中最高位值为1的位置的索引
UINT16 LOS_HighBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
@ -63,7 +67,7 @@ UINT16 LOS_HighBitGet(UINT32 bitmap)
return (OS_BITMAP_MASK - CLZ(bitmap));
}
//LOS_LowBitGet获取位图中最低位值为1的位置的索引
UINT16 LOS_LowBitGet(UINT32 bitmap)
{
if (bitmap == 0) {

@ -25,7 +25,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这段代码是关于错误处理的相关功能,包括注册错误处理函数和执行错误处理的函数。
*/
#include "los_err.h"
#ifdef __cplusplus
@ -35,8 +36,9 @@ extern "C" {
#endif /* __cplusplus */
/* Hook function for error handling. */
//g_usrErrFunc全局变量用于保存用户注册的错误处理函数
LITE_OS_SEC_BSS LOS_ERRORHANDLE_FUNC g_usrErrFunc;
//LOS_ErrHandle用于执行错误处理的函数当系统出现错误时会调用该函数来处理错误信息
LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo,
UINT32 paraLen, VOID *para)
{
@ -46,7 +48,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32
return LOS_OK;
}
//LOS_RegErrHandle用于注册错误处理函数的接口用户可以通过该函数注册自定义的错误处理函数
LITE_OS_SEC_TEXT_INIT VOID LOS_RegErrHandle(LOS_ERRORHANDLE_FUNC func)
{
g_usrErrFunc = func;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这段代码是关于事件管理的实现,包括事件的初始化、读取、写入、清除等操作。*/
#include "los_event_pri.h"
#include "los_task_pri.h"
#include "los_spinlock.h"
@ -38,7 +38,7 @@
extern "C" {
#endif
#endif /* __cplusplus */
//LOS_EventInit()函数用于初始化事件控制块eventCB并将事件ID、事件列表等属性设置为初始值
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
{
UINT32 intSave;
@ -55,7 +55,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
LOS_IntRestore(intSave);
return LOS_OK;
}
//OsEventParamCheck()函数用于检查参数的有效性包括事件掩码eventMask、模式mode
LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode)
{
if (ptr == NULL) {
@ -75,9 +75,10 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMa
!(mode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) {
return LOS_ERRNO_EVENT_FLAGS_INVALID;
}
//指针非空事件掩码非0事件掩码不包含LOS_ERRTYPE_ERROR标志位模式合法
return LOS_OK;
}
//OsEventPoll()函数用于轮询事件,根据指定的事件掩码和模式判断是否满足条件
LITE_OS_SEC_TEXT STATIC UINT32 OsEventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode)
{
UINT32 ret = 0;
@ -101,7 +102,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventPoll(UINT32 *eventId, UINT32 eventMask, UI
return ret;
}
//OsEventReadCheck()函数用于检查事件读取操作的参数有效性包括事件控制块eventCB、事件掩码eventMask、模式mode
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode)
{
UINT32 ret;
@ -122,7 +123,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT3
}
return LOS_OK;
}
//OsEventReadImp()函数是事件读取的实现,根据指定的事件掩码和模式进行轮询,并根据超时时间和是否只读取一次进行相应的操作
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode,
UINT32 timeout, BOOL once, UINT32 *intSave)
{
@ -165,7 +166,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM
}
return ret;
}
//OsEventRead()函数是对外提供的事件读取接口调用OsEventReadCheck()和OsEventReadImp()实现事件的读取操作
LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode,
UINT32 timeout, BOOL once)
{
@ -184,7 +185,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask
SCHEDULER_UNLOCK(intSave);
return ret;
}
//OsEventWrite()函数用于向事件控制块中写入指定的事件
LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once)
{
LosTaskCB *resumedTask = NULL;
@ -230,7 +231,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events,
}
return LOS_OK;
}
//LOS_EventPoll()函数是对外提供的事件轮询接口调用OsEventParamCheck()和OsEventPoll()实现事件的轮询操作
LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode)
{
UINT32 ret;
@ -246,17 +247,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32
SCHEDULER_UNLOCK(intSave);
return ret;
}
//LOS_EventRead()函数是对外提供的事件读取接口调用OsEventRead()实现事件的读取操作
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
{
return OsEventRead(eventCB, eventMask, mode, timeout, FALSE);
}
//LOS_EventWrite()函数是对外提供的事件写入接口调用OsEventWrite()实现事件的写入操作
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
{
return OsEventWrite(eventCB, events, FALSE);
}
//LOS_EventDestroy()函数用于销毁事件控制块将事件ID设置为0
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
{
UINT32 intSave;
@ -279,7 +280,7 @@ OUT:
LOS_TRACE(EVENT_DELETE, (UINTPTR)eventCB, ret);
return ret;
}
//LOS_EventClear()函数用于清除指定的事件
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events)
{
UINT32 intSave;
@ -296,18 +297,19 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events)
return LOS_OK;
}
//OsEventWriteOnce()函数是事件写入的实现与OsEventWrite()类似,但只写入一次
LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events)
{
return OsEventWrite(eventCB, events, TRUE);
}
#ifdef LOSCFG_COMPAT_POSIX
//OsEventReadOnce()函数是事件读取的实现与OsEventRead()类似,但只读取一次
LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
{
return OsEventRead(eventCB, eventMask, mode, timeout, TRUE);
}
// /OsEventReadWithCond()函数用于根据条件读取事件,只有当条件满足时才进行事件读取操作
LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB,
UINT32 eventMask, UINT32 mode, UINT32 timeout)
{

@ -25,7 +25,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这是关于LiteOS中异常处理的代码其中包括记录异常信息、异常信息保存和读取等功能。
*/
#include "los_exc.h"
#include "los_printf_pri.h"
#include "los_task_pri.h"
@ -48,7 +49,7 @@
extern "C" {
#endif
#endif /* __cplusplus */
//ExcInfoDumpFormat的结构体类型包含了用于存储异常信息的缓冲区指针、偏移量、长度和存储地址等信息
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
typedef struct {
CHAR *buf; /* pointer to the buffer for storing the exception information */
@ -56,11 +57,13 @@ typedef struct {
UINT32 len; /* the size of storing the exception information */
UINTPTR dumpAddr; /* the address of storing the exception information */
} ExcInfoDumpFormat;
//全局变量g_excInfoPool用于存储异常信息的缓冲区和相关的信息
STATIC ExcInfoDumpFormat g_excInfoPool = {0};
/* the hook of read-writing exception information */
STATIC __attribute__((section(".data"))) LogReadWriteFunc g_dumpHook = NULL;
//LOS_ExcInfoRegHook注册异常信息读写钩子函数用于设置异常信息的存储地址、长度以及缓冲区等信息
//"钩子函数"是指在特定事件发生时会被调用的函数
//通过使用钩子函数,可以在异常发生时灵活地执行特定的操作,例如记录异常信息、进行特定的处理或通知其他模块进行相应的操作
VOID LOS_ExcInfoRegHook(UINTPTR startAddr, UINT32 len, CHAR *buf, LogReadWriteFunc hook)
{
if ((hook == NULL) || (buf == NULL)) {
@ -78,57 +81,57 @@ VOID LOS_ExcInfoRegHook(UINTPTR startAddr, UINT32 len, CHAR *buf, LogReadWriteFu
g_excInfoPool.buf = buf;
g_dumpHook = hook;
}
//OsSetExcInfoRW设置异常信息读写钩子函数
VOID OsSetExcInfoRW(LogReadWriteFunc func)
{
g_dumpHook = func;
}
//OsGetExcInfoRW获取异常信息读写钩子函数
LogReadWriteFunc OsGetExcInfoRW(VOID)
{
return g_dumpHook;
}
//OsSetExcInfoBuf设置异常信息的缓冲区
VOID OsSetExcInfoBuf(CHAR *buf)
{
g_excInfoPool.buf = buf;
}
//OsGetExcInfoBuf获取异常信息的缓冲区
CHAR *OsGetExcInfoBuf(VOID)
{
return g_excInfoPool.buf;
}
//OsSetExcInfoOffset设置异常信息的偏移量
VOID OsSetExcInfoOffset(UINT32 Offset)
{
g_excInfoPool.offset = Offset;
}
//OsGetExcInfoOffset获取异常信息的偏移量
UINT32 OsGetExcInfoOffset(VOID)
{
return g_excInfoPool.offset;
}
//OsSetExcInfoDumpAddr设置异常信息的存储地址
VOID OsSetExcInfoDumpAddr(UINTPTR addr)
{
g_excInfoPool.dumpAddr = addr;
}
//OsGetExcInfoDumpAddr获取异常信息的存储地址
UINTPTR OsGetExcInfoDumpAddr(VOID)
{
return g_excInfoPool.dumpAddr;
}
//OsSetExcInfoLen设置异常信息的长度
VOID OsSetExcInfoLen(UINT32 len)
{
g_excInfoPool.len = len;
}
//OsGetExcInfoLen获取异常信息的长度
UINT32 OsGetExcInfoLen(VOID)
{
return g_excInfoPool.len;
}
//WriteExcBufVa将格式化的字符串写入异常信息缓冲区
VOID WriteExcBufVa(const CHAR *format, va_list arglist)
{
errno_t ret;
@ -143,7 +146,7 @@ VOID WriteExcBufVa(const CHAR *format, va_list arglist)
g_excInfoPool.offset += ret;
}
}
//WriteExcInfoToBuf将格式化的字符串写入异常信息缓冲区
VOID WriteExcInfoToBuf(const CHAR *format, ...)
{
va_list arglist;
@ -152,7 +155,7 @@ VOID WriteExcInfoToBuf(const CHAR *format, ...)
WriteExcBufVa(format, arglist);
va_end(arglist);
}
//OsRecordExcInfoTime记录异常信息的时间
VOID OsRecordExcInfoTime(VOID)
{
#define NOW_TIME_LENGTH 24
@ -169,7 +172,7 @@ VOID OsRecordExcInfoTime(VOID)
#undef NOW_TIME_LENGTH
PrintExcInfo("%s \n", nowTime);
}
//OsShellCmdReadExcInfo读取并打印异常信息的Shell命令
#ifdef LOSCFG_SHELL
INT32 OsShellCmdReadExcInfo(INT32 argc, const CHAR **argv)
{
@ -200,6 +203,9 @@ SHELLCMD_ENTRY(readExcInfo_shellcmd, CMD_TYPE_EX, "excInfo", 0, (CmdCallBackFunc
#endif
#ifdef LOSCFG_EXC_INTERACTION
//OsCheckExcInteractionTask检查任务是否为异常交互任务
//异常交互任务通常指的是用于处理异常情况的特殊任务或线程
//当系统发生严重的错误或异常时,需要立即采取相应的措施来处理异常情况,这就需要使用异常交互任务来处理
UINT32 OsCheckExcInteractionTask(const TSK_INIT_PARAM_S *initParam)
{
if ((initParam->pfnTaskEntry == (TSK_ENTRY_FUNC)ShellTask) ||
@ -209,7 +215,7 @@ UINT32 OsCheckExcInteractionTask(const TSK_INIT_PARAM_S *initParam)
}
return LOS_NOK;
}
//OsKeepExcInteractionTask保留异常交互任务删除其他任务
VOID OsKeepExcInteractionTask(VOID)
{
LosTaskCB *taskCB = NULL;
@ -243,7 +249,7 @@ VOID OsKeepExcInteractionTask(VOID)
}
#endif
//LOS_Panic打印异常信息并停止CPU执行
VOID LOS_Panic(const CHAR *fmt, ...)
{
va_list ap;
@ -252,7 +258,7 @@ VOID LOS_Panic(const CHAR *fmt, ...)
va_end(ap);
ArchHaltCpu();
}
//LOS_BackTrace打印当前任务的运行信息和回溯堆栈
VOID LOS_BackTrace(VOID)
{
#ifdef LOSCFG_BACKTRACE
@ -262,7 +268,7 @@ VOID LOS_BackTrace(VOID)
ArchBackTrace();
#endif
}
//LOS_TaskBackTrace打印指定任务的运行信息和回溯堆栈
VOID LOS_TaskBackTrace(UINT32 taskID)
{
#ifdef LOSCFG_BACKTRACE
@ -289,6 +295,7 @@ VOID LOS_TaskBackTrace(UINT32 taskID)
#ifdef __GNUC__
/* stack protector */
//__stack_chk_fail用于栈保护机制当发现栈被破坏时触发异常处理
VOID __stack_chk_fail(VOID)
{
/* __builtin_return_address is a builtin function, building in gcc */

@ -25,7 +25,9 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOS使
*/
#include "los_hwi_pri.h"
#include "los_hwi.h"
#include "los_memory.h"
@ -61,7 +63,7 @@ const HwiControllerOps *g_hwiOps = NULL;
typedef VOID (*HWI_PROC_FUNC0)(VOID);
typedef VOID (*HWI_PROC_FUNC2)(INT32, VOID *);
//OsIrqNestingActive用于在处理中断期间激活中断嵌套计数器避免在处理时钟中断时进行抢占
STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum)
{
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
@ -71,7 +73,7 @@ STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum)
}
#endif
}
//OsIrqNestingInactive用于在处理中断结束后禁用中断嵌套计数器
STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum)
{
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
@ -80,17 +82,17 @@ STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum)
}
#endif
}
//OsIrqNestingCntGet获取当前CPU的中断嵌套计数值
size_t OsIrqNestingCntGet(VOID)
{
return g_intCount[ArchCurrCpuid()];
}
//OsIrqNestingCntSet设置当前CPU的中断嵌套计数值
VOID OsIrqNestingCntSet(size_t val)
{
g_intCount[ArchCurrCpuid()] = val;
}
//InterruptHandle处理中断的实际函数根据中断号调用对应的中断处理函数
STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm)
{
hwiForm->respCount++;
@ -114,7 +116,7 @@ STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm)
}
#endif
}
//OsIntHandle中断处理入口函数负责处理中断前的一些准备工作如调用中断处理前的钩子函数等
VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm)
{
size_t *intCnt = NULL;
@ -148,7 +150,7 @@ VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm)
OsCpupIrqEnd(hwiNum);
#endif
}
//OsIntEntry中断向量入口函数根据中断号调用对应的中断处理函数
VOID OsIntEntry(VOID)
{
if ((g_hwiOps != NULL) && (g_hwiOps->handleIrq != NULL)) {
@ -156,7 +158,7 @@ VOID OsIntEntry(VOID)
}
return;
}
//OsHwiCpIrqParam根据传入的中断参数结构体分配内存并将参数信息拷贝到新分配的内存中
STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam)
{
HWI_IRQ_PARAM_S *paramByAlloc = NULL;
@ -169,6 +171,7 @@ STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam)
return (HWI_ARG_T)paramByAlloc;
}
#ifndef LOSCFG_SHARED_IRQ
//OsHwiDel删除指定的中断处理函数
STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId)
{
UINT32 intSave;
@ -190,7 +193,7 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam,
HWI_UNLOCK(intSave);
return LOS_OK;
}
//OsHwiCreate创建中断处理函数并将其添加到中断处理链表中
STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
const HWI_IRQ_PARAM_S *irqParam)
{
@ -218,6 +221,7 @@ STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_F
return LOS_OK;
}
#else /* LOSCFG_SHARED_IRQ */
//函数OsFreeHwiNode:用于释放中断处理函数节点,并在需要时禁止该中断
STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm, UINT32 irqId)
{
UINT32 ret = LOS_OK;
@ -240,7 +244,8 @@ STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm,
return ret;
}
//OsHwiDel:用于删除硬件中断处理函数,它首先判断中断是否是共享中断
//如果不是,则直接释放该中断的处理函数节点;如果是共享中断则遍历链表找到对应的设备ID然后释放该中断的处理函数节点
STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId)
{
HwiHandleInfo *hwiFormPrev = NULL;
@ -290,7 +295,8 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UIN
HWI_UNLOCK(intSave);
return ret;
}
//OsHwiCreate:用于创建硬件中断处理函数它首先判断中断是否是共享中断并检查是否已经存在具有相同设备ID的中断处理函数节点如果存在则返回错误
//然后申请内存并初始化新的中断处理函数节点,将其添加到链表中
STATIC UINT32 OsHwiCreate(HwiHandleInfo *head, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
const HWI_IRQ_PARAM_S *irqParam)
{
@ -359,7 +365,9 @@ size_t IntActive()
LOS_IntRestore(intSave);
return intCount;
}
//LOS_HwiCreate 函数:用于创建硬件中断处理函数
//它会注册一个中断处理函数,并将其与指定的硬件中断号相关联
//可以设置中断的优先级、硬件中断模式和处理函数
LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
HWI_PRIOR_T hwiPrio,
HWI_MODE_T hwiMode,
@ -396,7 +404,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
}
return ret;
}
//LOS_HwiDelete 函数:用于删除已经创建的硬件中断处理函数
//通过指定硬件中断号,可以将之前注册的中断处理函数从系统中删除
LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam)
{
UINT32 ret;
@ -417,7 +426,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqP
return ret;
}
//LOS_HwiTrigger 函数:用于手动触发指定的硬件中断
//调用该函数后,会立即触发对应的硬件中断,使得系统执行相应的中断处理函数
LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum)
{
if ((g_hwiOps == NULL) || (g_hwiOps->triggerIrq == NULL)) {
@ -427,7 +437,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum)
return g_hwiOps->triggerIrq(hwiNum);
}
//LOS_HwiEnable 函数:用于使能指定的硬件中断
//调用该函数后,系统将允许对应的硬件中断产生,并执行相应的中断处理函数
LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum)
{
if ((g_hwiOps == NULL) || (g_hwiOps->enableIrq == NULL)) {
@ -437,7 +448,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum)
return g_hwiOps->enableIrq(hwiNum);
}
//LOS_HwiDisable 函数:用于禁止指定的硬件中断
//调用该函数后,系统将阻止对应的硬件中断产生,屏蔽其影响
LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum)
{
if ((g_hwiOps == NULL) || (g_hwiOps->disableIrq == NULL)) {
@ -447,7 +459,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum)
return g_hwiOps->disableIrq(hwiNum);
}
//LOS_HwiClear 函数:用于清除指定的硬件中断
//在某些平台上,硬件中断发生后可能需要手动清除中断标志位,以便正确处理后续的中断
LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum)
{
if ((g_hwiOps == NULL) || (g_hwiOps->clearIrq == NULL)) {
@ -457,7 +470,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum)
return g_hwiOps->clearIrq(hwiNum);
}
//LOS_HwiSetPriority 函数:用于设置硬件中断的优先级
//通过指定硬件中断号和优先级,可以调整硬件中断的触发顺序
LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority)
{
if ((g_hwiOps == NULL) || (g_hwiOps->setIrqPriority == NULL)) {
@ -468,6 +482,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T prio
return g_hwiOps->setIrqPriority(hwiNum, priority);
}
#ifdef LOSCFG_KERNEL_SMP
//LOS_HwiSetAffinity函数用于设置硬件中断的处理CPU亲和性
//它首先检查硬件中断操作函数指针是否为空然后调用具体的操作函数来设置中断的处理CPU亲和性
LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
{
if ((g_hwiOps == NULL) || (g_hwiOps->setIrqCpuAffinity == NULL)) {
@ -477,7 +493,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
return g_hwiOps->setIrqCpuAffinity(hwiNum, cpuMask);
}
//LOS_HwiSendIpi函数用于发送硬件中断处理请求给指定的CPU
//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来发送中断处理请求
LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
{
if ((g_hwiOps == NULL) || (g_hwiOps->sendIpi == NULL)) {
@ -490,6 +507,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
#endif
#ifdef LOSCFG_KERNEL_LOWPOWER
//LOS_IntWakeupHookReg函数用于注册中断唤醒回调函数
//它将传入的回调函数赋值给全局变量g_intWakeupHook以便在中断唤醒时调用该回调函数
LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook)
{
g_intWakeupHook = hook;
@ -497,6 +516,8 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook)
#endif
/* Initialization of the hardware interrupt */
//OsHwiInit函数用于初始化硬件中断
//它会调用具体的平台相关函数来进行硬件中断的初始化操作
LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID)
{
ArchIrqInit();

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*这段代码是关于锁依赖检查的实现。包含了一些头文件和函数的定义,用于在多核系统中检测锁的使用情况*/
#include "los_base.h"
#include "los_spinlock.h"
#include "los_task_pri.h"
@ -47,6 +47,8 @@ extern "C" {
STATIC Atomic g_lockdepAvailable = 1;
/* atomic insurance for lockdep check */
//OsLockDepRequire该函数用于获取锁依赖检查的原子操作确保在进行锁依赖检查时不会被中断
//原子操作是指在计算机科学中,不会被中断的操作
STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave)
{
*intSave = LOS_IntLock();
@ -54,13 +56,13 @@ STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave)
/* busy waiting */
}
}
//OsLockDepRelease释放锁依赖检查的原子操作用于在完成锁依赖检查后恢复正常的中断状态
STATIC INLINE VOID OsLockDepRelease(UINT32 intSave)
{
LOS_AtomicSet(&g_lockdepAvailable, 1);
LOS_IntRestore(intSave);
}
//OsLockDepGetCycles获取当前 CPU 的周期计数器的值,用于记录锁请求和释放时的时间戳
STATIC INLINE UINT64 OsLockDepGetCycles(VOID)
{
UINT32 high, low;
@ -69,7 +71,7 @@ STATIC INLINE UINT64 OsLockDepGetCycles(VOID)
/* combine cycleHi and cycleLo into 8 bytes cycles */
return (((UINT64)high << 32) + low);
}
//OsLockDepErrorStringGet根据错误类型返回对应的错误字符串用于打印错误信息
STATIC INLINE CHAR *OsLockDepErrorStringGet(enum LockDepErrType type)
{
CHAR *errorString = NULL;
@ -94,7 +96,7 @@ STATIC INLINE CHAR *OsLockDepErrorStringGet(enum LockDepErrType type)
return errorString;
}
//OsLockDepPanic当发生严重错误时触发系统的崩溃通常在检测到死锁等无法修复的情况下调用
WEAK VOID OsLockDepPanic(enum LockDepErrType errType)
{
/* halt here */
@ -103,7 +105,7 @@ WEAK VOID OsLockDepPanic(enum LockDepErrType errType)
OsBackTrace();
while (1) {}
}
//OsLockDepDumpLock输出锁依赖检查失败时的调试信息包括任务名、任务 ID、CPU 号等,并最终触发崩溃
STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock,
const VOID *requestAddr, enum LockDepErrType errType)
{
@ -143,7 +145,7 @@ STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock,
OsLockDepPanic(errType);
}
//OsLockDepCheckDependancy检查当前任务与锁的所有者之间是否存在依赖关系以避免死锁
STATIC BOOL OsLockDepCheckDependancy(const LosTaskCB *current, const LosTaskCB *lockOwner)
{
BOOL checkResult = TRUE;
@ -164,7 +166,7 @@ STATIC BOOL OsLockDepCheckDependancy(const LosTaskCB *current, const LosTaskCB *
return checkResult;
}
//OsLockDepCheckIn在请求锁时进行依赖检查记录锁的请求地址和等待时间如检查失败则触发崩溃
VOID OsLockDepCheckIn(const SPIN_LOCK_S *lock)
{
UINT32 intSave;
@ -217,7 +219,7 @@ OUT:
OsLockDepRelease(intSave);
}
//OsLockDepRecord记录成功获取锁的时间戳和持有者信息并更新锁的所有者和 CPU 号等信息
VOID OsLockDepRecord(SPIN_LOCK_S *lock)
{
UINT32 intSave;
@ -250,7 +252,7 @@ VOID OsLockDepRecord(SPIN_LOCK_S *lock)
OsLockDepRelease(intSave);
}
//OsLockDepCheckOut在释放锁时进行依赖检查记录持有时间并清除相关信息如检查失败则触发崩溃
VOID OsLockDepCheckOut(SPIN_LOCK_S *lock)
{
UINT32 intSave;
@ -302,7 +304,8 @@ VOID OsLockDepCheckOut(SPIN_LOCK_S *lock)
OUT:
OsLockDepRelease(intSave);
}
//OsLockdepClearSpinlocks清除当前任务持有的所有自旋锁通常在系统处于异常状态下调用以确保解锁
//自旋锁是一种用于多线程同步的机制。在使用自旋锁时,线程会反复检查锁是否被释放,如果锁已经被占用,线程就会一直循环等待,直到锁被释放为止
VOID OsLockdepClearSpinlocks(VOID)
{
LosTaskCB *task = OsCurrTaskGet();

@ -25,7 +25,7 @@
* 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"
#include "los_misc_pri.h"
#include "los_memory_pri.h"
@ -48,23 +48,23 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_LIB_CONFIGURABLE
LITE_OS_SEC_BSS UINT32 g_osSysClock;
LITE_OS_SEC_BSS UINT32 g_semLimit;
LITE_OS_SEC_BSS UINT32 g_muxLimit;
LITE_OS_SEC_BSS UINT32 g_queueLimit;
LITE_OS_SEC_BSS UINT32 g_swtmrLimit;
LITE_OS_SEC_BSS UINT32 g_taskLimit;
LITE_OS_SEC_BSS UINT32 g_minusOneTickPerSecond;
LITE_OS_SEC_BSS UINT32 g_taskMinStkSize;
LITE_OS_SEC_BSS UINT32 g_taskIdleStkSize;
LITE_OS_SEC_BSS UINT32 g_taskSwtmrStkSize;
LITE_OS_SEC_BSS UINT32 g_taskDfltStkSize;
LITE_OS_SEC_BSS UINT32 g_timeSliceTimeOut;
LITE_OS_SEC_DATA BOOL g_nxEnabled = FALSE;
LITE_OS_SEC_BSS UINTPTR g_dlNxHeapBase;
LITE_OS_SEC_BSS UINT32 g_dlNxHeapSize;
LITE_OS_SEC_BSS UINT32 g_osSysClock; //操作系统的系统时钟频率
LITE_OS_SEC_BSS UINT32 g_semLimit; //信号量的最大数量限制
LITE_OS_SEC_BSS UINT32 g_muxLimit; //互斥锁的最大数量限制
LITE_OS_SEC_BSS UINT32 g_queueLimit; //队列最大数量限制
LITE_OS_SEC_BSS UINT32 g_swtmrLimit; //软件定时器的最大数量限制
LITE_OS_SEC_BSS UINT32 g_taskLimit; //任务的最大数量限制
LITE_OS_SEC_BSS UINT32 g_minusOneTickPerSecond; //每秒减去的滴答数,用于时间戳计算
LITE_OS_SEC_BSS UINT32 g_taskMinStkSize;//任务的最小堆栈大小
LITE_OS_SEC_BSS UINT32 g_taskIdleStkSize; //空闲任务的堆栈大小
LITE_OS_SEC_BSS UINT32 g_taskSwtmrStkSize; //软件定时器任务的堆栈大小
LITE_OS_SEC_BSS UINT32 g_taskDfltStkSize; //默认任务的堆栈大小
LITE_OS_SEC_BSS UINT32 g_timeSliceTimeOut; //时间片的超时时间
LITE_OS_SEC_DATA BOOL g_nxEnabled = FALSE; //是否启用了内存保护机制
LITE_OS_SEC_BSS UINTPTR g_dlNxHeapBase; //动态加载库的内存堆起始地址
LITE_OS_SEC_BSS UINT32 g_dlNxHeapSize; //动态加载库的内存堆大小
#endif
#ifdef LOSCFG_KERNEL_TRACE
@ -77,11 +77,12 @@ LMS_INIT_HOOK g_lmsMemInitHook = NULL;
LMS_FUNC_HOOK g_lmsMallocHook = NULL;
LMS_FUNC_HOOK g_lmsFreeHook = NULL;
#endif
//LOS_Align用于将给定的地址按指定的边界对齐返回对齐后的地址
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
{
return (addr + boundary - 1) & ~((UINTPTR)(boundary - 1));
}
//OsDumpMemByte用于以字节为单位打印内存中的数据
LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
{
UINT32 interval;
@ -97,7 +98,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
(VOID)LOS_TaskDelay(interval);
}
//OsDumpMemByte用于以字节为单位打印内存中的数据
VOID OsDumpMemByte(size_t length, UINTPTR addr)
{
size_t dataLen;
@ -141,6 +142,7 @@ VOID OsDumpMemByte(size_t length, UINTPTR addr)
}
#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_DEBUG_MUTEX) || defined(LOSCFG_DEBUG_QUEUE)
//OsArraySort快速排序
VOID OsArraySort(UINT32 *sortArray, UINT32 start, UINT32 end,
const SortParam *sortParam, OsCompareFunc compareFunc)
{

@ -25,7 +25,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*针对多处理器SMP系统的操作系统内核部分的实现
*/
#include "los_mp_pri.h"
#include "los_task_pri.h"
#include "los_percpu_pri.h"
@ -45,7 +46,7 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_mpCallSpin);
#define MP_CALL_LOCK(state) LOS_SpinLockSave(&g_mpCallSpin, &(state))
#define MP_CALL_UNLOCK(state) LOS_SpinUnlockRestore(&g_mpCallSpin, (state))
#endif
//LOS_MpSchedule多处理器调度函数用于向指定的处理器发送调度中断
VOID LOS_MpSchedule(UINT32 target)
{
UINT32 ret;
@ -57,12 +58,12 @@ VOID LOS_MpSchedule(UINT32 target)
}
return;
}
//OsMpWakeHandler多处理器唤醒处理函数目前为空实现无特定操作
VOID OsMpWakeHandler(VOID)
{
/* generic wakeup ipi, do nothing */
}
//OsMpScheduleHandler多处理器调度处理函数设置调度标志以触发调度器在中断结束时执行调度
VOID OsMpScheduleHandler(VOID)
{
/*
@ -71,7 +72,7 @@ VOID OsMpScheduleHandler(VOID)
*/
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
}
//OsMpHaltHandler多处理器停机处理函数将当前处理器标记为已停机状态并进入死循环
VOID OsMpHaltHandler(VOID)
{
(VOID)LOS_IntLock();
@ -79,7 +80,7 @@ VOID OsMpHaltHandler(VOID)
while (1) {}
}
//OsMpCollectTasks多处理器任务回收函数用于递归检查所有可用任务并删除标记为需要销毁的任务
VOID OsMpCollectTasks(VOID)
{
LosTaskCB *taskCB = NULL;
@ -109,6 +110,7 @@ VOID OsMpCollectTasks(VOID)
}
#ifdef LOSCFG_KERNEL_SMP_CALL
//OsMpFuncCall多处理器函数调用函数用于向指定的处理器发送函数调用请求
VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
{
UINT32 index;
@ -144,7 +146,7 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
}
return;
}
//OsMpFuncCallHandler多处理器函数调用处理函数从本处理器的函数调用队列中取出并执行函数调用请求
VOID OsMpFuncCallHandler(VOID)
{
UINT32 intSave;
@ -166,7 +168,7 @@ VOID OsMpFuncCallHandler(VOID)
}
MP_CALL_UNLOCK(intSave);
}
//OsMpFuncCallInit多处理器函数调用初始化函数用于初始化每个核心的函数调用队列
VOID OsMpFuncCallInit(VOID)
{
UINT32 index;
@ -176,7 +178,7 @@ VOID OsMpFuncCallInit(VOID)
}
}
#endif /* LOSCFG_KERNEL_SMP_CALL */
//OsMpInit多处理器初始化函数包括创建周期性软件定时器和初始化函数调用队列等
UINT32 OsMpInit(VOID)
{
UINT16 swtmrId;

@ -25,7 +25,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*代码实现了一个简单的互斥锁Mutex用于保护共享资源的访问
线访访*/
#include "los_mux_pri.h"
#include "los_mux_debug_pri.h"
#include "los_bitmap.h"
@ -49,6 +50,7 @@ LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedMuxList;
* Description : Initializes the mutex
* Return : LOS_OK on success, or error code on failure
*/
//OsMuxInitMutex初始化函数用于初始化Mutex数据结构并设置初始状态
LITE_OS_SEC_TEXT UINT32 OsMuxInit(VOID)
{
LosMuxCB *muxNode = NULL;
@ -74,7 +76,7 @@ LITE_OS_SEC_TEXT UINT32 OsMuxInit(VOID)
}
return LOS_OK;
}
//LOS_MuxCreate创建Mutex函数用于创建一个新的Mutex对象并返回其句柄
LITE_OS_SEC_TEXT UINT32 LOS_MuxCreate(UINT32 *muxHandle)
{
UINT32 intSave;
@ -113,7 +115,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxCreate(UINT32 *muxHandle)
ERR_HANDLER:
OS_RETURN_ERROR_P2(errLine, errNo);
}
//LOS_MuxDelete删除Mutex函数用于删除指定的Mutex对象及其相关资源
LITE_OS_SEC_TEXT UINT32 LOS_MuxDelete(UINT32 muxHandle)
{
UINT32 intSave;
@ -154,7 +156,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxDelete(UINT32 muxHandle)
ERR_HANDLER:
OS_RETURN_ERROR_P2(errLine, errNo);
}
//OsMuxParaCheck 函数主要用于验证互斥量操作的参数是否有效,包括互斥量是否被正确创建和传入的句柄是否有效,以及当前是否处于中断上下文
LITE_OS_SEC_TEXT STATIC UINT32 OsMuxParaCheck(const LosMuxCB *muxCB, UINT32 muxHandle)
{
if ((muxCB->muxStat == LOS_UNUSED) || (muxCB->muxId != muxHandle)) {
@ -168,7 +170,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsMuxParaCheck(const LosMuxCB *muxCB, UINT32 muxH
}
return LOS_OK;
}
//OsMuxBitmapSet 函数用于在互斥量等待队列中设置任务的优先级位图,并根据需要调整任务的优先级,以确保任务在等待互斥量时能够正确反映其优先级关系
LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapSet(const LosTaskCB *runTask, const MuxBaseCB *muxPended)
{
if (muxPended->owner->priority > runTask->priority) {
@ -176,7 +178,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapSet(const LosTaskCB *runTask, const MuxB
OsTaskPriModify(muxPended->owner, runTask->priority);
}
}
//OsMuxBitmapRestore 函数用于恢复任务的优先级位图,并根据需要更新拥有者任务的优先级
LITE_OS_SEC_TEXT STATIC VOID OsMuxBitmapRestore(const LosTaskCB *runTask, LosTaskCB *owner)
{
UINT16 bitMapPri;
@ -244,7 +246,8 @@ LITE_OS_SEC_TEXT STATIC LOS_DL_LIST *OsMuxPendFindPos(const LosTaskCB *runTask,
return node;
}
#endif
//总体来说OsMuxPostOp 函数用于处理 Mutex 的释放操作,包括唤醒等待任务、更新 Mutex 状态和持有者等
//确保 Mutex 能够按照预期的方式被正确释放和传递给下一个任务
LITE_OS_SEC_TEXT UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UINT32 timeout,
UINT32 *intSave)
{
@ -270,7 +273,7 @@ LITE_OS_SEC_TEXT UINT32 OsMuxPendOp(LosTaskCB *runTask, MuxBaseCB *muxPended, UI
return ret;
}
//LOS_MuxPend等待Mutex函数用于尝试获取指定Mutex的访问权限。如果Mutex已被其他任务持有则当前任务会被挂起直到Mutex可用
LITE_OS_SEC_TEXT UINT32 LOS_MuxPend(UINT32 muxHandle, UINT32 timeout)
{
UINT32 ret;
@ -332,7 +335,7 @@ OUT_UNLOCK:
}
return ret;
}
//OsMuxPostOpSub:通过比较当前任务和 Mutex 等待队列中的任务的优先级,来调整当前任务的优先级位图,并将 Mutex 持有者的优先级提升
LITE_OS_SEC_TEXT STATIC VOID OsMuxPostOpSub(LosTaskCB *runTask, MuxBaseCB *muxPosted)
{
LosTaskCB *pendedTask = NULL;
@ -350,7 +353,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsMuxPostOpSub(LosTaskCB *runTask, MuxBaseCB *muxPo
LOS_BitmapClr(&runTask->priBitMap, bitMapPri);
OsTaskPriModify(muxPosted->owner, bitMapPri);
}
//
LITE_OS_SEC_TEXT UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted)
{
LosTaskCB *resumedTask = NULL;
@ -386,7 +389,7 @@ LITE_OS_SEC_TEXT UINT32 OsMuxPostOp(LosTaskCB *runTask, MuxBaseCB *muxPosted)
return MUX_SCHEDULE;
}
//LOS_MuxPost释放Mutex函数用于释放当前任务对指定Mutex的访问权限以便其他任务可以获取该Mutex
LITE_OS_SEC_TEXT UINT32 LOS_MuxPost(UINT32 muxHandle)
{
UINT32 ret;

@ -33,7 +33,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//定义全局变量数组用于存储每个CPU核心的私有数据
Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
#ifdef __cplusplus

@ -32,7 +32,7 @@
* It should not add OS inner invocation, which is not allowed to be accessed in user space.
* But it's allowed to invoke syscall interface.
*---------------------------------------------------------------------------- */
/*这段代码是一个输出控制模块,根据不同的输出类型将字符串输出到不同的设备上*/
#ifdef LOSCFG_LIB_LIBC
#include "unistd.h"
#endif
@ -62,13 +62,13 @@ typedef enum {
CONSOLE_OUTPUT = 2,
EXC_OUTPUT = 3
} OutputType;
//ErrorMsg用于输出错误信息当字符串输出非法或者vsnprintf_s函数失败时调用
STATIC VOID ErrorMsg(VOID)
{
const CHAR *p = "Output illegal string! vsnprintf_s failed!\n";
UartPuts(p, (UINT32)strlen(p), UART_WITH_LOCK);
}
//UartOutput实际将字符串输出到串口的函数根据配置可能会进行一些额外的处理
STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock)
{
#ifdef LOSCFG_SHELL_DMESG
@ -82,7 +82,7 @@ STATIC VOID UartOutput(const CHAR *str, UINT32 len, BOOL isLock)
UartPuts(str, len, isLock);
#endif
}
//OutputControl根据输出类型选择相应的输出设备并调用对应的输出函数
STATIC VOID OutputControl(const CHAR *str, UINT32 len, OutputType type)
{
switch (type) {
@ -105,14 +105,14 @@ STATIC VOID OutputControl(const CHAR *str, UINT32 len, OutputType type)
}
return;
}
//OsVprintfFree释放动态分配的缓冲区内存
STATIC VOID OsVprintfFree(CHAR *buf, UINT32 bufLen)
{
if (bufLen != SIZEBUF) {
(VOID)LOS_MemFree(m_aucSysMem0, buf);
}
}
//OsVprintf核心函数根据给定的格式化字符串和可变参数进行字符串格式化并输出到相应的设备
STATIC VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
{
INT32 len;
@ -156,7 +156,7 @@ STATIC VOID OsVprintf(const CHAR *fmt, va_list ap, OutputType type)
OutputControl(bBuf, len, type);
OsVprintfFree(bBuf, bufLen);
}
//UartVprintf、ConsoleVprintf、UartPrintf、dprintf、LkDprintf、DmesgPrintf、ExcPrintf、PrintExcInfo这些函数都是对OsVprintf的封装提供了不同的输出接口在不同的场景下调用OsVprintf来完成字符串的格式化和输出
VOID UartVprintf(const CHAR *fmt, va_list ap)
{
OsVprintf(fmt, ap, UART_OUTPUT);

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//实现了一个基于轻量级操作系统的队列管理模块,提供了队列的创建、读写、删除以及信息获取等功能
#include "los_queue_pri.h"
#include "los_queue_debug_pri.h"
#include "los_task_pri.h"
@ -53,6 +53,7 @@ LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;
* Description : queue initial
* Return : LOS_OK on success or error code on failure
*/
//初始化队列,返回成功或失败错误码
LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
{
LosQueueCB *queueNode = NULL;
@ -78,7 +79,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
}
return LOS_OK;
}
//OsQueueCreateParameterCheck函数用于检查创建队列时传入的参数是否合法
STATIC INLINE UINT32 OsQueueCreateParameterCheck(UINT16 len, const UINT32 *queueId, UINT16 maxMsgSize)
{
if (queueId == NULL) {
@ -94,7 +95,7 @@ STATIC INLINE UINT32 OsQueueCreateParameterCheck(UINT16 len, const UINT32 *queue
}
return LOS_OK;
}
//OsQueueCreateInternal函数用于创建队列包括在队列控制块中记录队列长度、消息大小等信息
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsQueueCreateInternal(UINT16 len, UINT32 *queueId, UINT16 msgSize,
UINT8 *queue, UINT8 queueMemType)
{
@ -165,7 +166,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreateStatic(const CHAR *queueName,
return OsQueueCreateInternal(len, queueId, msgSize, queueMem, OS_QUEUE_ALLOC_STATIC);
}
#endif
//创建队列
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(const CHAR *queueName, UINT16 len, UINT32 *queueId,
UINT32 flags, UINT16 maxMsgSize)
{
@ -198,7 +199,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(const CHAR *queueName, UINT16 len,
return LOS_OK;
}
//OsQueueReadParameterCheck和OsQueueWriteParameterCheck分别用于检查读和写操作的参数合法性
LITE_OS_SEC_TEXT STATIC UINT32 OsQueueReadParameterCheck(UINT32 queueId, const VOID *bufferAddr,
const UINT32 *bufferSize, UINT32 timeout)
{
@ -248,7 +249,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsQueueWriteParameterCheck(UINT32 queueId, const
}
return LOS_OK;
}
//实现了队列的读取和写入操作,并对可能出现的错误进行了处理
STATIC UINT32 OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize)
{
UINT8 *queueNode = NULL;
@ -296,7 +297,7 @@ STATIC UINT32 OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID
}
return LOS_OK;
}
//用于处理队列操作函数 OsQueueBufferOperate 返回的错误码,使得在发生错误时能够打印相应的错误信息
STATIC VOID OsQueueBufferOperateErrProcess(UINT32 errorCode)
{
switch (errorCode) {
@ -336,7 +337,7 @@ STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueId
}
return LOS_OK;
}
//OsQueueOperate:实现了对队列的操作,包括参数检查、任务挂起与唤醒以及错误处理等功能
STATIC UINT32 OsQueueOperate(UINT32 queueId, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout)
{
LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueId);
@ -400,7 +401,7 @@ QUEUE_END:
OsQueueBufferOperateErrProcess(errorCode);
return ret;
}
//LOS_QueueReadCopy从队列中读取数据通过参数检查后调用OsQueueOperate函数进行实际的读取操作
LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueId,
VOID *bufferAddr,
UINT32 *bufferSize,
@ -417,7 +418,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueId,
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);
return OsQueueOperate(queueId, operateType, bufferAddr, bufferSize, timeout);
}
//LOS_QueueWriteHeadCopy向队列的头部写入数据通过参数检查后调用OsQueueOperate函数进行实际的写入操作
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueId,
VOID *bufferAddr,
UINT32 bufferSize,
@ -434,7 +435,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueId,
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);
return OsQueueOperate(queueId, operateType, bufferAddr, &bufferSize, timeout);
}
//LOS_QueueWriteCopy向队列的尾部写入数据通过参数检查后调用OsQueueOperate函数进行实际的写入操作
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueId,
VOID *bufferAddr,
UINT32 bufferSize,
@ -451,12 +452,12 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueId,
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);
return OsQueueOperate(queueId, operateType, bufferAddr, &bufferSize, timeout);
}
//LOS_QueueRead从队列中读取数据的简化接口直接调用LOS_QueueReadCopy函数
LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
{
return LOS_QueueReadCopy(queueId, bufferAddr, &bufferSize, timeout);
}
//LOS_QueueWrite向队列中写入数据的简化接口先进行参数检查然后调用LOS_QueueWriteCopy函数
LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueId, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
{
if (bufferAddr == NULL) {
@ -465,7 +466,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueId, VOID *bufferAddr, UINT32
bufferSize = sizeof(CHAR *);
return LOS_QueueWriteCopy(queueId, &bufferAddr, bufferSize, timeout);
}
//LOS_QueueWriteHead向队列头部写入数据的简化接口先进行参数检查然后调用LOS_QueueWriteHeadCopy函数
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueId,
VOID *bufferAddr,
UINT32 bufferSize,
@ -477,7 +478,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueId,
bufferSize = sizeof(CHAR *);
return LOS_QueueWriteHeadCopy(queueId, &bufferAddr, bufferSize, timeout);
}
//LOS_QueueDelete删除队列的函数
//首先检查队列是否存在,如果存在则检查是否有任务正在使用队列或者队列中还有未释放的内存块,如果满足条件则释放队列所占用的资源
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueId)
{
LosQueueCB *queueCB = NULL;
@ -537,7 +539,7 @@ QUEUE_END:
SCHEDULER_UNLOCK(intSave);
return ret;
}
//LOS_QueueInfoGet:获取指定队列的相关信息包括队列ID、队列长度、队列大小、队列头尾指针、等待读取和写入的任务数等
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueId, QUEUE_INFO_S *queueInfo)
{
UINT32 intSave;
@ -595,6 +597,9 @@ QUEUE_END:
* : timeout --- Expiry time. The value range is [0,LOS_WAIT_FOREVER]
* Return : pointer if success otherwise NULL
*/
//OsQueueMailAlloc函数用来从邮件池中分配一个邮件内存块
//如果没有可用的内存块,则根据超时时间挂起当前任务,并将其加入到等待内存块的任务链表中
//当有内存块可用时,会将任务从任务链表中移除,并返回分配的内存块指针
LITE_OS_SEC_TEXT VOID *OsQueueMailAlloc(UINT32 queueId, VOID *mailPool, UINT32 timeout)
{
VOID *mem = NULL;
@ -663,6 +668,8 @@ END:
* : mailMem --- The mail memory block address
* Return : LOS_OK on success or error code on failure
*/
//OsQueueMailFree函数用来释放指定的邮件内存块并将其加入到邮件池的空闲链表中
//如果有任务在等待内存块,则会从任务链表中唤醒一个任务,并将其从任务链表中移除
LITE_OS_SEC_TEXT UINT32 OsQueueMailFree(UINT32 queueId, VOID *mailPool, VOID *mailMem)
{
VOID *mem = NULL;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*实现环形缓冲区。环形缓冲区是一种循环使用固定大小存储空间的数据结构,常用于解决生产者-消费者问题*/
#include "los_ringbuf.h"
#ifdef __cplusplus
@ -33,7 +33,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//LOS_RingbufUsedSize获取环形缓冲区已使用的大小
UINT32 LOS_RingbufUsedSize(Ringbuf *ringbuf)
{
UINT32 size;
@ -56,6 +56,7 @@ UINT32 LOS_RingbufUsedSize(Ringbuf *ringbuf)
* |
* endIdx
*/
//OsRingbufWriteLinear线性写入数据到环形缓冲区
STATIC UINT32 OsRingbufWriteLinear(Ringbuf *ringbuf, const CHAR *buf, UINT32 size)
{
UINT32 cpSize;
@ -77,7 +78,7 @@ STATIC UINT32 OsRingbufWriteLinear(Ringbuf *ringbuf, const CHAR *buf, UINT32 siz
return cpSize;
}
//OsRingbufWriteLoop循环写入数据到环形缓冲区
STATIC UINT32 OsRingbufWriteLoop(Ringbuf *ringbuf, const CHAR *buf, UINT32 size)
{
UINT32 right, cpSize;
@ -105,7 +106,7 @@ STATIC UINT32 OsRingbufWriteLoop(Ringbuf *ringbuf, const CHAR *buf, UINT32 size)
return cpSize;
}
//LOS_RingbufWrite向环形缓冲区写入数据
UINT32 LOS_RingbufWrite(Ringbuf *ringbuf, const CHAR *buf, UINT32 size)
{
UINT32 cpSize = 0;
@ -130,7 +131,7 @@ EXIT:
LOS_SpinUnlockRestore(&ringbuf->lock, intSave);
return cpSize;
}
//OsRingbufReadLinear线性读取环形缓冲区中的数据
STATIC UINT32 OsRingbufReadLinear(Ringbuf *ringbuf, CHAR *buf, UINT32 size)
{
UINT32 cpSize, remain;
@ -153,7 +154,7 @@ STATIC UINT32 OsRingbufReadLinear(Ringbuf *ringbuf, CHAR *buf, UINT32 size)
return cpSize;
}
//OsRingbufReadLoop循环读取环形缓冲区中的数据
STATIC UINT32 OsRingbufReadLoop(Ringbuf *ringbuf, CHAR *buf, UINT32 size)
{
UINT32 right, cpSize;
@ -179,7 +180,7 @@ STATIC UINT32 OsRingbufReadLoop(Ringbuf *ringbuf, CHAR *buf, UINT32 size)
return cpSize;
}
//LOS_RingbufRead从环形缓冲区读取数据
UINT32 LOS_RingbufRead(Ringbuf *ringbuf, CHAR *buf, UINT32 size)
{
UINT32 cpSize;
@ -205,7 +206,7 @@ EXIT:
LOS_SpinUnlockRestore(&ringbuf->lock, intSave);
return cpSize;
}
//LOS_RingbufInit初始化环形缓冲区
UINT32 LOS_RingbufInit(Ringbuf *ringbuf, CHAR *fifo, UINT32 size)
{
if ((ringbuf == NULL) || (fifo == NULL) ||
@ -221,7 +222,7 @@ UINT32 LOS_RingbufInit(Ringbuf *ringbuf, CHAR *fifo, UINT32 size)
ringbuf->status = RBUF_INITED;
return LOS_OK;
}
//LOS_RingbufReset重置环形缓冲区
VOID LOS_RingbufReset(Ringbuf *ringbuf)
{
UINT32 intSave;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*实现信号量的操作系统内核代码主要包括信号量的创建、删除、等待Pend和释放Post等操作*/
#include "los_sem_pri.h"
#include "los_sem_debug_pri.h"
#include "los_err_pri.h"
@ -49,7 +49,7 @@ STATIC_INLINE VOID OsSemNodeRecycle(LosSemCB *semNode)
semNode->semStat = LOS_UNUSED;
LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);
}
//OsSemInit()函数:用于初始化信号量管理模块,包括申请创建信号量所需要的内存空间、将信号量结构体加入到未使用链表中等
LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
{
LosSemCB *semNode = NULL;
@ -74,7 +74,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
}
return LOS_OK;
}
//OsSemCreate函数:用于创建一个信号量,并将其加入到已使用信号量列表中
//参数count表示信号量的初始值type表示信号量的类型计数信号量或二进制信号量semHandle用于返回创建的信号量的句柄
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsSemCreate(UINT16 count, UINT8 type, UINT32 *semHandle)
{
UINT32 intSave;
@ -109,7 +110,7 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsSemCreate(UINT16 count, UINT8 type, UINT32
LOS_TRACE(SEM_CREATE, semCreated->semId, type, count);
return LOS_OK;
}
//LOS_SemCreate:对外部提供的接口函数,用于创建一个计数信号量
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
{
if (count > LOS_SEM_COUNT_MAX) {
@ -117,7 +118,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
}
return OsSemCreate(count, OS_SEM_COUNTING, semHandle);
}
//LOS_BinarySemCreate:对外部提供的接口函数,用于创建一个二进制信号量
LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle)
{
if (count > OS_SEM_BINARY_COUNT_MAX) {
@ -125,7 +126,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle
}
return OsSemCreate(count, OS_SEM_BINARY, semHandle);
}
//OsSemStateVerify:用于验证信号量的状态是否有效
//参数semId表示要验证的信号量的IDsemNode是指向信号量控制块的指针
STATIC_INLINE UINT32 OsSemStateVerify(UINT32 semId, const LosSemCB *semNode)
{
#ifndef LOSCFG_RESOURCE_ID_NOT_USE_HIGH_BITS
@ -137,7 +139,8 @@ STATIC_INLINE UINT32 OsSemStateVerify(UINT32 semId, const LosSemCB *semNode)
}
return LOS_OK;
}
//OsSemGetCBWithCheck:用于根据信号量句柄获取信号量的控制块
//参数semHandle表示信号量的句柄semCB是一个指向指针的指针用于返回获取到的信号量控制块
STATIC UINT32 OsSemGetCBWithCheck(UINT32 semHandle, LosSemCB **semCB)
{
if (GET_SEM_INDEX(semHandle) >= (UINT32)KERNEL_SEM_LIMIT) {
@ -147,7 +150,7 @@ STATIC UINT32 OsSemGetCBWithCheck(UINT32 semHandle, LosSemCB **semCB)
*semCB = GET_SEM(semHandle);
return LOS_OK;
}
//LOS_SemDelete:用于删除指定句柄的信号量,如果有任务正在等待该信号量,则删除失败
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
{
UINT32 intSave;
@ -184,7 +187,7 @@ OUT:
LOS_TRACE(SEM_DELETE, semHandle, ret);
return ret;
}
//LOS_SemPend:用于等待Pend一个信号量如果信号量不可用则阻塞当前任务直到信号量可用或超时。timeout表示超时时间
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
{
UINT32 intSave;
@ -252,7 +255,7 @@ OUT:
SCHEDULER_UNLOCK(intSave);
return ret;
}
//LOS_SemPost:用于释放Post一个信号量使其变为可用状态并唤醒等待该信号量的任务中的第一个任务
LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
{
UINT32 intSave;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*嵌入式操作系统中与任务调度相关的排序链表管理代码。包括了对排序链表的初始化、向排序链表中添加节点、从排序链表中删除节点、获取下一个超时时间等操作*/
#include "los_sortlink_pri.h"
#include "los_memory.h"
#include "los_exc.h"
@ -39,7 +39,7 @@ extern "C" {
#define OS_INVALID_VALUE 0xFFFFFFFF
#ifdef LOSCFG_BASE_CORE_USE_MULTI_LIST
//OsSortLinkInit初始化排序链表为排序链表的头节点分配内存并进行初始化
LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{
UINT32 size;
@ -60,7 +60,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
}
return LOS_OK;
}
//OsAdd2SortLink将一个节点添加到排序链表中根据节点的超时时间计算节点在排序链表中的位置然后插入到相应位置
LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
SortLinkList *listSorted = NULL;
@ -106,7 +106,7 @@ LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, So
LOS_ListTailInsert(&listSorted->sortLinkNode, &sortList->sortLinkNode);
}
}
//OsCheckSortLink检查排序链表是否合法排除循环引用和无效节点
LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const LOS_DL_LIST *listNode)
{
LOS_DL_LIST *tmp = listNode->pstPrev;
@ -122,7 +122,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const
/* delete invalid sortlink node */
OsBackTrace();
}
//OsDeleteSortLink从排序链表中删除一个节点然后更新相邻节点的超时时间
LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
LOS_DL_LIST *listObject = NULL;
@ -141,7 +141,7 @@ LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader,
}
LOS_ListDelete(&sortList->sortLinkNode);
}
//OsCalcExpierTime根据当前的排序链表游标和节点的位置计算超时时间
LITE_OS_SEC_TEXT STATIC INLINE UINT32 OsCalcExpierTime(UINT32 rollNum, UINT32 sortIndex, UINT16 curSortIndex)
{
UINT32 expireTime;
@ -154,7 +154,7 @@ LITE_OS_SEC_TEXT STATIC INLINE UINT32 OsCalcExpierTime(UINT32 rollNum, UINT32 so
expireTime = ((rollNum - 1) << OS_TSK_SORTLINK_LOGLEN) + sortIndex;
return expireTime;
}
//OsSortLinkGetNextExpireTime获取排序链表中下一个超时时间最小的节点的超时时间
LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader)
{
UINT16 cursor;
@ -184,7 +184,7 @@ LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sor
return expireTime;
}
//OsSortLinkUpdateExpireTime更新排序链表中所有节点的超时时间并更新游标
LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader)
{
SortLinkList *sortList = NULL;
@ -215,7 +215,7 @@ LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttr
}
sortLinkHeader->cursor = (sortLinkHeader->cursor + sleepTicks - 1) % OS_TSK_SORTLINK_LEN;
}
//OsSortLinkGetTargetExpireTime获取目标节点的超时时间
LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader,
const SortLinkList *targetSortList)
{
@ -235,7 +235,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttrib
}
#else /* LOSCFG_BASE_CORE_USE_SINGLE_LIST */
//OsSortLinkInit:初始化排序链表头部
LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{
UINT32 size;
@ -252,7 +252,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
LOS_ListInit(listObject);
return LOS_OK;
}
//OsAdd2SortLink:向排序链表中添加元素
LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
SortLinkList *listSorted = NULL;
@ -286,7 +286,7 @@ LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, So
LOS_ListTailInsert(&listSorted->sortLinkNode, &sortList->sortLinkNode);
}
}
//OsCheckSortLink:检查排序链表的有效性,用于内部调用
LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const LOS_DL_LIST *listNode)
{
LOS_DL_LIST *tmp = listNode->pstPrev;
@ -302,7 +302,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const
/* delete invalid sortlink node */
OsBackTrace();
}
//OsDeleteSortLink:从排序链表中删除指定元素
LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
LOS_DL_LIST *listObject = NULL;
@ -319,7 +319,7 @@ LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader,
}
LOS_ListDelete(&sortList->sortLinkNode);
}
//OsSortLinkGetNextExpireTime:获取排序链表中下一个到期的时间
LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader)
{
UINT32 expireTime = OS_INVALID_VALUE;
@ -333,7 +333,7 @@ LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sor
}
return expireTime;
}
//OsSortLinkUpdateExpireTime:更新排序链表中到期时间
LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader)
{
SortLinkList *sortList = NULL;
@ -349,7 +349,7 @@ LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttr
ROLLNUM_SUB(sortList->idxRollNum, sleepTicks - 1);
}
}
//OsSortLinkGetTargetExpireTime:获取指定排序链表元素的到期时间
LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader,
const SortLinkList *targetSortList)
{

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//栈
#include "securec.h"
#include "los_stackinfo_pri.h"
#ifdef LOSCFG_SHELL
@ -35,7 +35,7 @@
const StackInfo *g_stackInfo = NULL;
UINT32 g_stackNum;
//OsStackWaterLineGet:获取栈的使用情况
UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed)
{
UINT32 size;
@ -53,20 +53,20 @@ UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop,
return LOS_NOK;
}
}
//OsExcStackInfoReg:注册异常栈信息
VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum)
{
g_stackInfo = stackInfo;
g_stackNum = stackNum;
}
//OsStackInit:初始化任务栈
VOID OsStackInit(VOID *stacktop, UINT32 stacksize)
{
/* initialize the task stack, write magic num to stack top */
(VOID)memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize);
*((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD;
}
//OsGetStackInfo:获取栈信息
VOID OsGetStackInfo(const StackInfo **stackInfo, UINT32 *stackNum)
{
*stackInfo = g_stackInfo;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*软件定时器的实现,涉及软件定时器的创建、启动、停止、删除等操作*/
#include "los_swtmr_pri.h"
#include "los_sortlink_pri.h"
#include "los_queue_pri.h"
@ -52,6 +52,7 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);
* Description: Start Software Timer
* Input : swtmr --- Need to start software timer
*/
//OsSwtmrStart启动软件定时器
LITE_OS_SEC_TEXT VOID OsSwtmrStart(LosSwtmrCB *swtmr)
{
if ((swtmr->overrun == 0) && ((swtmr->mode == LOS_SWTMR_MODE_ONCE) ||
@ -75,13 +76,14 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(LosSwtmrCB *swtmr)
* Description: Delete Software Timer
* Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL.
*/
//OsSwtmrDelete删除软件定时器
STATIC INLINE VOID OsSwtmrDelete(LosSwtmrCB *swtmr)
{
/* insert to free list */
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->sortList.sortLinkNode);
swtmr->state = OS_SWTMR_STATUS_UNUSED;
}
//OsSwtmrUpdate更新软件定时器
STATIC INLINE VOID OsSwtmrUpdate(LosSwtmrCB *swtmr)
{
if (swtmr->mode == LOS_SWTMR_MODE_ONCE) {
@ -101,6 +103,7 @@ STATIC INLINE VOID OsSwtmrUpdate(LosSwtmrCB *swtmr)
}
#ifndef LOSCFG_BASE_CORE_SWTMR_IN_ISR
//OsSwtmrTask软件定时器任务处理函数用于处理定时器超时事件
LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID)
{
UINT32 ret, swtmrHandlerQueue;
@ -136,7 +139,7 @@ BOOL IsSwtmrTask(UINT32 taskId)
return FALSE;
}
#endif
//OsSwtmrTaskCreate创建软件定时器任务
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
{
UINT32 ret, swtmrTaskId;
@ -161,7 +164,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
return ret;
}
#endif
//OsSwtmrInit软件定时器初始化
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
{
UINT32 size;
@ -209,6 +212,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
* Description: Tick interrupt interface module of software timer
* Return : LOS_OK on success or error code on failure
*/
//OsSwtmrScan扫描软件定时器
LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)
{
SortLinkList *sortList = NULL;
@ -277,6 +281,7 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)
* Description: Get next timeout
* Return : Count of the Timer list
*/
//OsSwtmrGetNextTimeout获取下一个超时时间
LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
{
return OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink);
@ -286,6 +291,7 @@ LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
* Description: Stop of Software Timer interface
* Input : swtmr --- the software timer control handler
*/
//OsSwtmrStop停止软件定时器
LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(LosSwtmrCB *swtmr)
{
SortLinkAttribute *sortLinkHeader = NULL;
@ -309,6 +315,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(LosSwtmrCB *swtmr)
* Description: Get next software timer expiretime
* Input : swtmr --- the software timer control handler
*/
//获取指定软件定时器的剩余时间
LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const LosSwtmrCB *swtmr)
{
SortLinkAttribute *sortLinkHeader = NULL;
@ -325,7 +332,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const LosSwtmrCB *swtmr)
return OsSortLinkGetTargetExpireTime(sortLinkHeader, &swtmr->sortList);
}
//创建一个软件定时器
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode,
SWTMR_PROC_FUNC handler,
@ -377,7 +384,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
return LOS_OK;
}
//启动一个软件定时器
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrId)
{
LosSwtmrCB *swtmr = NULL;
@ -421,7 +428,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrId)
LOS_TRACE(SWTMR_START, swtmr->timerId, swtmr->mode, swtmr->overrun, swtmr->interval, swtmr->expiry);
return ret;
}
//停止一个软件定时器
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId)
{
LosSwtmrCB *swtmr = NULL;
@ -461,7 +468,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrId)
LOS_TRACE(SWTMR_STOP, swtmr->timerId);
return ret;
}
//获取一个软件定时器的剩余时间
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrId, UINT32 *tick)
{
LosSwtmrCB *swtmr = NULL;
@ -502,7 +509,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrId, UINT32 *tick)
SWTMR_UNLOCK(intSave);
return ret;
}
//删除一个软件定时器
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrId)
{
LosSwtmrCB *swtmr = NULL;

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*关于LiteOS中任务管理模块的部分实现包括任务控制块的初始化、任务创建、任务删除等功能*/
#include "los_task_pri.h"
#include "los_priqueue_pri.h"
#include "los_sem_pri.h"
@ -282,7 +282,7 @@ LITE_OS_SEC_TEXT VOID OsTaskScan(VOID)
LOS_Schedule();
}
}
//OsTaskInit用于初始化任务管理模块包括任务控制块数组、空闲任务列表、任务回收列表等数据结构的初始化
LITE_OS_SEC_TEXT_INIT UINT32 OsTaskInit(VOID)
{
UINT32 index;
@ -335,7 +335,7 @@ UINT32 OsGetIdleTaskId(VOID)
Percpu *perCpu = OsPercpuGet();
return perCpu->idleTaskId;
}
//创建空闲任务Idle Task
LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
{
UINT32 ret;
@ -363,6 +363,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID)
* Description : get id of current running task.
* Return : task id
*/
//读取任务ID
LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
{
LosTaskCB *runTask = OsCurrTaskGet();
@ -372,7 +373,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)
}
return runTask->taskId;
}
//获取当前正在运行的任务的任务名称
LITE_OS_SEC_TEXT CHAR *OsCurTaskNameGet(VOID)
{
LosTaskCB *runTask = OsCurrTaskGet();
@ -428,12 +429,12 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_LowpowerHookReg(LOWPOWERIDLEHOOK hook)
g_lowPowerHook = hook;
}
#endif
//注册空闲任务钩子函数,即在系统空闲时执行的函数
LITE_OS_SEC_TEXT_MINOR VOID LOS_IdleHandlerHookReg(IDLEHANDLERHOOK hook)
{
g_idleHandlerHook = hook;
}
//检查任务是否分离detached
STATIC BOOL OsTaskDeleteCheckDetached(const LosTaskCB *taskCB)
{
#if LOSCFG_COMPAT_POSIX
@ -442,7 +443,7 @@ STATIC BOOL OsTaskDeleteCheckDetached(const LosTaskCB *taskCB)
return TRUE;
#endif
}
//删除已分离的任务
STATIC VOID OsTaskDeleteDetached(const LosTaskCB *taskCB)
{
UINT32 intSave;
@ -451,7 +452,7 @@ STATIC VOID OsTaskDeleteDetached(const LosTaskCB *taskCB)
LOS_IntRestore(intSave);
(VOID)LOS_TaskDelete(taskCB->taskId);
}
//删除已加入的任务
STATIC VOID OsTaskDeleteJoined(LosTaskCB *taskCB, VOID *ret)
{
#ifdef LOSCFG_COMPAT_POSIX
@ -481,6 +482,8 @@ STATIC VOID OsTaskDeleteJoined(LosTaskCB *taskCB, VOID *ret)
* Description : All task entry
* Input : taskId --- The ID of the task to be run
*/
//执行任务的实际代码,并根据任务的属性判断是否需要删除任务
//如果任务是分离的,则直接删除任务;如果任务是加入的,则将任务加入的其他任务唤醒,并重新调度任务
LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskId)
{
LosTaskCB *taskCB = NULL;
@ -511,7 +514,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskId)
OsTaskDeleteJoined(taskCB, ret);
}
}
//对任务初始化参数进行检查,确保任务参数的合法性
STATIC UINT32 OsTaskInitParamCheck(const TSK_INIT_PARAM_S *initParam)
{
if (initParam == NULL) {
@ -566,7 +569,7 @@ STATIC UINT32 OsTaskCreateParamCheckStatic(const UINT32 *taskId,
return LOS_OK;
}
#endif
//对任务创建参数进行检查,确保参数的合法性。如果参数不合法,则返回相应的错误码;否则返回成功
LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCreateParamCheck(const UINT32 *taskId,
TSK_INIT_PARAM_S *initParam, VOID **pool)
{
@ -776,6 +779,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskDelAction(LosTaskCB *taskCB, BOOL useUsr
* 3. Do the deletion in hard-irq
* then LOS_TaskDelete will directly return with 'ret' value.
*/
//OsTaskDeleteCheckOnRun函数用来检查是否需要在任务运行时进行删除操作
LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskDeleteCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
{
/* init default out return value */
@ -813,7 +817,7 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskDeleteCheckOnRun(LosTaskCB *taskCB, UINT
return TRUE;
}
//OsTaskCBInit函数用于初始化任务控制块设置任务的各种属性和状态
LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam,
VOID *stackPtr, const VOID *topStack, BOOL useUsrStack)
{
@ -869,7 +873,7 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT
(VOID)memset_s(&taskCB->schedStat, sizeof(SchedStat), 0, sizeof(SchedStat));
#endif
}
//OsTaskGetFreeTaskCB函数用于获取一个空闲的任务控制块
STATIC UINT32 OsTaskGetFreeTaskCB(LosTaskCB **taskCB)
{
if (LOS_ListEmpty(&g_losFreeTask)) {
@ -883,7 +887,7 @@ STATIC UINT32 OsTaskGetFreeTaskCB(LosTaskCB **taskCB)
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_losFreeTask));
return LOS_OK;
}
//OsTaskCreateOnly函数用于创建一个新的任务其中会对参数进行合法性检查
STATIC UINT32 OsTaskCreateOnly(UINT32 *taskId, TSK_INIT_PARAM_S *initParam, VOID *topStack, BOOL useUsrStack)
{
UINT32 intSave, errRet;
@ -947,7 +951,7 @@ LOS_ERREND:
SCHEDULER_UNLOCK(intSave);
return errRet;
}
//OsTaskResume函数用于恢复一个被挂起的任务
STATIC VOID OsTaskResume(const UINT32 *taskId)
{
UINT32 intSave;
@ -998,7 +1002,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreateOnly(UINT32 *taskId, TSK_INIT_PARAM_S
{
return OsTaskCreateOnly(taskId, initParam, NULL, FALSE);
}
//LOS_TaskCreate该函数用于创建一个新的任务包括任务的名称、优先级、栈大小等参数的设置
//在创建任务时,需要进行一些参数的合法性检查,例如是否超出最大任务数量、是否有足够的堆栈空间等
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskId, TSK_INIT_PARAM_S *initParam)
{
UINT32 ret;
@ -1012,7 +1017,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskId, TSK_INIT_PARAM_S *in
return LOS_OK;
}
//LOS_TaskDelete用于删除一个已经存在的任务
//在删除任务时,需要对任务的状态进行判断。如果任务正在运行,则将其标记为删除状态并放入回收列表;否则直接释放任务占用的资源
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskDelete(UINT32 taskId)
{
LosTaskCB *taskCB = NULL;
@ -1072,7 +1078,7 @@ LOS_RETURN:
SCHEDULER_UNLOCK(intSave);
return errRet;
}
//LOS_TaskResume函数用于恢复一个挂起的任务
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskId)
{
UINT32 intSave;
@ -1136,6 +1142,7 @@ LOS_ERREND:
* 3. Do the suspension in hard-irq
* then LOS_TaskSuspend will directly return with 'ret' value.
*/
//OsTaskSuspendCheckOnRun检查当前任务是否需要挂起的函数根据条件判断是否需要进行任务挂起操作
LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UINT32 *ret)
{
/* init default out return value */
@ -1164,7 +1171,8 @@ LITE_OS_SEC_TEXT_INIT STATIC BOOL OsTaskSuspendCheckOnRun(LosTaskCB *taskCB, UIN
return TRUE;
}
//LOS_TaskSuspend挂起指定任务的函数
//如果任务已经处于挂起状态或者正在运行,并且不满足挂起条件,则直接返回错误码;否则执行挂起操作
LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskSuspend(UINT32 taskId)
{
UINT32 intSave;
@ -1218,7 +1226,7 @@ LOS_RETURN:
SCHEDULER_UNLOCK(intSave);
return errRet;
}
//LOS_TaskDelay该函数用于让任务进入延时状态在指定的时间后重新被调度执行
LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
{
UINT32 intSave;
@ -1250,7 +1258,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_TaskDelay(UINT32 tick)
return LOS_OK;
}
//LOS_TaskDelay将任务进入延时状态在指定的时间后重新被调度执行如果当前在中断中或者不可抢占则返回相应的错误码
LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskId)
{
UINT32 intSave;
@ -1273,7 +1281,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskPriGet(UINT32 taskId)
SCHEDULER_UNLOCK(intSave);
return priority;
}
//LOS_TaskPriGet获取指定任务的优先级
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskId, UINT16 taskPrio)
{
BOOL isReady = FALSE;
@ -1325,7 +1333,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskPriSet(UINT32 taskId, UINT16 taskPrio)
}
return LOS_OK;
}
//LOS_TaskPriSet设置指定任务的优先级根据任务当前状态选择不同的处理方式
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
{
return LOS_TaskPriSet(OsCurrTaskGet()->taskId, taskPrio);
@ -1337,6 +1345,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CurTaskPriSet(UINT16 taskPrio)
* taskStatus --- task status
* timeOut --- Expiry time
* Return : LOS_OK on success or LOS_NOK on failure
* OsTaskWaitOsTaskWake
*/
VOID OsTaskWait(LOS_DL_LIST *list, UINT16 taskStatus, UINT32 timeout)
{
@ -1373,7 +1382,7 @@ VOID OsTaskWake(LosTaskCB *resumedTask, UINT16 taskStatus)
OsPriQueueEnqueue(&resumedTask->pendList, resumedTask->priority);
}
}
//LOS_TaskYield用于使当前任务主动放弃 CPU 控制权,让出 CPU 给其他高优先级任务执行
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
{
UINT32 tskCount;
@ -1412,6 +1421,8 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID)
return LOS_OK;
}
//LOS_TaskLock和LOS_TaskUnlock任务锁定和解锁函数用于保护临界区
LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID)
{
UINT32 intSave;
@ -1446,7 +1457,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID)
LOS_IntRestore(intSave);
}
//LOS_TaskInfoGet获取指定任务的信息包括任务名、栈大小、堆栈使用情况等
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskId, TSK_INFO_S *taskInfo)
{
UINT32 intSave;
@ -1503,7 +1514,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskId, TSK_INFO_S *taskInf
return LOS_OK;
}
//LOS_TaskCpuAffiSet和LOS_TaskCpuAffiGet设置和获取任务的 CPU 亲和性,仅在支持多核的情况下有效
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskId, UINT16 cpuAffiMask)
{
#ifdef LOSCFG_KERNEL_SMP
@ -1580,6 +1591,7 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskId)
/*
* Description : Process pending signals tagged by others cores
*OsTaskProcSignal
*/
LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskProcSignal(VOID)
{

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*时钟模块:主要包括系统时钟的初始化、时钟中断处理函数、获取系统tick数等功能*/
#include "los_tick_pri.h"
#include "los_swtmr_pri.h"
#include "los_task_pri.h"
@ -52,6 +52,7 @@ STATIC WAKEUPFROMINTHOOK g_tickWakeupHook = NULL;
/*
* Description : Tick interruption handler
*/
//OsTickHandler函数时钟中断处理函数用于处理时钟中断事件。
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
{
UINT32 intSave;
@ -76,7 +77,7 @@ LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
OsSwtmrScan();
#endif
}
//OsTickInit初始化系统时钟
LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond)
{
if ((systemClock == 0) ||
@ -88,12 +89,12 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsTickInit(UINT32 systemClock, UINT32 tickPerSecond
return LOS_OK;
}
//启动系统时钟
LITE_OS_SEC_TEXT_INIT VOID OsTickStart(VOID)
{
HalClockStart();
}
//LOS_TickCountGet函数获取系统tick数
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
{
UINT32 intSave;
@ -109,12 +110,12 @@ LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
return tick;
}
//LOS_CyclePerTickGet函数获取每个tick所对应的CPU周期数
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID)
{
return g_sysClock / KERNEL_TICK_PER_SECOND;
}
//LOS_GetCpuCycle函数获取CPU周期数
LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt)
{
UINT64 cycle;
@ -129,7 +130,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_GetCpuCycle(UINT32 *highCnt, UINT32 *lowCnt)
/* get the low 32 bits */
*lowCnt = (UINT32)(cycle & 0xFFFFFFFFULL);
}
//LOS_CurrNanosec函数获取当前的纳秒数
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_CurrNanosec(VOID)
{
UINT64 nanos;
@ -137,7 +138,7 @@ LITE_OS_SEC_TEXT_MINOR UINT64 LOS_CurrNanosec(VOID)
nanos = HalClockGetCycles() * (OS_SYS_NS_PER_SECOND / OS_SYS_NS_PER_MS) / (g_sysClock / OS_SYS_NS_PER_MS);
return nanos;
}
//LOS_MS2Tick函数将毫秒转换为tick数
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
{
UINT64 delaySec;
@ -149,17 +150,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
delaySec = (UINT64)millisec * KERNEL_TICK_PER_SECOND;
return (UINT32)((delaySec + OS_SYS_MS_PER_SECOND - 1) / OS_SYS_MS_PER_SECOND);
}
//LOS_Tick2MS函数将tick数转换为毫秒数
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick)
{
return (UINT32)(((UINT64)tick * OS_SYS_MS_PER_SECOND) / KERNEL_TICK_PER_SECOND);
}
//LOS_Udelay函数微秒级延迟函数
LITE_OS_SEC_TEXT_MINOR VOID LOS_Udelay(UINT32 usecs)
{
HalDelayUs(usecs);
}
//LOS_Mdelay函数毫秒级延迟函数
LITE_OS_SEC_TEXT_MINOR VOID LOS_Mdelay(UINT32 msecs)
{
UINT32 delayUs = (UINT32_MAX / OS_SYS_US_PER_MS) * OS_SYS_US_PER_MS;

@ -43,9 +43,9 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define HEAP_CAST(t, exp) ((t)(exp))
#define HEAP_ALIGN sizeof(UINTPTR)
#define MALLOC_MAXSIZE (0xFFFFFFFF - HEAP_ALIGN + 1)
#define HEAP_CAST(t, exp) ((t)(exp))//这个宏定义是一个类型转换的快捷方式。它接受两个参数t 表示目标类型exp 是需要进行类型转换的表达式。这个宏最终会将 exp 转换为类型 t。
#define HEAP_ALIGN sizeof(UINTPTR)//这个宏定义定义了 HEAP_ALIGN它的值是 sizeof(UINTPTR)。sizeof 操作符用于返回其操作数的大小(以字节为单位),所以 HEAP_ALIGN 的值将取决于 UINTPTR 类型的大小。
#define MALLOC_MAXSIZE (0xFFFFFFFF - HEAP_ALIGN + 1)//这个宏定义了 MALLOC_MAXSIZE它的值是 0xFFFFFFFF - HEAP_ALIGN + 1。在这里0xFFFFFFFF 表示一个32位无符号整数的最大值HEAP_ALIGN 已经在上面定义过了。这个宏定义似乎是用来表示在分配内存时可能的最大尺寸。
/*
* Description : look up the next memory node according to one memory node in the memory block list.
@ -53,13 +53,25 @@ extern "C" {
* struct LosHeapNode *node --- Size of memory in bytes to allocate
* Return : Pointer to next memory node
*/
/*这个函数的作用是获取下一个堆节点的指针。具体实现过程如下:
node NULL
LosHeapNode data size data size
struct LosHeapNode* UINTPTR struct LosHeapNode*
*/
struct LosHeapNode* OsHeapPrvGetNext(struct LosHeapManager *heapMan, struct LosHeapNode *node)
{
return (heapMan->tail == node) ? NULL : (struct LosHeapNode *)(UINTPTR)(node->data + node->size);
}
#ifdef LOSCFG_MEM_TASK_STAT
/*该函数接受两个参数heapMan 表示堆管理器的指针size 表示堆的初始大小。该函数的作用是初始化堆的统计信息,
heapMan->stat
heapMan->stat.memTotalUsed heapMan->stat.memTotalPeak使
memset_s heapMan->stat 0
heapMan->stat.memTotalUsed sizeof(struct LosHeapNode) + sizeof(struct LosHeapManager)使
heapMan->stat.memTotalPeak heapMan->stat.memTotalUsed使
LOSCFG_MEM_TASK_STAT */
VOID OsHeapStatInit(struct LosHeapManager *heapMan, UINT32 size)
{
(VOID)memset_s(&heapMan->stat, sizeof(Memstat), 0, sizeof(Memstat));
@ -67,7 +79,16 @@ VOID OsHeapStatInit(struct LosHeapManager *heapMan, UINT32 size)
heapMan->stat.memTotalUsed = sizeof(struct LosHeapNode) + sizeof(struct LosHeapManager);
heapMan->stat.memTotalPeak = heapMan->stat.memTotalUsed;
}
/*该函数的作用是向堆的统计信息中添加被使用的内存块。具体实现过程如下:
taskId blockSizetaskId IDblockSize
taskId OS_INT_INACTIVE
taskId ID LOS_CurTaskIDGet taskId TASK_NUM - 1
taskId taskId便
OS_MEM_ADD_USED blockSize taskId stat
便使使
使便*/
VOID OsHeapStatAddUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node)
{
UINT32 taskId;
@ -87,7 +108,13 @@ VOID OsHeapStatAddUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node)
node->taskId = taskId;
OS_MEM_ADD_USED(&heapMan->stat, blockSize, taskId);
}
/*该函数的作用是从堆的统计信息中减少被使用的内存块。具体实现过程如下:
taskId blockSizetaskId ID
blockSize
OS_MEM_REDUCE_USED blockSize taskId stat
便使使
使便 OsHeapStatAddUsed
使使*/
VOID OsHeapStatDecUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node)
{
UINT32 taskId = node->taskId;
@ -97,17 +124,25 @@ VOID OsHeapStatDecUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node)
}
#else /* LOSCFG_MEM_TASK_STAT */
//函数用于初始化堆管理器的内存统计信息。它接受两个参数heapMan 表示堆管理器的指针size 表示堆的总大小。在这个备选实现中,该函数没有任何具体的实现操作,直接返回。
VOID OsHeapStatInit(struct LosHeapManager *heapMan, UINT32 size) { }
//函数用于向堆的统计信息中添加被使用的内存块。它接受两个参数heapMan 表示堆管理器的指针node 表示要添加到统计信息中的堆节点指针。在这个备选实现中,该函数没有任何具体的实现操作,什么也不做。
VOID OsHeapStatAddUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) { }
//函数用于从堆的统计信息中减少被使用的内存块。它接受两个参数heapMan 表示堆管理器的指针node 表示要从统计信息中减少使用的堆节点指针。在这个备选实现中,该函数没有任何具体的实现操作,什么也不做。
VOID OsHeapStatDecUsed(struct LosHeapManager *heapMan, struct LosHeapNode *node) { }
#endif /* LOSCFG_MEM_TASK_STAT */
#ifdef LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK
/*这段代码实现了一个堆完整性检查的函数 OsHeapIntegrityCheck用于检查堆内存的完整性
(struct LosHeapNode *)(heap + 1) heap
heapStart heapEnd
LOS_NOK
OsHeapPrvGetNext
LOS_OK
*/
UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap)
{
struct LosHeapNode *node = (struct LosHeapNode *)(heap + 1);
@ -127,7 +162,7 @@ UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap)
}
#else /* LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK */
//这段代码实现了一个名为 OsHeapIntegrityCheck 的函数,它接受一个指向 LosHeapManager 结构体的指针作为参数,并直接返回 LOS_OK。
UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap)
{
return LOS_OK;
@ -136,12 +171,16 @@ UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap)
#endif /* LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK */
#ifdef LOSCFG_KERNEL_MEM_SLAB_EXTENTION
/*接受一个指向内存池的指针 pool 和一个表示需要分配内存大小的参数 size。
OsHeapAlloc
*/
VOID *OsMemAlloc(VOID *pool, UINT32 size)
{
return OsHeapAlloc(pool, size);
}
/*接受一个指向内存池的指针 pool 和一个指向待释放内存块的指针 ptr。
OsHeapFree
LOS_OK LOS_NOK */
UINT32 OsMemFree(VOID *pool, const VOID *ptr)
{
if (OsHeapFree(pool, ptr) == TRUE) {
@ -160,6 +199,19 @@ UINT32 OsMemFree(VOID *pool, const VOID *ptr)
* UITN32 size --- size of the heap memory pool
* Return : 1:success 0:error
*/
/*这段代码实现了一个名为 OsHeapInit 的函数,用于初始化堆内存管理器。让我逐步解释这段代码的功能:
pool size
pool struct LosHeapManager heapMan便
heapMan NULL
FALSE
使 memset_s 0
size size - sizeof(struct LosHeapManager)
head tail usedprev size
OsHeapStatInit
TRUE
*/
BOOL OsHeapInit(VOID *pool, UINT32 size)
{
struct LosHeapNode *node = NULL;
@ -192,6 +244,33 @@ BOOL OsHeapInit(VOID *pool, UINT32 size)
* UINT32 size --- size of the heap memory pool
* Return : NULL:error, other value:the address of the memory we alloced
*/
/*这段代码实现了一个名为 OsHeapAlloc 的函数,用于在堆内存管理器中分配指定大小的内存块。让我逐步解释这段代码的功能:
pool size
nodenextbestptr alignSize
heapMan pool struct LosHeapManager 便
heapMan NULL MALLOC_MAXSIZE NULL
OsHeapIntegrityCheck LOS_OK NULL
使node->used == 0node->size >= alignSize
best
best->size == alignSize SIZE_MATCH
best != NULL
SIZE_MATCH
alignSize
ptr
NULL*/
VOID *OsHeapAlloc(VOID *pool, UINT32 size)
{
struct LosHeapNode *node = NULL;
@ -222,11 +301,18 @@ VOID *OsHeapAlloc(VOID *pool, UINT32 size)
}
/* alloc failed */
/*这是一个条件判断语句,如果找到的最佳节点为空(即没有足够大小的空闲节点),则执行花括号中的代码块。*/
if (best == NULL) {
PRINT_ERR("there's not enough mem to alloc 0x%x Bytes!\n", alignSize);
goto OUT;
}
PRINT_ERR("there's not enough mem to alloc 0x%x Bytes!\n", alignSize);//在没有足够空闲内存来分配请求大小的内存块时,打印错误信息,提示用户无法分配指定大小的内存。
goto OUT;//跳转到标签 OUT 处,这通常是用于执行清理和释放资源的操作。
}
/*这是另一个条件判断语句,用于判断是否有足够的空间将找到的节点分割为两部分,以满足请求的大小,并且保留一个足够大的空洞来放置下一个节点的元数据。*/
/*node = (struct LosHeapNode*)(UINTPTR)(best->data + alignSize);:计算出新的节点的地址,该节点位于原节点的空闲空间之后,用于存放剩余的内存块。
node->used = 0;使
node->size = best->size - alignSize - sizeof(struct LosHeapNode);
node->prev = best;
best->size = alignSize;*/
if ((best->size - alignSize) > sizeof(struct LosHeapNode)) {
/* hole divide into 2 */
node = (struct LosHeapNode*)(UINTPTR)(best->data + alignSize);
@ -246,7 +332,11 @@ VOID *OsHeapAlloc(VOID *pool, UINT32 size)
best->size = alignSize;
}
/*这段代码可能是用于实现动态内存分配器的代码。具体来说,函数名称 SIZE_MATCH 可能代表了一种内存分配策略,即在进行内存分配时,选择最能够匹配请求大小的空闲内存块进行分配。
best best align 0used 1使 ptr OsHeapStatAddUsed 使
*/
SIZE_MATCH:
best->align = 0;
best->used = 1;
@ -264,6 +354,15 @@ OUT:
* UINT32 boundary --- boundary the heap needs align
* Return : NULL:error, other value:the address of the memory we alloced
*/
/*这段代码是一个用于分配指定大小、指定对齐边界alignment boundary的内存块的函数。该函数的名称为 OsHeapAllocAlign。
pool size 0boundary sizeof(VOID*)VOID* boundary NULL
useSize使 OsHeapAlloc pool useSize ptr
OS_MEM_ALIGN ptr boundary OUT ptr gap gap sizeof(UINTPTR) alignedPtr
*/
VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
{
UINT32 useSize;
@ -297,7 +396,15 @@ VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
OUT:
return ptr;
}
/*这段代码是一个用于释放内存的函数,名称为 OsHeapDoFree。该函数接收两个参数一个是 LosHeapManager 结构体指针 heapMan代表内存池管理器另一个是 LosHeapNode 结构体指针 curNode代表需要释放的内存块对应的内存池节点。
curNode node used 0使
使 while node 使 node node
使 while 使 OsHeapPrvGetNext node next next 使 node next node size heapMan->tail heapMan->tail next 使
使 LosHeapManager LosHeapNode */
STATIC VOID OsHeapDoFree(struct LosHeapManager *heapMan, struct LosHeapNode *curNode)
{
struct LosHeapNode *node = curNode;
@ -330,6 +437,15 @@ STATIC VOID OsHeapDoFree(struct LosHeapManager *heapMan, struct LosHeapNode *cur
* VOID* ptr --- the pointer of heap memory we want to free
* Return : 1:success 0:error
*/
/*这段代码是用于释放指定内存块的函数 OsHeapFree。该函数接收两个参数一个是 VOID 类型指针 pool代表内存池另一个是 const VOID 类型指针 ptr代表需要释放的内存块的起始地址。
node LosHeapNode gapSize UINT32 ret BOOL
ptr sizeof(UINTPTR) ptr ptr FALSE
使 ((struct LosHeapNode *)ptr) - 1 node 使 ret FALSE OUT
OsHeapStatDecUsed used OsHeapDoFree node ret */
BOOL OsHeapFree(VOID *pool, const VOID *ptr)
{
struct LosHeapNode *node = NULL;
@ -378,6 +494,19 @@ OUT:
* Output : status --- heap statistics
* Return : LOS_OK on success or error code on failure
*/
/*这段代码是用于获取指定内存池的统计信息的函数 OsHeapStatisticsGet。该函数接收两个参数一个是 VOID 类型指针 pool代表内存池另一个是 LosHeapStatus 结构体指针 status用于保存内存池的统计信息。
heapUsedmaxFreeNodeSizefreeNodeNumusedNodeNum node ramHeap heapUsed maxFreeNodeSize freeNodeNum usedNodeNum
LOS_NOK status LOS_NOK
使 sizeof(struct LosHeapManager) heapUsed
使 node 使 heapUsed usedNodeNum 使 maxFreeNodeSize freeNodeNum
heapUsed LOS_NOK status LOS_OK
LOSCFG_MEM_TASK_STAT usageWaterLine */
UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status)
{
UINT32 heapUsed = 0;
@ -435,6 +564,15 @@ UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status)
* Input : pool --- Pointer to the manager, to distinguish heap
* Return : max free block size
*/
/*这段代码是用于获取指定内存池中最大可用块大小的函数 OsHeapGetMaxFreeBlkSize。该函数接收一个参数一个 VOID 类型指针 pool代表内存池。
sizetemp node ramHeap size temp
LOS_NOK
使 node 使 temp temp size size temp
size */
UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool)
{
UINT32 size = 0;

@ -41,18 +41,40 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define POOL_ADDR_ALIGNSIZE 64
#define POOL_ADDR_ALIGNSIZE 64//是一个宏表示内存池地址对齐的大小值为64。
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memSpin);
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memSpin);//是一个修饰符用于指定变量所属的段section为.bss.init该变量在程序运行前会被初始化为0。
//是一个宏用于初始化自旋锁变量g_memSpin。
UINT8 *m_aucSysMem0 = (UINT8 *)NULL;
UINT8 *m_aucSysMem1 = (UINT8 *)NULL;
__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end;
UINT8 *m_aucSysMem0 = (UINT8 *)NULL;//是一个指向UINT8类型的指针变量初始值为NULL。
UINT8 *m_aucSysMem1 = (UINT8 *)NULL;//是一个指向UINT8类型的指针变量初始值为NULL。
__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end;//是一个UINTPTR类型的变量位于.data.init段用于记录系统内存地址的末尾位置。
#ifdef LOSCFG_EXC_INTERACTION
__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0;
#ifdef LOSCFG_EXC_INTERACTION//表示如果定义了宏LOSCFG_EXC_INTERACTION则编译以下代码块。
__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0;//是一个UINTPTR类型的变量位于.data.init段用于记录异常交互内存的大小初始值为0。
#endif
/*这段代码是一个函数LOS_MemInit()的实现,用于初始化内存池。
LITE_OS_SEC_TEXT_INIT section.text.init
pool
size
poolsizesizeof(struct LosHeapManager)LOS_NOK
poolsizeOS_MEM_ALIGN_SIZEsize
OsMemMulPoolInit()OUT
OsHeapInit()OUT
OsSlabMemInit() Slab LOS_OK
OUT
LOS_NOKLOS_OK
Slab */
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size)
{
UINT32 ret = LOS_NOK;
@ -103,6 +125,21 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMemExcInteractionInit(UINTPTR memStart)
* Description : Initialize Dynamic Memory pool
* Return : LOS_OK on success or error code on failure
*/
/*这段代码是一个条件编译块当定义了宏LOSCFG_EXC_INTERACTION时才会被编译。
LITE_OS_SEC_TEXT_INIT section.text.init
memStart
m_aucSysMem0memStartmemStart
g_excInteractMemSizeEXC_INTERACT_MEM_SIZE
LOS_MemInit()m_aucSysMem0g_excInteractMemSizeret
ret
LOS_MemInit()LOSCFG_EXC_INTERACTION*/
LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart)
{
UINT32 ret;
@ -121,6 +158,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart)
* Description : print heap information
* Input : pool --- Pointer to the manager, to distinguish heap
*/
/*这段代码是用于打印内存池pool信息的函数接收一个pool指针作为参数。
pool
poolLosHeapManagerheapMan
LosHeapStatusstatus
OsHeapStatisticsGet()statusLOS_NOK
使
便*/
VOID OsMemInfoPrint(const VOID *pool)
{
struct LosHeapManager *heapMan = (struct LosHeapManager *)pool;
@ -136,6 +185,20 @@ VOID OsMemInfoPrint(const VOID *pool)
status.usedNodeNum, status.freeNodeNum);
}
/*这段代码是用于内存分配的函数,可以从指定的内存池中分配一块指定大小的内存。
pool
size
ptr
poolsize0
OsSlabMemAlloc()SLABptr
SLABOsHeapAlloc()ptr
SLAB便*/
LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size)
{
VOID *ptr = NULL;
@ -158,6 +221,19 @@ LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size)
return ptr;
}
/*这段代码是用于按指定对齐边界分配内存的函数,可以从指定的内存池中分配一块指定大小、按指定对齐边界对齐的内存。
pool
size
boundary
ptr
OsHeapAllocAlign()ptr
便*/
LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
{
VOID *ptr = NULL;
@ -171,6 +247,14 @@ LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundar
return ptr;
}
/*这段代码是用于重新分配内存大小的函数,主要有以下几个步骤:
ptrLOS_MemAlloc()
ptr0
ptr0OsSlabMemCheck()
*/
VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size)
{
VOID *retPtr = NULL;
@ -228,6 +312,15 @@ VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size)
return retPtr;
}
/*这段代码是用于释放内存的函数,主要有以下几个步骤:
poolmemLOS_NOK
便
OsSlabMemFree()TRUE
OsSlabMemFree()OsHeapFree()TRUEFALSE
TRUELOS_OKLOS_NOK
*/
LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *mem)
{
BOOL ret = FALSE;
@ -250,6 +343,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *mem)
return (ret == TRUE ? LOS_OK : LOS_NOK);
}
/*这段代码是用于获取内存池状态信息的函数,主要有以下几个步骤:
poolstatusLOS_NOK
LosHeapStatusheapStatus
errintSave
便
OsHeapStatisticsGet()heapStatusLOS_OKLOS_NOK
status使使
使statusuwUsageWaterLine
LOS_OK
使使*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *status)
{
LosHeapStatus heapStatus;
@ -282,6 +386,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *st
return LOS_OK;
}
/*这段代码是用于获取指定内存池已使用内存大小的函数,主要有以下几个步骤:
poolOS_NULL_INT
LosHeapStatusheapStatus
errintSave
便
OsHeapStatisticsGet()heapStatusLOS_OKOS_NULL_INT
使
使使便*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool)
{
LosHeapStatus heapStatus;
@ -303,6 +416,13 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool)
return heapStatus.totalUsedSize;
}
/*这段代码是用于获取指定内存池的大小的函数,主要有以下几个步骤:
poolOS_NULL_INT
LosHeapManagerheapManager
LosHeapManagerheapManager
heapManager->size
便*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(const VOID *pool)
{
struct LosHeapManager *heapManager = NULL;
@ -315,6 +435,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(const VOID *pool)
return heapManager->size;
}
/*这段代码是用于对指定内存池进行完整性检查的函数,主要有以下几个步骤:
poolOS_NULL_INT
intSaveret
便
OsHeapIntegrityCheck()ret0
*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool)
{
UINT32 intSave;
@ -331,6 +459,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool)
return ret;
}
/*这段代码是用于对多个内存池进行完整性检查的函数,主要有以下几个步骤:
LOS_MemIntegrityCheck()m_aucSysMem1LOS_OK
LOSCFG_EXC_INTERACTION
LOS_MemIntegrityCheck()m_aucSysMem0LOS_OK
*/
VOID OsMemIntegrityMultiCheck(VOID)
{
if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) {

@ -42,13 +42,18 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//用于将指定的大小 sz 进行对齐,返回对齐后的大小。它使用 HEAP_ALIGN 宏定义来指定对齐的字节数,通过将 sz 加上 HEAP_ALIGN - 1然后按位取反与运算&)来实现向上对齐。
#define ALIGNE(sz) (((sz) + HEAP_ALIGN - 1) & (~(HEAP_ALIGN - 1)))
//用于将指定的 value 进行 align 字节对齐,返回对齐后的值。它将 value 转换为 UINT32 类型,并将其与 align - 1 按位取反与运算,即将 value 向上舍入到最近的 align 的倍数。
#define OS_MEM_ALIGN(value, align) (((UINT32)(UINTPTR)(value) + (UINT32)((align) - 1)) & \
(~(UINT32)((align) - 1)))
//用于表示对齐标志的宏定义,其值为 0x80000000。
#define OS_MEM_ALIGN_FLAG 0x80000000
//用于设置对齐标志的宏定义,将传入的 align 参数按位或运算与 OS_MEM_ALIGN_FLAG 进行组合。
#define OS_MEM_SET_ALIGN_FLAG(align) ((align) = ((align) | OS_MEM_ALIGN_FLAG))
//用于获取对齐标志的宏定义,将传入的 align 参数与 OS_MEM_ALIGN_FLAG 进行按位与运算,得到对齐标志。
#define OS_MEM_GET_ALIGN_FLAG(align) ((align) & OS_MEM_ALIGN_FLAG)
//用于获取对齐间隙大小的宏定义,将传入的 align 参数与 ~OS_MEM_ALIGN_FLAG 进行按位与运算,得到去除对齐标志后的值。
#define OS_MEM_GET_ALIGN_GAPSIZE(align) ((align) & (~OS_MEM_ALIGN_FLAG))
typedef struct tagLosHeapStatus {
@ -60,8 +65,12 @@ typedef struct tagLosHeapStatus {
#ifdef LOSCFG_MEM_TASK_STAT
UINT32 usageWaterLine;
#endif
} LosHeapStatus;
} LosHeapStatus;//结构体:描述了内存堆的状态信息,包括总共使用的大小、总共空闲的大小、最大空闲节点的大小、已用节点数和空闲节点数等字段。
/*结构体:描述了内存堆中的每个节点,包括前一个节点指针、任务 ID、节点大小、
使使
使 0 data[0]
便*/
struct LosHeapNode {
struct LosHeapNode *prev;
#ifdef LOSCFG_MEM_TASK_STAT
@ -73,12 +82,12 @@ struct LosHeapNode {
UINT8 data[0];
};
extern BOOL OsHeapInit(VOID *pool, UINT32 size);
extern VOID* OsHeapAlloc(VOID *pool, UINT32 size);
extern VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary);
extern BOOL OsHeapFree(VOID *pool, const VOID* ptr);
extern UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status);
extern UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap);
extern BOOL OsHeapInit(VOID *pool, UINT32 size);//函数声明:用于初始化内存池,即将一块内存空间转化为一个内存堆,并返回是否初始化成功。
extern VOID* OsHeapAlloc(VOID *pool, UINT32 size);//函数声明:用于在内存堆上分配一块指定大小的内存,并返回分配到的内存地址。
extern VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary);//函数声明:用于在内存堆上分配一块指定大小并且按照给定对齐边界对齐的内存,并返回分配到的内存地址。
extern BOOL OsHeapFree(VOID *pool, const VOID* ptr);//函数声明:用于释放内存堆中的指定内存地址所对应的节点,返回是否释放成功。
extern UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status);//函数声明:用于获取内存堆的状态信息,并将其保存在传入的 LosHeapStatus 结构体中,返回获取到的信息字节数。
extern UINT32 OsHeapIntegrityCheck(struct LosHeapManager *heap);//函数声明:用于检查整个内存堆的完整性,即检查是否存在内存泄漏或内存重叠等问题。
#ifdef __cplusplus
#if __cplusplus

@ -39,6 +39,15 @@ extern "C" {
#define MIN_TASK_ID(x, y) ((x) > (y) ? (y) : (x))
#define MAX_MEM_USE(x, y) ((x) > (y) ? (x) : (y))
/*这段代码是一个函数OsMemstatTaskUsedInc的实现用于更新内存统计信息。
IDstattaskMemstats
usedSizememUsed使usedSize使MAX_MEM_USEmemUsedmemPeakmemPeak
usedSizestatmemTotalUsed使usedSize使MAX_MEM_USE
使*/
LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedInc(Memstat *stat, UINT32 usedSize, UINT32 taskId)
{
UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1);
@ -51,6 +60,13 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedInc(Memstat *stat, UINT32 usedSize,
stat->memTotalPeak = MAX_MEM_USE(stat->memTotalPeak, stat->memTotalUsed);
}
/*这段代码是一个函数OsMemstatTaskUsedDec的实现用于更新内存统计信息。
IDstattaskMemstats
使usedSizeusedSizememUsed使usedSizeusedSizestatmemTotalUsed使usedSize
使便*/
LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedDec(Memstat *stat, UINT32 usedSize, UINT32 taskId)
{
UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1);
@ -66,6 +82,15 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskUsedDec(Memstat *stat, UINT32 usedSize,
stat->memTotalUsed -= usedSize;
}
/*这段代码是一个函数OsMemstatTaskClear的实现用于清除任务的内存统计信息。
IDstattaskMemstats
使00
memUsedmemPeak0使
*/
LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskClear(Memstat *stat, UINT32 taskId)
{
UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1);
@ -80,6 +105,13 @@ LITE_OS_SEC_TEXT_MINOR VOID OsMemstatTaskClear(Memstat *stat, UINT32 taskId)
taskMemstats[record].memPeak = 0;
}
/*这段代码是一个函数OsMemstatTaskUsage的实现用于获取指定任务的内存使用量。
IDstattaskMemstats
memUsed使
使*/
LITE_OS_SEC_TEXT_MINOR UINT32 OsMemstatTaskUsage(const Memstat *stat, UINT32 taskId)
{
UINT32 record = MIN_TASK_ID(taskId, TASK_NUM - 1);
@ -88,6 +120,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsMemstatTaskUsage(const Memstat *stat, UINT32 tas
return taskMemstats[record].memUsed;
}
/*这段代码是一个函数OsMemTaskUsage的实现用于获取指定任务在系统内所有内存池中的内存使用量之和。
poolstat
statOsMemstatTaskUsage使
使
使*/
UINT32 OsMemTaskUsage(UINT32 taskId)
{
LosMemPoolInfo *pool = NULL;
@ -110,6 +153,17 @@ UINT32 OsMemTaskUsage(UINT32 taskId)
#endif
}
/*这段代码是一个函数OsMemTaskClear的实现用于清除指定任务在系统内所有内存池中的内存统计信息。
poolstat
statOsMemstatTaskClear
OsMemstatTaskClear
*/
VOID OsMemTaskClear(UINT32 taskId)
{
LosMemPoolInfo *pool = NULL;

@ -30,6 +30,17 @@
STATIC VOID *g_poolHead = NULL;
/*这段代码是一个函数OsMemMulPoolInit的实现用于初始化多内存池。
nextPoolcurPoolpoolEndnextPoolcurPoolpoolEnd
NULL
使便*/
UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size)
{
VOID *nextPool = g_poolHead;
@ -58,6 +69,21 @@ UINT32 OsMemMulPoolInit(VOID *pool, UINT32 size)
return LOS_OK;
}
/*这段代码是一个函数OsMemMulPoolDeinit的实现用于反初始化多内存池。
retnextPoolcurPoolretnextPoolcurPool
do-while
退
next
*/
UINT32 OsMemMulPoolDeinit(const VOID *pool)
{
UINT32 ret = LOS_NOK;
@ -90,12 +116,29 @@ UINT32 OsMemMulPoolDeinit(const VOID *pool)
return ret;
}
/*这段代码是函数OsMemMulPoolHeadGet的实现用于获取多内存池链表的头节点指针。
g_poolHead
便便*/
VOID *OsMemMulPoolHeadGet(VOID)
{
return g_poolHead;
}
/*这段代码是函数LOS_MemDeInit的实现用于释放指定内存池的资源并进行反初始化操作。
retintSaveretintSave
MEM_LOCK
OsMemMulPoolDeinitret
MEM_UNLOCK
使MEM_LOCKOsMemMulPoolDeinit使MEM_UNLOCK*/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pool)
{
UINT32 ret;
@ -108,6 +151,17 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemDeInit(VOID *pool)
return ret;
}
/*这段代码是函数LOS_MemPoolList的实现用于打印多内存池链表中每个内存池的信息。
nextPoolindexnextPoolindex
whileOsMemInfoPrintnextPoolindex
OsMemInfoPrint
便使OsMemInfoPrint便*/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemPoolList(VOID)
{
VOID *nextPool = g_poolHead;

@ -25,7 +25,11 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOSShell
CPU
CPU101
*/
#include "los_config.h"
#ifdef LOSCFG_SHELL
#ifdef LOSCFG_CPUP_INCLUDE_IRQ
@ -39,7 +43,7 @@
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
//这个函数实现了打印硬件中断信息的表头
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdHwiInfoTitle(VOID)
{
#ifdef LOSCFG_CPUP_INCLUDE_IRQ
@ -53,7 +57,7 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdHwiInfoTitle(VOID)
PRINTK("----------- ----- ------------- --------- --------\n");
#endif
}
//这个函数会根据传入的硬件中断句柄信息,获取该中断是否为共享模式
STATIC BOOL GetHwiShare(const HwiHandleInfo *hwiForm)
{
#ifndef LOSCFG_SHARED_IRQ
@ -64,9 +68,10 @@ STATIC BOOL GetHwiShare(const HwiHandleInfo *hwiForm)
}
#ifdef LOSCFG_CPUP_INCLUDE_IRQ
STATIC CPUP_INFO_S g_hwiCpupAll[LOSCFG_PLATFORM_HWI_LIMIT];
STATIC CPUP_INFO_S g_hwiCpup10s[LOSCFG_PLATFORM_HWI_LIMIT];
STATIC CPUP_INFO_S g_hwiCpup1s[LOSCFG_PLATFORM_HWI_LIMIT];
STATIC CPUP_INFO_S g_hwiCpupAll[LOSCFG_PLATFORM_HWI_LIMIT];//所有时间段CPU利用率的统计信息
STATIC CPUP_INFO_S g_hwiCpup10s[LOSCFG_PLATFORM_HWI_LIMIT];//最近10sCPU利用率的统计信息
STATIC CPUP_INFO_S g_hwiCpup1s[LOSCFG_PLATFORM_HWI_LIMIT];//最近1sCPU利用率的统计信息
//这个函数实现了硬件中断信息的查询根据参数argc和argv判断是否有误并调用其他函数获取硬件中断的各项信息最终打印输出硬件中断的详细信息。
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
{
UINT32 i, intSave;
@ -75,22 +80,24 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
HwiHandleInfo *hwiForm = NULL;
(VOID)argv;
//打印错误信息
if (argc > 0) {
PRINTK("\nUsage: hwi\n");
return OS_ERROR;
}
(VOID)memset_s(g_hwiCpupAll, size, 0, size);
(VOID)memset_s(g_hwiCpup10s, size, 0, size);
(VOID)memset_s(g_hwiCpup1s, size, 0, size);
(VOID)memset_s(g_hwiCpupAll, size, 0, size);//置零
(VOID)memset_s(g_hwiCpup10s, size, 0, size);//置零
(VOID)memset_s(g_hwiCpup1s, size, 0, size);//置零
intSave = LOS_IntLock();
(VOID)LOS_AllCpuUsage(LOSCFG_PLATFORM_HWI_LIMIT, g_hwiCpupAll, CPUP_ALL_TIME, 0);
(VOID)LOS_AllCpuUsage(LOSCFG_PLATFORM_HWI_LIMIT, g_hwiCpup10s, CPUP_LAST_TEN_SECONDS, 0);
(VOID)LOS_AllCpuUsage(LOSCFG_PLATFORM_HWI_LIMIT, g_hwiCpup1s, CPUP_LAST_ONE_SECONDS, 0);
LOS_IntRestore(intSave);
//打印硬件中断信息的表头
OsShellCmdHwiInfoTitle();
//打印CPU硬件中断的利用率
for (i = 0; i < LOSCFG_PLATFORM_HWI_LIMIT; i++) {
if (!HWI_IS_REGISTED(i)) {
continue;
@ -101,6 +108,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
}
/* Different cores has different hwi form implementation */
//打印各个时间内的硬件中断利用率
hwiForm = OsGetHwiForm(i);
PRINTK("%-8u\t %-s\t %-10u\t %-10llu %2u.%-7u %2u.%-7u %2u.%-6u",
i, GetHwiShare(hwiForm) ? "Y" : "N", OsGetHwiFormCnt(i), cycles,
@ -110,6 +118,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
#ifdef LOSCFG_SHARED_IRQ
hwiForm = hwiForm->next;
#endif
//打印中断设备ID和信息
if ((hwiForm->registerInfo != 0) && ((HWI_IRQ_PARAM_S *)hwiForm->registerInfo)->pName != NULL) {
PRINTK("\t %-16s 0x%-.8x\n",
((HWI_IRQ_PARAM_S *)hwiForm->registerInfo)->pName,
@ -128,24 +137,28 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
return 0;
}
#else
//这个函数主要实现对hwi命令的解释功能输出硬件中断信息
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
{
UINT32 i;
HwiHandleInfo *hwiForm = NULL;
//参数错误,打印错误信息
(VOID)argv;
if (argc > 0) {
PRINTK("\nUsage: hwi\n");
return OS_ERROR;
}
//打印硬件中断信息的表头
OsShellCmdHwiInfoTitle();
//遍历所有硬件中断寄存器
for (i = 0; i < LOSCFG_PLATFORM_HWI_LIMIT; i++) {
if (!HWI_IS_REGISTED(i)) {
continue;
}
/* Different cores has different hwi form implementation */
//输出信息
hwiForm = OsGetHwiForm(i);
PRINTK("%-8u\t %-s\t %-10u", i, GetHwiShare(hwiForm) ? "Y" : "N", OsGetHwiFormCnt(i));
#ifdef LOSCFG_SHARED_IRQ
@ -170,7 +183,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdHwi(INT32 argc, const CHAR **argv)
return 0;
}
#endif
//该函数实现了OsShellCmdHwi的函数调用用户可以输入hwi命令来调用该函数从而查询和展示硬件中断信息
SHELLCMD_ENTRY(hwi_shellcmd, CMD_TYPE_EX, "hwi", 0, (CmdCallBackFunc)OsShellCmdHwi);
#ifdef __cplusplus

@ -25,7 +25,10 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOSShell
使
*/
#include "stdlib.h"
#include "stdio.h"
#include "los_memory_pri.h"
@ -45,54 +48,60 @@ extern "C" {
#define MEM_SIZE_1K 0x400
#define MEM_SIZE_1M 0x100000
//这个函数用于检查内存完整性
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[])
{
//打印错误信息
if (argc > 0) {
PRINTK("\nUsage: memcheck\n");
return OS_ERROR;
}
//调用OsMemIntegrityMultiCheck函数完成内存完整性检查
OsMemIntegrityMultiCheck();
return 0;
}
#ifdef LOSCFG_SHELL
//这个函数可以读取内存中指定位置指定长度的数据调用OsDumpMemByte函数完成内存读取并打印数据
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemRead(INT32 argc, const CHAR *argv[])
{
size_t tempAddr;
size_t length;
CHAR *ptrlen = NULL;
CHAR *ptrAddr = NULL;
//读取错误,打印错误信息
if ((argc == 0) || (argc > 2)) { /* argc is num of parameters */
PRINTK("\nUsage: readreg [ADDRESS] [LENGTH]\n");
return OS_ERROR;
}
//读取正确
if (argc == 1) {
length = 0;
} else {
//读取长度为负数,打印错误信息
length = strtoul(argv[1], &ptrlen, 0);
if ((ptrlen == NULL) || (*ptrlen != 0)) {
PRINTK("readreg invalid length %s\n", argv[1]);
return OS_ERROR;
}
}
//保存ptrAddr的地址
tempAddr = strtoul(argv[0], &ptrAddr, 0);
//地址错误,打印错误信息
if ((ptrAddr == NULL) || (*ptrAddr != 0) || (tempAddr > g_sys_mem_addr_end) ||
((tempAddr + length) > g_sys_mem_addr_end) || (tempAddr > (OS_NULL_INT - length))) {
PRINTK("readreg invalid address %s\n", argv[0]);
return OS_ERROR;
}
//调用OsDumpMemByte函数打印指定内存位置读取的信息。
OsDumpMemByte(length, tempAddr);
return 0;
}
//这个函数用于输出代码段、数据段、只读数据段和BSS段的大小信息。
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdSectionInfo(INT32 argc, const CHAR *argv[])
{
//计算各部分长度
size_t textLen = &__text_end - &__text_start;
size_t dataLen = &__ram_data_end - &__ram_data_start;
size_t rodataLen = &__rodata_end - &__rodata_start;
@ -103,7 +112,7 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdSectionInfo(INT32 argc, const CHAR
dataLen += &__fast_data_end - &__fast_data_start;
rodataLen += &__fast_rodata_end - &__fast_rodata_start;
#endif
//打印代码段、数据段、只读数据段、BSS段的大小信息
PRINTK("\r\n text data rodata bss\n");
if ((argc == 1) && (strcmp(argv[0], "-k") == 0)) {
PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", textLen / MEM_SIZE_1K, dataLen / MEM_SIZE_1K,
@ -115,19 +124,24 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdSectionInfo(INT32 argc, const CHAR
PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", textLen, dataLen, rodataLen, bssLen);
}
}
//这个函数用于输出系统可用的内存总量、已经使用的内存量和剩余内存量的大小
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OsShellCmdFreeInfo(INT32 argc, const CHAR *argv[])
{
#ifdef LOSCFG_EXC_INTERACTION
//调用LOS_MemTotaUsedGet函数得到已经使用的内存量
UINT32 memUsed0 = LOS_MemTotalUsedGet(m_aucSysMem0);
//调用LOS_MemPoolSizeGet函数得到系统可用的内存总量
UINT32 totalMem0 = LOS_MemPoolSizeGet(m_aucSysMem0);
//计算得到系统剩余的内存量
UINT32 freeMem0 = totalMem0 - memUsed0;
#endif
//调用LOS_MemTotaUsedGet函数得到已经使用的内存量
UINT32 memUsed = LOS_MemTotalUsedGet(m_aucSysMem1);
//调用LOS_MemPoolSizeGet函数得到系统可用的内存总量
UINT32 totalMem = LOS_MemPoolSizeGet(m_aucSysMem1);
/
UINT32 freeMem = totalMem - memUsed;
//打印统可用的内存总量、已经使用的内存量和剩余内存量的大小
if ((argc == 0) ||
((argc == 1) && (strcmp(argv[0], "-k") == 0)) ||
((argc == 1) && (strcmp(argv[0], "-m") == 0))) {
@ -157,47 +171,57 @@ LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OsShellCmdFreeInfo(INT32 argc, const CHAR *
PRINTK("Mem1: %-9u %-10u %-10u\n", totalMem0, memUsed0, freeMem0);
#endif
} else {
//打印错误信息
PRINTK("\nUsage: free or free [-k/-m]\n");
return OS_ERROR;
}
return 0;
}
//这个函数用于显示系统内存的使用情况调用了OsShellCmdFreeInfo和OsShellCmdSectionInfo函数完成内存使用情况和内存分配情况的打印输出。
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[])
{
//打印错误信息
if (argc > 1) {
PRINTK("\nUsage: free or free [-k/-m]\n");
return OS_ERROR;
}
//打印错误信息
if (OsShellCmdFreeInfo(argc, argv) != 0) {
return OS_ERROR;
}
//调用OsShellCmdSectionInfo函数输出存使用情况和内存分配情况
OsShellCmdSectionInfo(argc, argv);
return 0;
}
//这个函数根据参数选择输出不同的系统信息,在控制台上输出相应的信息。
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[])
{
//如果参数为0在控制台上打印Huawei LiteOS
if (argc == 0) {
PRINTK("Huawei LiteOS\n");
return 0;
}
if (argc == 1) {
//系统参数为-a时打印LiteOS所有的信息
if (strcmp(argv[0], "-a") == 0) {
PRINTK("%s %s %s %s %s\n", HW_LITEOS_VER, HW_LITEOS_SYSNAME, HW_LITEOS_KERNEL_VERSION_STRING,
__DATE__, __TIME__);
return 0;
//系统参数为-s时打印Huawei LiteOS
} else if (strcmp(argv[0], "-s") == 0) {
PRINTK("Huawei LiteOS\n");
return 0;
//系统参数为-t时打印系统创建的时间信息
} else if (strcmp(argv[0], "-t") == 0) {
PRINTK("build date : %s %s", __DATE__, __TIME__);
return 0;
//系统参数为-v时打印LiteOS的版本信息和时间信息
} else if (strcmp(argv[0], "-v") == 0) {
PRINTK("%s %s %s %s\n", HW_LITEOS_SYSNAME, HW_LITEOS_KERNEL_VERSION_STRING,
__DATE__, __TIME__);
return 0;
//系统参数为--help时打印各参数的含义
} else if (strcmp(argv[0], "--help") == 0) {
PRINTK("-a, print all information\n"
"-s, print the kernel name\n"
@ -206,20 +230,22 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[])
return 0;
}
}
//如果都不是,打印错误信息,提示用户输入--help来查看信息
PRINTK("uname: invalid option %s\n"
"Try 'uname --help' for more information.\n",
argv[0]);
return OS_ERROR;
}
#ifdef LOSCFG_MEM_LEAKCHECK
//这个函数打印了系统已使用的内存信息
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemUsed(INT32 argc, const CHAR *argv[])
{
//打印错误信息
if (argc > 0) {
PRINTK("\nUsage: memused\n");
return OS_ERROR;
}
//调用OsMemUsedNodeShow函数输出已使用的节点信息
OsMemUsedNodeShow(m_aucSysMem1);
#ifdef LOSCFG_EXC_INTERACTION
@ -230,6 +256,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemUsed(INT32 argc, const CHAR *argv[])
}
#endif
/*
memcheckOsMemIntegrityMultiCheck
memread [ADDRESS] [LENGTH]OsDumpMemByte
free使OsShellCmdFreeInfoOsShellCmdSectionInfo使
uname [-a/-s/-t/-v]PRINTK
*/
#ifdef LOSCFG_MEM_LEAKCHECK
SHELLCMD_ENTRY(memused_shellcmd, CMD_TYPE_EX, "memused", 0, (CmdCallBackFunc)OsShellCmdMemUsed);
#endif

@ -25,7 +25,10 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOSShell
*/
#include "securec.h"
#include "los_config.h"
#include "los_stackinfo_pri.h"
@ -34,7 +37,7 @@
#include "shcmd.h"
#include "shell.h"
#endif
//这个函数用于检查堆栈是否溢出
VOID OsExcStackCheck(VOID)
{
UINT32 index;
@ -42,15 +45,17 @@ VOID OsExcStackCheck(VOID)
UINTPTR *stackTop = NULL;
const StackInfo *stackInfo = NULL;
UINT32 stackNum;
//获取堆栈信息,如果堆栈信息错误,直接返回
OsGetStackInfo(&stackInfo, &stackNum);
if ((stackInfo == NULL) || (stackNum == 0)) {
return;
}
//从头开始,遍历所有的堆栈
for (index = 0; index < stackNum; index++) {
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
//堆栈的栈顶
stackTop = (UINTPTR *)((UINTPTR)stackInfo[index].stackTop + cpuid * stackInfo[index].stackSize);
//检查栈顶信息是否被篡改,如果被篡改输出该堆栈溢出的信息
if (*stackTop != OS_STACK_MAGIC_WORD) {
PRINT_ERR("cpu:%u %s overflow , magic word changed to 0x%x\n",
LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, stackInfo[index].stackName, *stackTop);
@ -58,7 +63,7 @@ VOID OsExcStackCheck(VOID)
}
}
}
//这个函数用于获取并打印所有的堆栈信息
VOID OsExcStackInfo(VOID)
{
UINT32 index;
@ -68,29 +73,31 @@ VOID OsExcStackInfo(VOID)
UINTPTR *stack = NULL;
const StackInfo *stackInfo = NULL;
UINT32 stackNum;
//获取堆栈信息,如果堆栈信息错误,直接返回
OsGetStackInfo(&stackInfo, &stackNum);
if ((stackInfo == NULL) || (stackNum == 0)) {
return;
}
//输出堆栈名、CPU ID、堆栈的地址、堆栈的总大小堆栈已使用的大小
PrintExcInfo("\n stack name cpu id stack addr total size used size\n"
" ---------- ------ --------- -------- --------\n");
//从头开始,遍历所有的堆栈
for (index = 0; index < stackNum; index++) {
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
//获取堆栈的栈顶
stackTop = (UINTPTR *)((UINTPTR)stackInfo[index].stackTop + cpuid * stackInfo[index].stackSize);
stack = (UINTPTR *)((UINTPTR)stackTop + stackInfo[index].stackSize);
//调用OsStackWaterLineGet函数计算堆栈已使用的大小
(VOID)OsStackWaterLineGet(stack, stackTop, &size);
//输出各类信息
PrintExcInfo("%11s %-5d %-10p 0x%-8x 0x%-4x\n", stackInfo[index].stackName,
LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, stackTop, stackInfo[index].stackSize, size);
}
}
//进行堆栈溢出检查
OsExcStackCheck();
}
//注册Shell命令stack调用OsExcStackInfo函数获取并打印所有堆栈信息至控制台。
#ifdef LOSCFG_SHELL
SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo);
#endif

@ -25,7 +25,10 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOS
ID
*/
#include "los_config.h"
#ifdef LOSCFG_SHELL
#include "stdlib.h"
@ -42,20 +45,20 @@ extern "C" {
#define SWTMR_STRLEN 12
#ifdef LOSCFG_BASE_CORE_SWTMR
//展示g_shellSwtmrMode的数据
LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrMode[][SWTMR_STRLEN] = {
"Once",
"Period",
"NSD",
"OPP",
};
//展示g_shellSwtmrStatus的数据
LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = {
"UnUsed",
"Created",
"Ticking",
};
//这个函数用于打印软件定时器的信息包括定时器ID、状态、模式、间隔、参数和处理函数地址等。
STATIC VOID OsPrintSwtmrMsg(const LosSwtmrCB *swtmr)
{
PRINTK("0x%08x "
@ -64,20 +67,20 @@ STATIC VOID OsPrintSwtmrMsg(const LosSwtmrCB *swtmr)
"%-6u "
"0x%08x "
"%p\n",
swtmr->timerId % LOSCFG_BASE_CORE_SWTMR_LIMIT,
g_shellSwtmrStatus[swtmr->state],
g_shellSwtmrMode[swtmr->mode],
swtmr->interval,
swtmr->arg,
swtmr->handler);
swtmr->timerId % LOSCFG_BASE_CORE_SWTMR_LIMIT,//打印定时器ID
g_shellSwtmrStatus[swtmr->state],//打印定时器的状态
g_shellSwtmrMode[swtmr->mode],//打印定时器的模式
swtmr->interval,//打印定时器的间隔
swtmr->arg,//打印定时器的参数
swtmr->handler);//打印定时器的处理函数地址
}
//这个函数用于打印软件定时器信息的表头
STATIC INLINE VOID OsPrintSwtmrMsgHead(VOID)
{
PRINTK("\r\nSwTmrID State Mode Interval Arg handlerAddr\n");
PRINTK("---------- ------- ------- --------- ---------- --------\n");
}
//这个函数用于获取软件定时器的信息。
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSwtmrInfoGet(INT32 argc, const UINT8 **argv)
{
#define OS_ALL_SWTMR_MASK 0xffffffff
@ -87,34 +90,36 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSwtmrInfoGet(INT32 argc, const UINT8 **a
size_t timerId;
UINT16 num = 0;
CHAR *endPtr = NULL;
//打印错误信息
if (argc > 1) {
PRINTK("\nUsage: swtmr [ID]\n");
return OS_ERROR;
}
//获取计时器ID
if (argc == 0) {
timerId = OS_ALL_SWTMR_MASK;
} else {
//没有这个ID打印错误信息
timerId = strtoul((CHAR *)argv[0], &endPtr, 0);
if ((endPtr == NULL) || (*endPtr != 0) || (timerId > LOSCFG_BASE_CORE_SWTMR_LIMIT)) {
PRINTK("\nswtmr ID can't access %s.\n", argv[0]);
return OS_ERROR;
}
}
//遍历所有计时器让计时器的状态加1
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr1++) {
if (swtmr1->state == 0) {
num = num + 1;
}
}
//达到时间限制,输出错误信息
if (num == LOSCFG_BASE_CORE_SWTMR_LIMIT) {
PRINTK("\r\nThere is no swtmr was created!\n");
return OS_ERROR;
}
//打印软件定时器信息的表头
OsPrintSwtmrMsgHead();
//打印软件定时器的各类信息
if (timerId == OS_ALL_SWTMR_MASK) {
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
if (swtmr->state != 0) {
@ -132,7 +137,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSwtmrInfoGet(INT32 argc, const UINT8 **a
}
return LOS_OK;
}
//注册Shell命令swtmr调用OsShellCmdSwtmrInfoGet函数获取软件定时器的信息。根据输入的参数获取特定或者所有软件定时器的状态信息并打印出来。
SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet);
#endif

@ -25,7 +25,10 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOSShell
*/
#include "los_config.h"
#include "los_swtmr.h"
#include "los_sem_pri.h"
@ -43,141 +46,173 @@
extern "C" {
#endif
#endif /* __cplusplus */
//这个函数用于获取当系统的进程数量
UINT32 OsShellCmdTaskCntGet(VOID)
{
UINT32 loop;
UINT32 taskCnt = 0;
UINT32 intSave;
LosTaskCB *taskCB = NULL;
//加上锁,用于防止中断
intSave = LOS_IntLock();
//遍历所有进程,并统计进程数量
for (loop = 0; loop < g_taskMaxNum; loop++) {
taskCB = (LosTaskCB *)g_taskCBArray + loop;
//若该进程未使用,则直接跳过
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
continue;
}
taskCnt++;
}
//为进程解锁
LOS_IntRestore(intSave);
//返回系统的进程数量
return taskCnt;
}
#ifdef LOSCFG_BASE_IPC_SEM
//这个函数用于获取当前系统信号量的数量
UINT32 OsShellCmdSemCntGet(VOID)
{
UINT32 loop;
UINT32 semCnt = 0;
UINT32 intSave;
LosSemCB *semNode = NULL;
//加上锁,用于防止中断
intSave = LOS_IntLock();
//遍历所有信号量
for (loop = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) {
semNode = GET_SEM(loop);
//如果该信号量被使用了数量加1
if (semNode->semStat == LOS_USED) {
semCnt++;
}
}
//为进程解锁
LOS_IntRestore(intSave);
//返回系统信号量的数量
return semCnt;
}
#endif
#ifdef LOSCFG_BASE_IPC_MUX
//这个函数用于获取当前系统互斥锁的数量
UINT32 OsShellCmdMuxCntGet(VOID)
{
UINT32 loop;
UINT32 muxCnt = 0;
UINT32 intSave;
LosMuxCB *muxNode = NULL;
//加上锁,用于防止中断
intSave = LOS_IntLock();
//遍历所有互斥锁
for (loop = 0; loop < LOSCFG_BASE_IPC_MUX_LIMIT; loop++) {
muxNode = GET_MUX(loop);
//如果互斥锁的状态被使用了数量加1
if (muxNode->muxStat == LOS_USED) {
muxCnt++;
}
}
//为进程解锁
LOS_IntRestore(intSave);
//返回系统互斥锁的数量
return muxCnt;
}
#endif
#ifdef LOSCFG_BASE_IPC_QUEUE
//这个函数用于获取系统消息队列的数量
UINT32 OsShellCmdQueueCntGet(VOID)
{
UINT32 loop;
UINT32 queueCnt = 0;
UINT32 intSave;
LosQueueCB *queueCB = NULL;
//加上锁,用于防止中断
intSave = LOS_IntLock();
queueCB = g_allQueue;
//遍历所有消息队列
for (loop = 0; loop < LOSCFG_BASE_IPC_QUEUE_LIMIT; loop++, queueCB++) {
//如果消息队列的状态为使用数量加1
if (queueCB->queueState == LOS_USED) {
queueCnt++;
}
}
//为进程解锁
LOS_IntRestore(intSave);
//返回系统获取消息队列的数量
return queueCnt;
}
#endif
#ifdef LOSCFG_BASE_CORE_SWTMR
//这个函数用于获取系统软件定时器的数量
UINT32 OsShellCmdSwtmrCntGet(VOID)
{
UINT32 loop;
UINT32 swtmrCnt = 0;
UINT32 intSave;
LosSwtmrCB *swtmrCB = NULL;
//加上锁,用于防止中断
intSave = LOS_IntLock();
swtmrCB = g_swtmrCBArray;
//遍历所有软件定时器
for (loop = 0; loop < LOSCFG_BASE_CORE_SWTMR_LIMIT; loop++, swtmrCB++) {
//如果软件定时器的状态不是没有使用数量加1
if (swtmrCB->state != OS_SWTMR_STATUS_UNUSED) {
swtmrCnt++;
}
}
//为进程解锁
LOS_IntRestore(intSave);
//返回系统软件定时器的数量
return swtmrCnt;
}
#endif
//这个函数用于打印系统信息,包括进程数量、信号量数量、互斥锁数量、消息队列数量和软件定时器数量。
LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID)
{
//打印表头
PRINTK("\n Module Used Total\n");
PRINTK("--------------------------------\n");
//打印进程数量
PRINTK(" Task %-10u%-10d\n",
OsShellCmdTaskCntGet(),
LOSCFG_BASE_CORE_TSK_LIMIT);
#ifdef LOSCFG_BASE_IPC_SEM
//打印信号量数量
PRINTK(" Sem %-10u%-10d\n",
OsShellCmdSemCntGet(),
LOSCFG_BASE_IPC_SEM_LIMIT);
#endif
#ifdef LOSCFG_BASE_IPC_MUX
//打印互斥锁数量
PRINTK(" Mutex %-10u%-10d\n",
OsShellCmdMuxCntGet(),
LOSCFG_BASE_IPC_MUX_LIMIT);
#endif
#ifdef LOSCFG_BASE_IPC_QUEUE
//打印消息队列数量
PRINTK(" Queue %-10u%-10d\n",
OsShellCmdQueueCntGet(),
LOSCFG_BASE_IPC_QUEUE_LIMIT);
#endif
#ifdef LOSCFG_BASE_CORE_SWTMR
//打印软件定时器数量
PRINTK(" SwTmr %-10u%-10d\n",
OsShellCmdSwtmrCntGet(),
LOSCFG_BASE_CORE_SWTMR_LIMIT);
#endif
}
//这个函数用于处理shell的systeminfo命令根据相应的参数做出相应的处理
INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv)
{
//如果参数数量为0调用OsShellCmdSystemInfoGet函数打印所有的系统信息。
if (argc == 0) {
OsShellCmdSystemInfoGet();
return 0;
}
//参数数量不正确,打印错误信息
PRINTK("systeminfo: invalid option %s\n"
"Systeminfo has NO ARGS.\n",
argv[0]);
@ -185,6 +220,7 @@ INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv)
}
#ifdef LOSCFG_SHELL
//注册Shell命令systeminfo调用OsShellCmdSystemInfo根据参数输出当前系统的程数量、信号量数量、互斥锁数量、消息队列数量和软件定时器数量。。
SHELLCMD_ENTRY(systeminfo_shellcmd, CMD_TYPE_EX, "systeminfo", 1, (CmdCallBackFunc)OsShellCmdSystemInfo);
#endif /* LOSCFG_SHELL */

@ -25,7 +25,10 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*
LiteOSShell
*/
#include "stdio.h"
#include "stdlib.h"
#include "los_config.h"
@ -53,55 +56,65 @@ extern "C" {
#define OS_INVALID_SEM_ID 0xFFFFFFFF
#ifdef LOSCFG_KERNEL_CPUP
LITE_OS_SEC_BSS STATIC CPUP_INFO_S g_taskCpupAll[LOSCFG_BASE_CORE_TSK_LIMIT];
LITE_OS_SEC_BSS STATIC CPUP_INFO_S g_taskCpup10s[LOSCFG_BASE_CORE_TSK_LIMIT];
LITE_OS_SEC_BSS STATIC CPUP_INFO_S g_taskCpup1s[LOSCFG_BASE_CORE_TSK_LIMIT];
LITE_OS_SEC_BSS STATIC CPUP_INFO_S g_taskCpupAll[LOSCFG_BASE_CORE_TSK_LIMIT];//所有时间段CPU利用率的统计信息
LITE_OS_SEC_BSS STATIC CPUP_INFO_S g_taskCpup10s[LOSCFG_BASE_CORE_TSK_LIMIT];//最近10sCPU利用率的统计信息
LITE_OS_SEC_BSS STATIC CPUP_INFO_S g_taskCpup1s[LOSCFG_BASE_CORE_TSK_LIMIT];//最近1sCPU利用率的统计信息
#endif
LITE_OS_SEC_BSS STATIC UINT32 g_taskWaterLine[LOSCFG_BASE_CORE_TSK_LIMIT];
LITE_OS_SEC_BSS STATIC UINT32 g_taskWaterLine[LOSCFG_BASE_CORE_TSK_LIMIT];//记录各个堆栈最低的水位
//这个函数通过进程状态位来判断进程的状态,并返回相应的字符串表示进程状态。
LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdConvertTskStatus(UINT16 taskStatus)
{
//进程处于运行状态返回Running
if (taskStatus & OS_TASK_STATUS_RUNNING) {
return (UINT8 *)"Running";
//进程处于就绪状态返回Ready
} else if (taskStatus & OS_TASK_STATUS_READY) {
return (UINT8 *)"Ready";
//其他的进程状态
} else {
//进程处于延迟状态返回Delay
if (taskStatus & OS_TASK_STATUS_DELAY) {
return (UINT8 *)"Delay";
} else if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
//进程处于定时挂起状态返回SuspendTime
if (taskStatus & OS_TASK_STATUS_SUSPEND) {
return (UINT8 *)"SuspendTime";
//进程处于定时等待状态返回PendTime
} else if (taskStatus & OS_TASK_STATUS_PEND) {
return (UINT8 *)"PendTime";
}
//进程处于等待状态返回Pend
} else if (taskStatus & OS_TASK_STATUS_PEND) {
return (UINT8 *)"Pend";
//进程处于挂起状态返回SusPend
} else if (taskStatus & OS_TASK_STATUS_SUSPEND) {
return (UINT8 *)"Suspend";
}
}
//进程状态不合法返回Invalid
return (UINT8 *)"Invalid";
}
//这个函数用于获取所有堆栈的栈水位(堆栈的使用情况)
STATIC VOID OsShellCmdTaskWaterLineGet(const LosTaskCB *allTaskArray)
{
const LosTaskCB *taskCB = NULL;
UINT32 loop;
//遍历所有堆栈
for (loop = 0; loop < g_taskMaxNum; ++loop) {
taskCB = allTaskArray + loop;
//如果该堆栈未使用,直接跳过
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
continue;
}
//调用OsStackWaterLineGet输出堆栈的栈水位信息
(VOID)OsStackWaterLineGet((const UINTPTR *)((UINTPTR)taskCB->topOfStack + taskCB->stackSize),
(const UINTPTR *)taskCB->topOfStack, &g_taskWaterLine[taskCB->taskId]);
}
}
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
//这个函数用于在异常信息输出缓冲区中打印任务信息的标题。
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoTitleExc(VOID)
{
WriteExcInfoToBuf("\r\nName TaskEntryAddr TID ");
@ -133,7 +146,7 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoTitleExc(VOID)
WriteExcInfoToBuf("\n");
}
#endif
//这个函数用于在控制台打印任务信息的标题。
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoTitle(VOID)
{
PRINTK("\r\nName TaskEntryAddr TID ");
@ -165,14 +178,15 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoTitle(VOID)
PRINTK("\n");
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
//在异常信息输出缓冲区中打印任务信息的标题。
OsShellCmdTskInfoTitleExc();
#endif
}
//这个函数通过TCB进程控制块获取进程所持有的信号量的ID。
LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsGetSemID(const LosTaskCB *taskCB)
{
UINT32 semId = OS_INVALID_SEM_ID;
//返回该进程的信号量ID
if (taskCB->taskSem != NULL) {
semId = ((LosSemCB *)taskCB->taskSem)->semId;
}
@ -181,12 +195,13 @@ LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsGetSemID(const LosTaskCB *taskCB)
}
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
//这个函数用于将TCB进程控制块中的进程信息输出到异常信息输出缓冲区。
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoDataExc(const LosTaskCB *allTaskArray)
{
const LosTaskCB *taskCB = NULL;
UINT32 loop;
UINT32 semId;
//遍历所有的堆栈
for (loop = 0; loop < g_taskMaxNum; ++loop) {
taskCB = allTaskArray + loop;
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
@ -194,21 +209,25 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoDataExc(const LosTaskCB *all
}
semId = OsGetSemID(taskCB);
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf("%-23s0x%-18.8x0x%-5x", taskCB->taskName, taskCB->taskEntry, taskCB->taskId);
#ifdef LOSCFG_KERNEL_SMP
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf("0x%04x %4d ", taskCB->cpuAffiMask, (INT16)(taskCB->currCpu));
#endif
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf("%-11u%-13s0x%-11x0x%-11x 0x%-.8x 0x%-.8x 0x%-11x", taskCB->priority,
OsShellCmdConvertTskStatus(taskCB->taskStatus), taskCB->stackSize,
g_taskWaterLine[taskCB->taskId],
taskCB->stackPointer, taskCB->topOfStack, semId);
#ifdef LOSCFG_BASE_IPC_EVENT
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf("0x%-6x", taskCB->eventMask);
#endif
#ifdef LOSCFG_KERNEL_CPUP
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf(" %4u.%1u%9u.%1u%8u.%1u ",
g_taskCpupAll[taskCB->taskId].uwUsage / LOS_CPUP_PRECISION_MULT,
g_taskCpupAll[taskCB->taskId].uwUsage % LOS_CPUP_PRECISION_MULT,
@ -218,41 +237,47 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoDataExc(const LosTaskCB *all
g_taskCpup1s[taskCB->taskId].uwUsage % LOS_CPUP_PRECISION_MULT);
#endif /* LOSCFG_KERNEL_CPUP */
#ifdef LOSCFG_MEM_TASK_STAT
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf(" %-11u", OsMemTaskUsage(taskCB->taskId));
#endif
//调用WriteExcInfoToBuf函数将TCB进程控制块的信息写入缓冲区
WriteExcInfoToBuf("\n");
}
}
#endif
//这个函数可以将TCB(进程控制块)中的信息输出到控制台。
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoData(const LosTaskCB *allTaskArray)
{
const LosTaskCB *taskCB = NULL;
UINT32 loop;
UINT32 semId;
//遍历所有的堆栈
for (loop = 0; loop < g_taskMaxNum; ++loop) {
taskCB = allTaskArray + loop;
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
continue;
}
//调用OsGetSemID获取该进程的信号量ID
semId = OsGetSemID(taskCB);
//输出进程信息到控制台
PRINTK("%-23s0x%-18.8x0x%-5x", taskCB->taskName, taskCB->taskEntry, taskCB->taskId);
#ifdef LOSCFG_KERNEL_SMP
//输出进程信息到控制台
PRINTK("0x%04x %4d ", taskCB->cpuAffiMask, (INT16)(taskCB->currCpu));
#endif
//输出进程信息到控制台
PRINTK("%-11u%-13s0x%-11x0x%-11x 0x%-.8x 0x%-.8x 0x%-11x", taskCB->priority,
OsShellCmdConvertTskStatus(taskCB->taskStatus), taskCB->stackSize,
g_taskWaterLine[taskCB->taskId],
taskCB->stackPointer, taskCB->topOfStack, semId);
#ifdef LOSCFG_BASE_IPC_EVENT
//输出进程信息到控制台
PRINTK("0x%-6x", taskCB->eventMask);
#endif
#ifdef LOSCFG_KERNEL_CPUP
//输出进程信息到控制台
PRINTK(" %4u.%1u%9u.%1u%8u.%1u ",
g_taskCpupAll[taskCB->taskId].uwUsage / LOS_CPUP_PRECISION_MULT,
g_taskCpupAll[taskCB->taskId].uwUsage % LOS_CPUP_PRECISION_MULT,
@ -262,16 +287,19 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdTskInfoData(const LosTaskCB *allTas
g_taskCpup1s[taskCB->taskId].uwUsage % LOS_CPUP_PRECISION_MULT);
#endif /* LOSCFG_KERNEL_CPUP */
#ifdef LOSCFG_MEM_TASK_STAT
//输出进程信息到控制台
PRINTK(" %-11u", OsMemTaskUsage(taskCB->taskId));
#endif
//输出进程信息到控制台
PRINTK("\n");
}
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
//将进程信息输出到异常信息输出缓冲区。
OsShellCmdTskInfoDataExc(allTaskArray);
#endif
}
//这个函数可以通过进程号获取进程的信息
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskId)
{
BOOL backupFlag = TRUE;
@ -279,50 +307,57 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskId)
UINT32 size, intSave;
LosTaskCB *tcbArray = NULL;
INT32 ret;
//如果是目标进程
if (taskId == OS_ALL_TASK_MASK) {
size = g_taskMaxNum * sizeof(LosTaskCB);
tcbArray = (LosTaskCB *)LOS_MemAlloc(m_aucSysMem1, size);
//如果目标进程信息为空输出错误信息将backup设置为Fasle不备份该进程信息
if (tcbArray == NULL) {
PRINTK("Memory is not enough to save task info!\n");
tcbArray = g_taskCBArray;
backupFlag = FALSE;
}
#ifdef LOSCFG_KERNEL_CPUP
(VOID)memset_s((VOID *)g_taskCpupAll, sizeof(g_taskCpupAll), 0, sizeof(g_taskCpupAll));
(VOID)memset_s((VOID *)g_taskCpup10s, sizeof(g_taskCpup10s), 0, sizeof(g_taskCpup10s));
(VOID)memset_s((VOID *)g_taskCpup1s, sizeof(g_taskCpup1s), 0, sizeof(g_taskCpup1s));
(VOID)memset_s((VOID *)g_taskCpupAll, sizeof(g_taskCpupAll), 0, sizeof(g_taskCpupAll));//置零
(VOID)memset_s((VOID *)g_taskCpup10s, sizeof(g_taskCpup10s), 0, sizeof(g_taskCpup10s));//置零
(VOID)memset_s((VOID *)g_taskCpup1s, sizeof(g_taskCpup1s), 0, sizeof(g_taskCpup1s));//置零
#endif
(VOID)memset_s((VOID *)g_taskWaterLine, sizeof(g_taskWaterLine), 0, sizeof(g_taskWaterLine));
(VOID)memset_s((VOID *)g_taskWaterLine, sizeof(g_taskWaterLine), 0, sizeof(g_taskWaterLine));//置零
//如果没有调度器自旋锁,为该进程添加调度器自旋锁
if (LOS_SpinHeld(&g_taskSpin) == FALSE) {
SCHEDULER_LOCK(intSave);
lockFlag = TRUE;
}
//如果需要将进程信息备份
if (backupFlag == TRUE) {
//将进程信息备份到tcbArray
ret = memcpy_s(tcbArray, size, g_taskCBArray, size);
//如果没有备份成果返回错误
if (ret != EOK) {
return LOS_NOK;
}
}
#ifdef LOSCFG_KERNEL_CPUP
(VOID)LOS_AllCpuUsage(LOSCFG_BASE_CORE_TSK_LIMIT, g_taskCpupAll, CPUP_ALL_TIME, 1);
(VOID)LOS_AllCpuUsage(LOSCFG_BASE_CORE_TSK_LIMIT, g_taskCpup10s, CPUP_LAST_TEN_SECONDS, 1);
(VOID)LOS_AllCpuUsage(LOSCFG_BASE_CORE_TSK_LIMIT, g_taskCpup1s, CPUP_LAST_ONE_SECONDS, 1);
(VOID)LOS_AllCpuUsage(LOSCFG_BASE_CORE_TSK_LIMIT, g_taskCpupAll, CPUP_ALL_TIME, 1);//显示CPU所有时段的使用率信息
(VOID)LOS_AllCpuUsage(LOSCFG_BASE_CORE_TSK_LIMIT, g_taskCpup10s, CPUP_LAST_TEN_SECONDS, 1);//显示CPU最近10s的使用率信息
(VOID)LOS_AllCpuUsage(LOSCFG_BASE_CORE_TSK_LIMIT, g_taskCpup1s, CPUP_LAST_ONE_SECONDS, 1);//显示CPU最近1s的使用率信息
#endif
//获取进程的栈水位信息
OsShellCmdTaskWaterLineGet(tcbArray);
//如果进程有调度器自旋锁,将该进程解锁
if (lockFlag == TRUE) {
SCHEDULER_UNLOCK(intSave);
}
//打印进程信息标题
OsShellCmdTskInfoTitle();
//打印进程信息的数据
OsShellCmdTskInfoData(tcbArray);
//如果进程信息数据备份成果释放tcbArrayd的内存空间
if (backupFlag == TRUE) {
(VOID)LOS_MemFree(m_aucSysMem1, tcbArray);
}
} else {
//调用 OsTaskBackTrace函数来获取该任务的回溯信息。
OsTaskBackTrace(taskId);
}
@ -330,29 +365,34 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskId)
}
#ifdef LOSCFG_SHELL
//这个函数用于处理task命令通过各种参数输出结果
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
{
size_t taskId;
CHAR *endPtr = NULL;
//当参数数量合法时
if (argc < 2) { /* 2:Just as number of parameters */
//如果没有参数,进程号是所有进程
if (argc == 0) {
taskId = OS_ALL_TASK_MASK;
//存在一个参数为进程号
} else {
taskId = strtoul(argv[0], &endPtr, 0);
//如果进程号不合法,打印错误信息
if ((*endPtr != 0) || (taskId >= g_taskMaxNum)) {
PRINTK("\ntask ID can't access %s.\n", argv[0]);
return OS_ERROR;
}
}
//调用OsShellCmdTskInfoGet函数输出该进程的进程信息
return OsShellCmdTskInfoGet((UINT32)taskId);
} else {
//参数不合法,打印错误信息
PRINTK("\nUsage: task or task ID\n");
return OS_ERROR;
}
}
//注册Shell命令task调用OsShellCmdDumpTask根据参数进程号或者没有参数获取进程信息并输出。
SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask);
#endif

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "windows-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "D:/mingw64/bin/gcc.exe",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "windows-gcc-x64",
"compilerArgs": [
""
]
}
],
"version": 4
}

@ -0,0 +1,24 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": true,
"cwd": "h:/ruanjian/LiteOS-Reading/src/kernel/extended/perf/pmu",
"program": "h:/ruanjian/LiteOS-Reading/src/kernel/extended/perf/pmu/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

@ -0,0 +1,59 @@
{
"C_Cpp_Runner.cCompilerPath": "gcc",
"C_Cpp_Runner.cppCompilerPath": "g++",
"C_Cpp_Runner.debuggerPath": "gdb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
}

@ -25,7 +25,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
/*低功耗管理*/
#include "los_lowpower_pri.h"
#ifdef LOSCFG_KERNEL_TICKLESS
#include "los_tickless_pri.h"
@ -36,10 +36,10 @@
__attribute__((section(".data"))) STATIC const PowerMgrOps *g_pmOps = NULL;
VOID OsLowpowerInit(const PowerMgrOps *pmOps)
VOID OsLowpowerInit(const PowerMgrOps *pmOps) /*初始化低功耗管理*/
{
if (pmOps == NULL) {
#ifdef LOSCFG_KERNEL_POWER_MGR
#ifdef LOSCFG_KERNEL_POWER_MGR/*是否配置了低功耗内核管理*/
PRINT_ERR("\r\n [PM] PowerMgrOps must be non-null.\n");
return;
#endif
@ -55,27 +55,27 @@ VOID OsLowpowerInit(const PowerMgrOps *pmOps)
g_pmOps = pmOps;
LOS_LowpowerHookReg(OsPowerMgrProcess);
/*注册低功耗处理函数和终端唤醒处理函数*/
LOS_IntWakeupHookReg(OsPowerMgrWakeUpFromInterrupt);
}
VOID OsPowerMgrProcess(VOID)
VOID OsPowerMgrProcess(VOID) /*执行低功耗管理的处理过程*/
{
#ifdef LOSCFG_KERNEL_POWER_MGR
#ifdef LOSCFG_KERNEL_POWER_MGR/*判断是否配置了内核低功耗管理*/
CALL_PMOPS_FUNC_VOID(process);
#else
if (g_pmOps == NULL) {
#ifdef LOSCFG_KERNEL_TICKLESS
OsTicklessOpen();
wfi();
wfi(); /*管理进程进入睡眠状态*/
#endif
} else {
CALL_PMOPS_FUNC_VOID(process);
CALL_PMOPS_FUNC_VOID(process);/*执行低功耗管理*/
}
#endif
}
VOID OsPowerMgrWakeUpFromInterrupt(UINT32 intNum)
VOID OsPowerMgrWakeUpFromInterrupt(UINT32 intNum) /*从中断唤醒处理*/
{
#ifdef LOSCFG_KERNEL_POWER_MGR
CALL_PMOPS_FUNC_VOID(resumeFromInterrupt, intNum);
@ -90,44 +90,44 @@ VOID OsPowerMgrWakeUpFromInterrupt(UINT32 intNum)
#endif
}
VOID OsPowerMgrWakeupFromReset(VOID)
VOID OsPowerMgrWakeupFromReset(VOID) /*从复位唤醒处理*/
{
CALL_PMOPS_FUNC_VOID(wakeupFromReset);
}
VOID LOS_PowerMgrChangeFreq(LosFreqMode freq)
VOID LOS_PowerMgrChangeFreq(LosFreqMode freq)/*改变系统频率*/
{
CALL_PMOPS_FUNC_VOID(changeFreq, freq);
}
VOID LOS_PowerMgrDeepSleepVoteBegin(VOID)
VOID LOS_PowerMgrDeepSleepVoteBegin(VOID)/*开始深度睡眠设置*/
{
CALL_PMOPS_FUNC_VOID(deepSleepVoteBegin);
}
VOID LOS_PowerMgrDeepSleepVoteEnd(VOID)
VOID LOS_PowerMgrDeepSleepVoteEnd(VOID)/*结束深度睡眠状态*/
{
CALL_PMOPS_FUNC_VOID(deepSleepVoteEnd);
}
VOID LOS_PowerMgrSleepDelay(UINT32 tick)
VOID LOS_PowerMgrSleepDelay(UINT32 tick)/*延迟进入睡眠状态*/
{
CALL_PMOPS_FUNC_VOID(deepSleepVoteDelay, tick);
}
VOID LOS_PowerMgrRegisterExtVoter(UINT32 (*callback)(VOID))
VOID LOS_PowerMgrRegisterExtVoter(UINT32 (*callback)(VOID))/*注册外部投票者*/
{
CALL_PMOPS_FUNC_VOID(registerExternalVoter, callback);
}
UINT32 LOS_PowerMgrGetSleepMode(VOID)
UINT32 LOS_PowerMgrGetSleepMode(VOID)/*获取睡眠模式*/
{
UINT32 ret = 0;
CALL_PMOPS_FUNC_RET(getSleepMode, ret);
return ret;
}
UINT32 LOS_PowerMgrGetDeepSleepVoteCount(VOID)
UINT32 LOS_PowerMgrGetDeepSleepVoteCount(VOID)/*获取深度睡眠的投票计数*/
{
UINT32 ret = 0;
CALL_PMOPS_FUNC_RET(getDeepSleepVoteCount, ret);

@ -44,7 +44,7 @@
#endif
#if defined(LOSCFG_KERNEL_RUNSTOP) || defined(LOSCFG_KERNEL_DEEPSLEEP)
/* Is system is up from the memory image, then this flag should be 1; else 0 */
/* 如果系统是从内存映像中启动的则该标志应为1否则为0。*/
#ifdef LOSCFG_AARCH64
__attribute__((section(".data"))) INT64 g_resumeFromImg = LOS_COLD_RESET;
__attribute__((section(".data"))) STATIC INT64 g_otherCoreResume = 0;
@ -55,8 +55,8 @@ __attribute__((section(".data"))) INT32 g_otherCoreResume = 0;
#ifdef LOSCFG_AARCH64
/*
* 16: The number of aligned memory,
* 34: The number of task context registers(X0~X30, SP, DAIF, NZCV)
* 16: ,
* 34: (X0~X30, SP, DAIF, NZCV)
*/
LITE_OS_SEC_DATA_MINOR __attribute__((aligned(16))) UINT64 g_saveSRContext[34];
/* 3: The number of available universal registers(X0, X1, X2) temporarily saved */
@ -161,24 +161,24 @@ STATIC PowerMgrRunOps g_pmRunOps = {
.postConfig = OsPostConfigDefault,
};
STATIC VOID OsLightSleepDefault(VOID)
STATIC VOID OsLightSleepDefault(VOID)/*轻量级睡眠函数执行wfi指令让处理器进入睡眠状态*/
{
TRACE_FUNC_CALL();
wfi();
}
STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick)
STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick)/*设置唤醒定时器,默认实现为空函数*/
{
TRACE_FUNC_CALL();
}
STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID)
STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID)/*撤销唤醒定时器默认实现返回0*/
{
TRACE_FUNC_CALL();
return 0;
}
STATIC UINT32 OsGetSleepTimeDefault(VOID)
STATIC UINT32 OsGetSleepTimeDefault(VOID)/*获取当前任务休眠时间*/
{
#ifdef LOSCFG_KERNEL_TICKLESS
return OsSleepTicksGet();
@ -187,12 +187,12 @@ STATIC UINT32 OsGetSleepTimeDefault(VOID)
#endif
}
STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)
STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)/*选择合适的休眠模式*/
{
if (sleepTicks < g_pmMgr.minSleepTicks) {
return LOS_INTERMIT_NONE;
}
/*默认实现根据休眠时间和当前系统状态选择轻量级睡眠或者深度睡眠模式*/
if (g_pmMgr.deepSleepOps != NULL && sleepTicks >= g_pmMgr.minDeepSleepTicks &&
g_pmRunOps.getDeepSleepVoteCount() == 0) {
return LOS_INTERMIT_DEEP_SLEEP;
@ -201,73 +201,73 @@ STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)
return LOS_INTERMIT_LIGHT_SLEEP;
}
STATIC VOID OsChangeFreqDefault(UINT8 freq)
STATIC VOID OsChangeFreqDefault(UINT8 freq)/*改变处理器频率*/
{
(VOID)freq;
TRACE_FUNC_CALL();
}
STATIC VOID OsEnterDeepSleepDefault(VOID)
STATIC VOID OsEnterDeepSleepDefault(VOID)// 进入深度睡眠模式函数
{
TRACE_FUNC_CALL();
wfi();
}
STATIC UINT32 OsPreConfigDefault(VOID)
STATIC UINT32 OsPreConfigDefault(VOID)//电源管理模块预配置函数
{
TRACE_FUNC_CALL();
return 1;
}
STATIC VOID OsPostConfigDefault(VOID)
STATIC VOID OsPostConfigDefault(VOID)//电源管理模块后配置函数
{
}
#ifdef LOSCFG_KERNEL_DEEPSLEEP
STATIC BOOL OsCouldDeepSleepDefault(VOID)
STATIC BOOL OsCouldDeepSleepDefault(VOID)// 判断是否可以进入深度睡眠模式
{
TRACE_FUNC_CALL();
return true;
}
STATIC BOOL OsSuspendPreConfigDefault(VOID)
STATIC BOOL OsSuspendPreConfigDefault(VOID)// 休眠前的预配置函数
{
TRACE_FUNC_CALL();
return true;
}
STATIC VOID OsSuspendDeviceDefault(VOID)
STATIC VOID OsSuspendDeviceDefault(VOID)//休眠时设备挂起函数
{
TRACE_FUNC_CALL();
}
STATIC VOID OsRollBackDefault(VOID)
STATIC VOID OsRollBackDefault(VOID)//唤醒后的回滚函数
{
TRACE_FUNC_CALL();
}
STATIC VOID OsResumeDeviceDefault(VOID)
STATIC VOID OsResumeDeviceDefault(VOID)//唤醒后的设备恢复函数
{
TRACE_FUNC_CALL();
}
STATIC VOID OsResumePostConfigDefault(VOID)
STATIC VOID OsResumePostConfigDefault(VOID)//唤醒后电源管理模块后配置函数
{
TRACE_FUNC_CALL();
}
STATIC VOID OsSystemWakeupDefault(VOID)
STATIC VOID OsSystemWakeupDefault(VOID)//系统唤醒函数
{
TRACE_FUNC_CALL();
}
STATIC VOID OsResumeCallBackDefault(VOID)
STATIC VOID OsResumeCallBackDefault(VOID)//唤醒后回调函数
{
TRACE_FUNC_CALL();
}
STATIC VOID OsOtherCoreResumeDefault(VOID)
STATIC VOID OsOtherCoreResumeDefault(VOID)//其他核心唤醒函数
{
TRACE_FUNC_CALL();
}
@ -275,18 +275,18 @@ STATIC VOID OsOtherCoreResumeDefault(VOID)
STATIC VOID OsDeepSleepResume(VOID);
STATIC PowerMgrDeepSleepOps g_deepSleepOps = {
.couldDeepSleep = OsCouldDeepSleepDefault,
.systemWakeup = OsSystemWakeupDefault,
.suspendPreConfig = OsSuspendPreConfigDefault,
.suspendDevice = OsSuspendDeviceDefault,
.rollback = OsRollBackDefault,
.resumeDevice = OsResumeDeviceDefault,
.resumePostConfig = OsResumePostConfigDefault,
.resumeCallBack = OsResumeCallBackDefault,
.otherCoreResume = OsOtherCoreResumeDefault
.couldDeepSleep = OsCouldDeepSleepDefault, //判断是否可以进入深度睡眠模式的函数指针
.systemWakeup = OsSystemWakeupDefault,//唤醒函数的函数指针
.suspendPreConfig = OsSuspendPreConfigDefault,//修面前的预配置函数的函数指针
.suspendDevice = OsSuspendDeviceDefault,//设备挂起函数的函数指针
.rollback = OsRollBackDefault,//唤醒后的回滚函数的函数指针
.resumeDevice = OsResumeDeviceDefault,//设备回复函数的函数指针
.resumePostConfig = OsResumePostConfigDefault,//唤醒后电源管理模块后配置函数的函数指针
.resumeCallBack = OsResumeCallBackDefault,//唤醒后回调函数的函数指针
.otherCoreResume = OsOtherCoreResumeDefault//其他核心唤醒函数的函数指针
};
STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)
STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)//用于更新系统始终,根据休眠时间调整系统时钟
{
UINT32 cpuid = ArchCurrCpuid();
if (sleepTicks > g_pmMgr.sleepTime[cpuid]) {
@ -297,7 +297,7 @@ STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)
OsSysTimeUpdate(sleepTicks);
}
STATIC VOID OsDeepSleepResume(VOID)
STATIC VOID OsDeepSleepResume(VOID)//深度睡眠唤醒后的处理函数
{
DEEPOPS_CALL_FUNC_VOID(resumeFromReset);
LOS_AtomicSet(&g_pmMgr.resumeSleepCores, OS_MP_CPU_ALL);
@ -305,30 +305,32 @@ STATIC VOID OsDeepSleepResume(VOID)
#ifdef LOSCFG_KERNEL_CPUP
OsSetCpuCycle(0);
#endif
//恢复设置,恢复其他核心进程
#if (LOSCFG_KERNEL_SMP == YES)
release_secondary_cores();
#endif
OsSRRestoreRegister();
}
STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)
STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)//用于主核心进入深度睡眠
{
//挂起预配置
LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1);
g_deepSleepOps.suspendPreConfig();
//是否可以进入神对睡眠判断
if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM && g_deepSleepOps.couldDeepSleep()) {
g_deepSleepOps.suspendDevice();
g_pmRunOps.setWakeUpTimer(g_pmMgr.sleepTime[0]);
g_resumeFromImg = LOS_COLD_RESET;
OsSRSaveRegister();
//进入深度睡眠,进行回滚操作,保存上下文
if (g_resumeFromImg == LOS_COLD_RESET) {
g_resumeFromImg = LOS_DEEP_SLEEP_RESET;
CALL_RUN_OPS_FUNC_NO_RETURN(contextSave);
g_pmRunOps.enterDeepSleep();
g_deepSleepOps.rollback();
}
//设置唤醒定时器
g_deepSleepOps.resumeDevice();
UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer();
OsSysTimeUpdate(sleepTicks);
@ -342,42 +344,43 @@ STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)
LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);
}
STATIC INLINE VOID OsEnterSleepMode(VOID)
STATIC INLINE VOID OsEnterSleepMode(VOID)//进入睡眠模式,包括主核心和其他核心的不同处理
{
#ifdef LOSCFG_KERNEL_SMP
UINT32 currCpuid = ArchCurrCpuid();
if (currCpuid == 0) {
if (currCpuid == 0) { //如果是0则进入主核心深度睡眠
#endif
OsEnterDeepSleepMainCore();
#ifdef LOSCFG_KERNEL_SMP
#ifdef LOSCFG_KERNEL_SMP //如果当前核心不是主核心,则直接返回,因为其他核心的睡眠处理逻辑不在此函数中处理
return;
}
UINT32 cpuMask = 1 << currCpuid;
LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1);
OsSRSaveRegister();
OsSRSaveRegister();//保存相关寄存器状态并判断是否需要唤醒当前核心。
if (g_pmMgr.resumeSleepCores & cpuMask) {
INT32 val;
do {
do { //,将 g_pmMgr.resumeSleepCores 的值中当前核心的位清零,表示该核心已被唤醒。
val = LOS_AtomicRead(&g_pmMgr.resumeSleepCores);
} while (LOS_AtomicCmpXchg32bits(&g_pmMgr.resumeSleepCores, val & (~cpuMask), val));
g_deepSleepOps.otherCoreResume();
UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer();
OsTickResume(sleepTicks);
//执行其他核心的恢复操作,并从唤醒定时器中获取休眠时间,然后调用 OsTickResume 函数更新系统时钟。
} else {
if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) {
LOS_MpSchedule(1 << 0);
if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) {//如果不需要唤醒,则判断是否所有核心都进入了深度睡眠
LOS_MpSchedule(1 << 0);//调用函数选择一个核心唤醒系统
}
#ifdef LOSCFG_KERNEL_TICKLESS
OsTicklessOpen();
OsTicklessOpen();//开启节能模式
#endif
g_pmRunOps.enterLightSleep();
}
LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);
LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);//将 g_pmMgr.deepSleepCores 的值减1表示当前核心已经处理完睡眠状态
#endif // LOSCFG_KERNEL_SMP
}
STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)
STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)//选择合适的低功耗模式(深度,轻度
{
// If enterShutdownMode is not defined, will fall through to standby mode
// If enterStandbyMode is not defined, will fall through to stop mode
@ -402,10 +405,10 @@ STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)
}
#endif
STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)
STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)//轻度睡眠中的模式调整
{
if (g_pmRunOps.preConfig != NULL) {
sleepTicks = g_pmRunOps.getSleepTime();
sleepTicks = g_pmRunOps.getSleepTime();//获取休眠时间
}
if (sleepTicks > 1) {
g_pmMgr.sleepMode[cpuid] = (mode & 0x0FF);
@ -414,18 +417,19 @@ STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)
OsTicklessOpen();
#endif
if (mode == LOS_INTERMIT_LIGHT_SLEEP && g_pmRunOps.enterLightSleep != NULL) {
g_pmRunOps.enterLightSleep();
g_pmRunOps.enterLightSleep();//进入轻度睡眠
} else {
wfi();
}
} else {
g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;
g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;//等待中断事件
g_pmMgr.sleepTime[cpuid] = 0;
wfi();
}
}
STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 sleepTicks)
//深度睡眠设置
{
#ifdef LOSCFG_KERNEL_DEEPSLEEP
if (g_pmRunOps.enterDeepSleep == NULL) {
@ -438,27 +442,31 @@ STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 slee
OsSystemSuspend(mode);
}
#else
*mode = LOS_INTERMIT_LIGHT_SLEEP;
*mode = LOS_INTERMIT_LIGHT_SLEEP;//若不支持深度睡眠则强制进入轻度睡眠
#endif
}
STATIC VOID OsLowpowerProcess(VOID)
STATIC VOID OsLowpowerProcess(VOID)//处理系统进入低功耗模式的过程
{
#ifdef LOSCFG_KERNEL_RUNSTOP
#ifdef LOSCFG_KERNEL_RUNSTOP//检查系统是否需要在进入低功耗模式前保存系统消息
if (OsWowSysDoneFlagGet() == OS_STORE_SYSTEM) {
OsStoreSystemInfoBeforeSuspend();
}
#endif
/* Change frequency is pended, need to change the freq here. */
if ((g_pmRunOps.changeFreq != NULL)) {
if ((g_pmRunOps.changeFreq != NULL)) {//如果需要改变频率则调整切换
OsChangeFreq();
}
//禁止中断锁住任务调度并获取当前CPUID和休眠时间
UINT32 intSave = LOS_IntLock();
LOS_TaskLock();
RUNOPS_CALL_FUNC_VOID(preConfig);
UINT32 cpuid = ArchCurrCpuid();
UINT32 sleepTicks = g_pmRunOps.getSleepTime();
/*如果休眠时间小于等于最小休眠时间g_pmMgr.minSleepTicks
LOS_PowerMgrGetDeepSleepVoteCount 0
CPU
postConfig */
if (sleepTicks <= g_pmMgr.minSleepTicks || LOS_PowerMgrGetDeepSleepVoteCount() != 0) {
g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;
g_pmMgr.sleepTime[cpuid] = 0;
@ -477,23 +485,23 @@ STATIC VOID OsLowpowerProcess(VOID)
sleepTicks = g_pmMgr.maxSleepCount;
}
UINT32 mode = g_pmRunOps.selectSleepMode(sleepTicks);
if (mode >= LOS_INTERMIT_DEEP_SLEEP) {
if (mode >= LOS_INTERMIT_DEEP_SLEEP) {//如果支持深度睡眠
g_pmMgr.sleepTime[cpuid] = g_pmRunOps.withdrawWakeUpTimer();
OsLowpowerDeepSleep(&mode, cpuid, sleepTicks);
}
RUNOPS_CALL_FUNC_VOID(postConfig);
if (mode < LOS_INTERMIT_DEEP_SLEEP) {
if (mode < LOS_INTERMIT_DEEP_SLEEP) {//进入轻度睡眠
OsLowpowerLightSleep(mode, cpuid, sleepTicks);
}
}
LOS_TaskUnlock();
LOS_IntRestore(intSave);
LOS_IntRestore(intSave);//解锁任务调度并恢复中断
}
STATIC VOID OsLowpowerWakeupFromReset(VOID)
STATIC VOID OsLowpowerWakeupFromReset(VOID)//处理系统从重置状态唤醒的情况
{
#ifdef LOSCFG_KERNEL_RUNSTOP
if (g_resumeFromImg == LOS_RUN_STOP_RESET) {
@ -508,7 +516,7 @@ STATIC VOID OsLowpowerWakeupFromReset(VOID)
#endif
}
STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)
STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)//用于处理系统从重置状态唤醒的情况
{
#ifdef LOSCFG_KERNEL_TICKLESS
OsTicklessUpdate(intNum);
@ -517,26 +525,27 @@ STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)
#endif
}
STATIC VOID OsChangeFreq(VOID)
STATIC VOID OsChangeFreq(VOID)//处理改变系统频率的操作
{
UINT32 freq;
BOOL ret;
do {
do {//尝试获取频率切换的自旋锁(通过原子操作实现)
//如果成功获取锁,则说明没有其他线程正在频率切换过程中,可以继续执行
ret = LOS_AtomicCmpXchg32bits(&g_pmMgr.freeLock, LOCK_ON, LOCK_OFF);
if (ret) {
return;
}
freq = (UINT32)g_pmMgr.freqPending;
freq = (UINT32)g_pmMgr.freqPending;//获取频率切换的目标频率,并进行频率切换
if (freq != (UINT32)g_pmMgr.freq) {
g_pmRunOps.changeFreq(freq);
g_pmRunOps.changeFreq(freq);//更新频率
LOS_AtomicSet(&g_pmMgr.freq, (INT32)freq);
}
LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);
LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);//释放自旋锁
} while (FreqHigher(g_pmMgr.freqPending, freq));
}
STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)
STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)//改变系统频率
{
TRACE_FUNC_CALL();
if (g_pmRunOps.changeFreq == NULL) {
@ -554,36 +563,36 @@ STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)
// We get a high frequency request, then change it
if (FreqHigher(g_pmMgr.freqPending, g_pmMgr.freq) && g_pmRunOps.changeFreq != NULL) {
OsChangeFreq();
OsChangeFreq();//如果目标频率高于当前频率,并且 g_pmRunOps.changeFreq 不为空,则调用 OsChangeFreq 函数进行频率切换。
}
}
STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID)
STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID)//开始深度睡眠投票
{
TRACE_FUNC_CALL();
LOS_AtomicInc(&g_pmMgr.sleepVoteCount);
LOS_AtomicInc(&g_pmMgr.sleepVoteCount);//用原子操作将 g_pmMgr.sleepVoteCount 加一,并断言 g_pmMgr.sleepVoteCount 大于零。
LOS_ASSERT(g_pmMgr.sleepVoteCount > 0);
}
STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID)
STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID)//结束深度睡眠投票
{
TRACE_FUNC_CALL();
LOS_AtomicDec(&g_pmMgr.sleepVoteCount);
LOS_AtomicDec(&g_pmMgr.sleepVoteCount);//原子操作将 g_pmMgr.sleepVoteCount 减一,并断言 g_pmMgr.sleepVoteCount 大于等于零。
LOS_ASSERT(g_pmMgr.sleepVoteCount >= 0);
}
STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks)
STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks)//延迟深度睡眠投票
{
TRACE_FUNC_CALL();
}
STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback)
STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback)//注册外部投票者
{
TRACE_FUNC_CALL();
g_pmMgr.exVoterHandle = callback;
}
STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)
STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)//获取深度睡眠投票数
{
if (g_pmMgr.exVoterHandle == NULL) {
return (UINT32)g_pmMgr.sleepVoteCount;
@ -593,22 +602,26 @@ STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)
}
STATIC PowerMgrOps g_pmOps = {
.process = OsLowpowerProcess,
.wakeupFromReset = OsLowpowerWakeupFromReset,
.resumeFromInterrupt = OsLowpowerWakeupFromInterrupt,
.changeFreq = OsLowpowerChangeFreq,
.deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin,
.deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd,
.deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay,
.registerExternalVoter = OsLowpowerRegisterExternalVoter,
.getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount,
.getSleepMode = NULL,
.setSleepMode = NULL,
.process = OsLowpowerProcess, //该函数指针用于处理低功耗过程,即在进入低功耗模式前需要执行的操作
.wakeupFromReset = OsLowpowerWakeupFromReset,//该函数指针用于处理从复位状态唤醒时的操作
.resumeFromInterrupt = OsLowpowerWakeupFromInterrupt,//该函数指针用于处理从中断状态恢复时的操作。
.changeFreq = OsLowpowerChangeFreq,//该函数指针用于改变系统频率的操作,可以根据需要调整系统的工作频率
.deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin,//该函数指针用于开始深度休眠投票,即在进入深度休眠模式前需要执行的操作
.deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd,//该函数指针用于结束深度休眠投票,即在退出深度休眠模式后需要执行的操作
.deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay,//该函数指针用于处理深度休眠投票延迟的操作,可以根据需要延迟深度休眠的投票
.registerExternalVoter = OsLowpowerRegisterExternalVoter,//该函数指针用于注册外部投票者,即在系统中存在其他模块也需要参与低功耗投票时的操作
.getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount,//该函数指针用于获取当前深度休眠投票的数量,可以用来监控系统中参与休眠投票的模块数量
.getSleepMode = NULL,//该函数指针用于获取当前的睡眠模式,即获取系统当前是否处于睡眠状态
.setSleepMode = NULL,//该函数指针用于设置睡眠模式,即将系统设置为指定的睡眠模式
//以上提及的函数均为函数指针
};
#define FORCE_NULL_CALLBACK (void *)0x3f3f3f3f
#define ASSIGN_MEMBER(lhs, rhs, member) \
//以下定义是用于给结构体成员赋值,如果某个回调函数指针为特殊空值,则将相应的成员置为空,否则进行赋值
#define ASSIGN_MEMBER(lhs, rhs, member)
//lhs 是左操作数,表示要赋值的结构体指针;
//rhs 是右操作数,表示要赋给成员的值;
//member 是要赋值的结构体成员
do { \
if ((rhs)->member == FORCE_NULL_CALLBACK) { \
(lhs)->member = NULL; \
@ -631,16 +644,16 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
const PowerMgrRunOps *runOps = NULL;
const PowerMgrDeepSleepOps *deepSleepOps = NULL;
(void)deepSleepOps;
if (para != NULL) {
if (para != NULL) { //如果para为空则运行操作和深度睡眠操作都为空指针
runOps = &para->runOps;
#ifdef LOSCFG_KERNEL_DEEPSLEEP
deepSleepOps = &para->deepSleepOps;
#endif
g_pmMgr.minSleepTicks = para->config.minLightSleepTicks;
g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks;
g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks;
g_pmMgr.minSleepTicks = para->config.minLightSleepTicks;//记录了系统中需要从睡眠状态唤醒的 CPU 核心数
g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks;//用于保护电源管理模块在多线程环境下的并发访问
g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks;//记录自旋锁是否被释放
}
//将传入的运行操作和深度睡眠操作分别赋值给全局变量 g_pmRunOps 和 g_deepSleepOps
LOS_AtomicSet(&g_pmMgr.resumeSleepCores, 0);
LOS_SpinInit(&g_pmMgr.lock);
@ -648,25 +661,25 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
// verify and assign input operators.
if (runOps != NULL) {
ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq);
ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep);
ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq);//改变CPU频率
ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep);//进入浅度睡眠
#ifdef LOSCFG_KERNEL_DEEPSLEEP
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep);
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer);
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer);
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep);//进入深度睡眠
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer);//设置唤醒定时器
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer);//撤销定时器
#else
ASSIGN_MEMBER(&g_pmRunOps, runOps, enterDeepSleep);
ASSIGN_MEMBER(&g_pmRunOps, runOps, setWakeUpTimer);
ASSIGN_MEMBER(&g_pmRunOps, runOps, withdrawWakeUpTimer);
#endif
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime);
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode);
ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig);
ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig);
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime);//货的睡眠时间
ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode);//选择不同的睡眠模式
ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig);//预配置
ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig);//后配置
}
#ifdef LOSCFG_KERNEL_DEEPSLEEP
if (deepSleepOps != NULL) {
if (deepSleepOps != NULL) {//进入深度睡眠
ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, couldDeepSleep);
ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, systemWakeup);
ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, suspendPreConfig);
@ -680,4 +693,7 @@ VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
#endif
// Register PowerMgr to Low-Power Framework.
LOS_LowpowerInit(&g_pmOps);
//将电源管理模块注册到低功耗框架中。
//低功耗框架是一个用于管理处理器和设备进入低功耗模式的软件框架,
//它能够最大限度地降低系统能耗,提高系统的电池寿命
}

@ -51,22 +51,28 @@ extern "C" {
/* If core is ready for imaging */
LITE_OS_SEC_DATA_MINOR STATIC UINT32 g_sysDoneFlag[LOSCFG_KERNEL_CORE_NUM] = {
[0 ... (LOSCFG_KERNEL_CORE_NUM - 1)] = OS_NO_STORE_SYSTEM
};
}; /*标记数组状态,用来表示系统是否加载完成*/
/* Start position of flash to write image */
LITE_OS_SEC_DATA_MINOR STATIC UINTPTR g_flashImgAddr;
/*flash图像地址和大小用于存储flash相关信息。*/
/* Start position of heap memory after carry the image from flash to memory */
LITE_OS_SEC_DATA_MINOR STATIC const VOID *g_heapMemStart = NULL;
/*初始化图像地址*/
/* Size of heap memory in image */
LITE_OS_SEC_DATA_MINOR STATIC size_t g_heapMemSize = 0;
/*初始化定义图像大小*/
#ifdef LOSCFG_EXC_INTERACTION
/* Start position of exc interaction heap memory after carry the image from flash to memory */
LITE_OS_SEC_DATA_MINOR STATIC const VOID *g_excInteractionMemStart = NULL;
/*在存储器映像从闪存复制到内存之后异常交互堆的起始位置变量*/
/* Size of exc interaction heap memory in image */
LITE_OS_SEC_DATA_MINOR STATIC size_t g_excInteractionMemSize = 0;
/*异常交互堆内存在储存器映像中的大小*/
#endif
/* Size of wow image */
LITE_OS_SEC_DATA_MINOR STATIC size_t g_wowImgSize = 0;
@ -76,15 +82,17 @@ LITE_OS_SEC_DATA_MINOR STATIC EVENT_CB_S g_suspendResumeEvent;
LITE_OS_SEC_DATA_MINOR STATIC EVENT_CB_S g_writeFlashEvent;
typedef struct {
UINTPTR memStart;
UINTPTR flashStart;
size_t memSize;
UINTPTR memStart; /*内存起始地址*/
UINTPTR flashStart; /*闪存起始地址*/
size_t memSize; /*存储空间大小*/
} FlashWriteParam;
BOOL IsImageResume(VOID)
{
return (g_resumeFromImg != LOS_COLD_RESET);
}
/*判断系统是否从存储器映像中恢复的,功能是当系统异常启动或者需要重启的时候就会从内存将其数据保存到闪存中
*/
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsDoWriteWow2Flash(FLASH_WRITE_FUNC flashWriteFunc,
const FlashWriteParam *wowSection,
@ -109,29 +117,32 @@ LITE_OS_SEC_TEXT_MINOR STATIC VOID OsDoWriteWow2Flash(FLASH_WRITE_FUNC flashWrit
return;
}
}
LITE_OS_SEC_TEXT_MINOR VOID OsWriteWow2Flash(VOID)
/*首先检查内存中的大小是否为0
0wowsectionexcheapsectionheapmemsection*/
LITE_OS_SEC_TEXT_MINOR VOID OsWriteWow2Flash(VOID) /*根据指定的内存区域,在闪存中写入相应的数据,完成写入操作*/
{
FlashWriteParam wowSection;
FlashWriteParam excHeapSection = {0};
FlashWriteParam heapMemSection;
size_t eraseAlignSize;
size_t writeAlignSize;
FlashWriteParam heapMemSection; /*这是三种闪存内部独立的堆专用的内存区域对应的闪存写入参数*/
size_t eraseAlignSize; /*表示闪存擦除时的对齐大小*/
size_t writeAlignSize; /*闪存写入时的对齐大小*/
FLASH_WRITE_FUNC flashWriteFunc = g_runstopParam.pfFlashWriteFunc;
eraseAlignSize = g_runstopParam.uwFlashEraseAlignSize;
writeAlignSize = g_runstopParam.uwFlashWriteAlignSize;
eraseAlignSize = g_runstopParam.uwFlashEraseAlignSize; /*用来指定擦除和写入时的对齐大小,通常设置为扇区大小的整数倍*/
writeAlignSize = g_runstopParam.uwFlashWriteAlignSize; /*为了避免出现擦除或写入不规则数据的情况,
*/
writeAlignSize = (writeAlignSize >= eraseAlignSize) ? writeAlignSize : eraseAlignSize;
if (flashWriteFunc == NULL) {
PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
return;
}
wowSection.memStart = (UINTPTR)&__ram_vectors_vma;
wowSection.flashStart = g_flashImgAddr;
wowSection.memStart = (UINTPTR)&__ram_vectors_vma;/*初始化wowSection为内存中起始地址*/
wowSection.flashStart = g_flashImgAddr; /*为闪存中起始地址*/
wowSection.memSize = ((UINTPTR)&__wow_end) - ((UINTPTR)&__ram_vectors_vma);
wowSection.memSize = (wowSection.memSize + writeAlignSize - 1) & ~(writeAlignSize - 1);
/*计算了wowSection大小通过与运算保证每次写入的数据都是整个扇区的倍数*/
#ifdef LOSCFG_EXC_INTERACTION
excHeapSection.memStart = (UINTPTR)m_aucSysMem0;
excHeapSection.flashStart = g_flashImgAddr + wowSection.memSize;
@ -152,39 +163,41 @@ LITE_OS_SEC_TEXT_MINOR VOID OsWriteWow2Flash(VOID)
g_wowImgSize = wowSection.memSize + heapMemSection.memSize + excHeapSection.memSize;
OsDoWriteWow2Flash(flashWriteFunc, &wowSection, &excHeapSection, &heapMemSection);
/*将变量传输给函数,由其实现相应的写入操作*/
}
LITE_OS_SEC_TEXT_MINOR VOID OsSystemSuspend(VOID)
LITE_OS_SEC_TEXT_MINOR VOID OsSystemSuspend(VOID) /*实现系统的挂起操作*/
{
UINT32 cpuid;
UINT32 cpuid; /*获取当前CPU的ID*/
(VOID)LOS_IntLock();
LOS_TaskLock();
cpuid = ArchCurrCpuid();
/*禁止中断并锁定任务调度器,确保在执行挂起操作期间不会被打断*/
g_sysDoneFlag[cpuid] = OS_NO_STORE_SYSTEM; /*将当前CPU的系统挂起标志设置为不需要保存系统状态*/
g_saveTsk[cpuid] = OsCurrTaskGet(); /*保存当前任务指针到savetask变量中*/
g_sysDoneFlag[cpuid] = OS_NO_STORE_SYSTEM;
g_saveTsk[cpuid] = OsCurrTaskGet();
OsSRSaveRegister();
OsSRSaveRegister(); /*保存当前CPU的寄存器状态以便在恢复系统时能够正确恢复到挂起前的状态*/
/* If 1 core, only to save registers */
if (cpuid != 0) {
if (g_otherCoreResume != 0) {
if (cpuid != 0) { /*若此CPU部位0号内核*/
if (g_otherCoreResume != 0) { /*说明其他多核核心需要恢复运行*/
HalIrqInitPercpu();
OsTickStart();
LOS_TaskUnlock();
(VOID)LOS_IntUnLock();
return;
}
g_sysDoneFlag[cpuid - 1] = OS_STORE_SYSTEM;
g_sysDoneFlag[cpuid - 1] = OS_STORE_SYSTEM; /*需要初始化中断并启动系统时钟,并最终解锁任务调度器并恢复中断*/
while (1) {}
}
if (g_resumeFromImg) {
if (g_resumeFromImg) { /*如果是 0 号 CPU且系统需要从镜像中恢复g_resumeFromImg 为真)*/
OsWriteWow2Flash();
LOS_TaskUnlock();
(VOID)LOS_IntUnLock();
(VOID)LOS_EventWrite(&g_suspendResumeEvent, FLASH_IMG_SUCCESS);
} else {
/*调用 OsWriteWow2Flash 函数将数据写入闪存,并发送 FLASH_IMG_SUCCESS 事件信号,表示成功从镜像中恢复*/
} else { /*不需要从镜像中恢复*/
OsTickStart();
LOS_TaskUnlock();
(VOID)LOS_IntUnLock();
@ -194,9 +207,15 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemSuspend(VOID)
}
(VOID)LOS_EventWrite(&g_suspendResumeEvent, WAKEUP_FROM_SUSPEND);
}
/*启动系统时钟,解锁任务调度器和中断,并根据是否设置了空闲唤醒回调函数来执行相应的操作,
WAKEUP_FROM_SUSPEND */
}
LITE_OS_SEC_TEXT VOID OsWriteToFlashTask(VOID)
/*初始化了一个事件对象 g_writeFlashEvent
LOS_EventRead
OR 0x01
OsSystemSuspend */
{
(VOID)LOS_EventInit(&g_writeFlashEvent);
@ -207,6 +226,10 @@ LITE_OS_SEC_TEXT VOID OsWriteToFlashTask(VOID)
}
LITE_OS_SEC_TEXT VOID OsStoreSystemInfoBeforeSuspend(VOID)
/*根据当前 CPU 的 ID 判断是否需要挂起系统。
CPU 0 CPU OsSystemSuspend
0 CPU LOS_EventWrite g_writeFlashEvent
OsWriteToFlashTask */
{
UINT32 cpuid = ArchCurrCpuid();
if (cpuid != 0) {
@ -218,6 +241,9 @@ LITE_OS_SEC_TEXT VOID OsStoreSystemInfoBeforeSuspend(VOID)
}
LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID)
/*是系统从挂起状态唤醒后的处理函数。*/
{
UINT32 cpuid;
errno_t err;
@ -225,7 +251,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID)
if (!g_resumeFromImg) {
return;
}
/*进行一些内存数据的复制操作,然后设置当前 CPU 的任务指针,*/
#ifdef LOSCFG_EXC_INTERACTION
err = memmove_s(m_aucSysMem0, g_excInteractMemSize, g_excInteractionMemStart, g_excInteractionMemSize);
if (err != EOK) {
@ -243,6 +269,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID)
cpuid = ArchCurrCpuid();
OsCurrTaskSet(g_saveTsk[cpuid]);
/*设置系统计数器频率。接着,它重置内存池的末尾节点,清零 BSS 区域的数据,重新初始化中断*/
/* Set system counter freq */
HalClockFreqWrite(OS_SYS_CLOCK);
dsb();
@ -270,7 +297,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsSystemWakeup(VOID)
#ifdef LOSCFG_KERNEL_CPUP
OsSetCpuCycle(0);
#endif
/*并调用 OsSRRestoreRegister 函数恢复寄存器状态*/
#if (LOSCFG_KERNEL_SMP == YES)
release_secondary_cores();
#endif
@ -281,32 +308,33 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsWaitImagingDone(UINTPTR wowFlashAddr, size_t *wo
{
UINT32 ret;
g_flashImgAddr = wowFlashAddr;
(VOID)LOS_EventInit(&g_suspendResumeEvent);
g_flashImgAddr = wowFlashAddr; /*烧录的flash地址*/
(VOID)LOS_EventInit(&g_suspendResumeEvent); /*指向用于存储烧录镜像大小的变量的指针*/
// This flag will be stored into flash, and will affect the wakeup procedure when cpu is rebooting.
// 这个标志将被存储到闪存中,当 CPU 重新启动时,它将影响唤醒流程。
g_resumeFromImg = LOS_RUN_STOP_RESET;
// This flag affects the suspending procedure later,
// and will be reset depending on 'g_resumeFromImg' when cpu is rebooting.
// 这个标志会影响之后的挂起过程,并且在 CPU 重新启动时根据 'g_resumeFromImg' 的值进行重置
g_otherCoreResume = 0;
g_sysDoneFlag[LOSCFG_KERNEL_CORE_NUM - 1] = OS_STORE_SYSTEM;
g_sysDoneFlag[LOSCFG_KERNEL_CORE_NUM - 1] = OS_STORE_SYSTEM; /*表示系统状态需要被保存*/
ret = LOS_EventRead(&g_suspendResumeEvent, 0xFF, LOS_WAITMODE_OR | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER);
/*等待事件发生*/
if (wowImgSize != NULL) {
*wowImgSize = g_wowImgSize;
}
}/*保证能够在烧录完成之后正确的保存和恢复状态*/
return ret;
}
LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID)
LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID) /*将位于RAM的数据从指定位置复制到Flash存储器中*/
{
size_t size;
UINTPTR memAddr;
size_t wowSize;
size_t readAlignSize;
size_t eraseAlignSize;
size_t writeAlignSize;
size_t wowSize;/*等待复制数据的大小*/
size_t readAlignSize;/*读取对齐大小*/
size_t eraseAlignSize;/*擦除对齐大小*/
size_t writeAlignSize;/*写入对齐大小*/
/*读取所有参数的初始状态*/
UINTPTR imageFlashAddr;
FLASH_READ_FUNC flashReadFunc = g_runstopParam.pfFlashReadFunc;
@ -315,18 +343,19 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID)
eraseAlignSize = g_runstopParam.uwFlashEraseAlignSize;
writeAlignSize = g_runstopParam.uwFlashWriteAlignSize;
writeAlignSize = (writeAlignSize >= eraseAlignSize) ? writeAlignSize : eraseAlignSize;
/*计算wowsize的大小根据对齐大小调整值*/
wowSize = ((UINTPTR)&__wow_end) - ((UINTPTR)&__ram_vectors_vma);
wowSize = (wowSize + writeAlignSize - 1) & ~(writeAlignSize - 1);
imageFlashAddr += wowSize;
/*检查memaddr是否超出了BSS段的起始地址*/
memAddr = ((UINTPTR)&__ram_vectors_vma) + wowSize;
if (memAddr >= ((UINTPTR)&__bss_start)) {
return;
}
/*计算了要复制的数据大小在磁盘中根据对齐大小调整size*/
size = ((UINTPTR)&__int_stack_start) - memAddr;
size = (size + readAlignSize - 1) & ~(readAlignSize - 1);
/*将RAM中的数据从memaddr复制到flash存储器的imageflashaddr进行缓存和同步操作*/
if ((flashReadFunc != NULL) && (flashReadFunc((VOID *)memAddr, imageFlashAddr, size) != 0)) {
PRINT_ERR("%s, %d\n", __FUNCTION__, __LINE__);
}
@ -336,6 +365,8 @@ LITE_OS_SEC_TEXT_MINOR VOID OsCarryLeftScatter(VOID)
}
LITE_OS_SEC_TEXT_MINOR VOID OsRunstopParamInit(const RUNSTOP_PARAM_S *runstopParam)
/*初始化运行暂停功能所需的参数保存在全局变量g_中以便告诉计算机目前的系统转台
*/
{
g_runstopParam.pfIdleWakeupCallback = runstopParam->pfIdleWakeupCallback;
g_runstopParam.pfWakeupCallback = runstopParam->pfWakeupCallback;
@ -350,28 +381,31 @@ LITE_OS_SEC_TEXT_MINOR VOID OsRunstopParamInit(const RUNSTOP_PARAM_S *runstopPar
}
LITE_OS_SEC_TEXT_MINOR VOID LOS_MakeImage(RUNSTOP_PARAM_S *runstopParam)
/*用于除法运行暂停功能的操作,并根据返回值进行相应处理*/
{
UINT32 ret;
size_t imgSize;
/*检查是否需要暂停*/
if (runstopParam == NULL) {
return;
}
/*调用函数将传入的runstopparam转换为全局变量*/
OsRunstopParamInit(runstopParam);
ret = OsWaitImagingDone(g_runstopParam.uwWowFlashAddr, &imgSize);
if (ret == WAKEUP_FROM_SUSPEND) {
/*用于等待图像转移完成范围相应的状态码ret和图像大小imgsize*/
if (ret == WAKEUP_FROM_SUSPEND) { /*从暂停状态唤醒,并查看系统是否需要空闲唤醒回调*/
if (g_runstopParam.pfWakeupCallback != NULL) {
g_runstopParam.pfWakeupCallback();
}
OsCarryLeftScatter();
OsCarryLeftScatter(); /*将RAM中的数据复制到Flash存储器*/
PRINT_INFO("Resume ok!\n");
} else if (ret == FLASH_IMG_SUCCESS) {
} else if (ret == FLASH_IMG_SUCCESS) { /*闪存图像成功*/
if (g_runstopParam.pfImageDoneCallback != NULL) {
g_runstopParam.pfImageDoneCallback();
}
PRINT_INFO("Flash ok! Image length 0x%x\n", imgSize);
PRINT_INFO("Flash ok! Image length 0x%x\n", imgSize);/*图像转移成功,并打印图像大小*/
}
}
@ -380,8 +414,9 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsWowWriteFlashTaskCreate(VOID)
UINT32 ret;
UINT32 writeFlashTaskId;
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)OsWriteToFlashTask;
taskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
taskInitParam.pcName = "WowWriteFlashTask";
@ -389,24 +424,28 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsWowWriteFlashTaskCreate(VOID)
#ifdef LOSCFG_KERNEL_SMP
taskInitParam.usCpuAffiMask = CPUID_TO_AFFI_MASK(0);
#endif
/*创建任务,返回结果*/
ret = LOS_TaskCreate(&writeFlashTaskId, &taskInitParam);
return ret;
}
LITE_OS_SEC_TEXT_MINOR size_t OsWowImageSizeGet(VOID)
/*获取wow图像的大小返回全局变量*/
{
return g_wowImgSize;
}
LITE_OS_SEC_TEXT_MINOR UINT32 OsWowSysDoneFlagGet(VOID)
/*获取wow系统完成的标志*/
{
UINT32 cpuid = ArchCurrCpuid();
return g_sysDoneFlag[cpuid];
}
LITE_OS_SEC_TEXT_MINOR VOID OsWowOtherCoreResume(UINT32 cpuid)
/*唤醒其他的核心*/
{
if (g_otherCoreResume == 1) {
if (g_otherCoreResume == 1) { /*全局变量的值为1则表示需要唤醒其他核心*/
OsCurrTaskSet(g_saveTsk[cpuid]);
OsSRRestoreRegister();
}

@ -46,17 +46,18 @@ STATIC volatile UINT32 g_sleepTicks[LOSCFG_KERNEL_CORE_NUM] = {0};
(((GET_SYS_CLOCK()) / (g_tickPerSecond)) - (cyclesCur)) : \
((((GET_SYS_CLOCK()) / (g_tickPerSecond)) << 1) - (cyclesCur)))
LITE_OS_SEC_TEXT VOID LOS_TicklessEnable(VOID)
LITE_OS_SEC_TEXT VOID LOS_TicklessEnable(VOID) /*开启Tickless功能*/
{
g_ticklessFlag = TRUE;
/*变量表示Tickless功能的开启状态为TRUE表示已开启为FALSE表示已关闭。*/
}
LITE_OS_SEC_TEXT VOID LOS_TicklessDisable(VOID)
LITE_OS_SEC_TEXT VOID LOS_TicklessDisable(VOID) /*开启Tickless功能*/
{
g_ticklessFlag = FALSE;
}
LITE_OS_SEC_TEXT BOOL OsTicklessFlagGet(VOID)
LITE_OS_SEC_TEXT BOOL OsTicklessFlagGet(VOID) /*用于获取Tickless标志的状态*/
{
return g_ticklessFlag;
}
@ -64,24 +65,27 @@ LITE_OS_SEC_TEXT BOOL OsTicklessFlagGet(VOID)
LITE_OS_SEC_TEXT BOOL OsTickIrqFlagGet(VOID)
{
return g_tickIrqFlag[ArchCurrCpuid()];
/*数组表示每个核心的Tick中断标志的状态
TRUEFALSE*/
}
LITE_OS_SEC_TEXT VOID OsTickIrqFlagSet(BOOL tickIrqFlag)
LITE_OS_SEC_TEXT VOID OsTickIrqFlagSet(BOOL tickIrqFlag) /*用于设置当前核心的时钟中断标志*/
{
g_tickIrqFlag[ArchCurrCpuid()] = tickIrqFlag;
}
LITE_OS_SEC_TEXT UINT32 OsTicklessSleepTickGet(VOID)
LITE_OS_SEC_TEXT UINT32 OsTicklessSleepTickGet(VOID) /*用于获取当前系统的睡眠计时器的数值*/
{
return g_sleepTicks[ArchCurrCpuid()];
}
LITE_OS_SEC_TEXT VOID OsTicklessSleepTickSet(UINT32 sleeptick)
LITE_OS_SEC_TEXT VOID OsTicklessSleepTickSet(UINT32 sleeptick) /*设置当前核心得到睡眠计时器的数值*/
{
g_sleepTicks[ArchCurrCpuid()] = sleeptick;
}
LITE_OS_SEC_TEXT UINT32 OsSleepTicksGet(VOID)
LITE_OS_SEC_TEXT UINT32 OsSleepTicksGet(VOID) /*函数用于获取当前需要休眠的ticks数通过查询任务链表和软件定时器链表
*/
{
UINT32 tskSortLinkTicks, sleepTicks;
@ -104,7 +108,8 @@ LITE_OS_SEC_TEXT UINT32 OsSleepTicksGet(VOID)
return sleepTicks;
}
LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks)
LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks) /*用于更新系统时间,
*/
{
UINT32 intSave;
@ -127,7 +132,7 @@ LITE_OS_SEC_TEXT VOID OsSysTimeUpdate(UINT32 sleepTicks)
LOS_IntRestore(intSave);
}
VOID OsTicklessUpdate(UINT32 irqnum)
VOID OsTicklessUpdate(UINT32 irqnum) /*OsTicklessUpdate函数用于在发生中断时更新系统时间*/
{
UINT32 cycles, ticks;
UINT32 cyclesPertick;
@ -165,7 +170,8 @@ VOID OsTicklessUpdate(UINT32 irqnum)
LOS_IntRestore(intSave);
}
VOID OsTicklessStart(VOID)
VOID OsTicklessStart(VOID) /*Tickless模式的入口函数根据休眠时长计算需要延迟的周期数
Tickless*/
{
UINT32 intSave;
/*
@ -202,7 +208,8 @@ VOID OsTicklessStart(VOID)
return;
}
VOID OsTicklessOpen(VOID)
VOID OsTicklessOpen(VOID) /*在Tick中断处理函数中开启Tickless模式。
TickTickless1Tickless*/
{
if (OsTickIrqFlagGet()) {
OsTickIrqFlagSet(0);

@ -37,10 +37,11 @@ extern "C" {
#endif /* __cplusplus */
#ifdef LOSCFG_KERNEL_PERF
STATIC Pmu *g_pmu = NULL;
STATIC PerfCB g_perfCb = {0};
STATIC Pmu *g_pmu = NULL;//用于保存当前系统中所使用的硬件性能计数器
STATIC PerfCB g_perfCb = {0};//保存了性能测量回调函数和一些测量结果数据
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_perfSpin);
//定义了一个自旋锁 g_perfSpin用于保护性能测量模块在多线程环境下的并发访问
#define PERF_LOCK(state) LOS_SpinLockSave(&g_perfSpin, &(state))
#define PERF_UNLOCK(state) LOS_SpinUnlockRestore(&g_perfSpin, (state))
@ -55,8 +56,9 @@ STATIC INLINE UINT64 OsPerfGetCurrTime(VOID)
#endif
}
STATIC UINT32 OsPmuInit(VOID)
STATIC UINT32 OsPmuInit(VOID)//初始化性能计数器
{
//判断是否开启了计数器
#ifdef LOSCFG_PERF_HW_PMU
if (OsHwPmuInit() != LOS_OK) {
return LOS_ERRNO_PERF_HW_INIT_ERROR;
@ -77,13 +79,13 @@ STATIC UINT32 OsPmuInit(VOID)
return LOS_OK;
}
STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg)
STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg)//配置性能计数器
{
UINT32 i;
UINT32 ret;
g_pmu = OsPerfPmuGet(eventsCfg->type);
if (g_pmu == NULL) {
if (g_pmu == NULL) {//根据配置的类型获取对应的性能计数器对象
PRINT_ERR("perf config type error %u!\n", eventsCfg->type);
return LOS_ERRNO_PERF_INVALID_PMU;
}
@ -92,6 +94,7 @@ STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg)
(VOID)memset_s(&g_pmu->events, sizeof(PerfEvent), 0, sizeof(PerfEvent));
//根据配置信息设置各性能事件的参数,调用性能计数器对象的配置函数进行配置
for (i = 0; i < eventNum; i++) {
g_pmu->events.per[i].eventId = eventsCfg->events[i].eventId;
g_pmu->events.per[i].period = eventsCfg->events[i].period;
@ -109,13 +112,13 @@ STATIC UINT32 OsPerfConfig(PerfEventConfig *eventsCfg)
return LOS_OK;
}
STATIC VOID OsPerfPrintCount(VOID)
STATIC VOID OsPerfPrintCount(VOID)//用于打印性能计数器的统计信息
{
UINT32 index;
UINT32 intSave;
UINT32 cpuid = ArchCurrCpuid();
PerfEvent *events = &g_pmu->events;
PerfEvent *events = &g_pmu->events;//获取性能计数器对象的性能时间数组和事件数量
UINT32 eventNum = events->nr;
PERF_LOCK(intSave);
@ -123,7 +126,7 @@ STATIC VOID OsPerfPrintCount(VOID)
Event *event = &(events->per[index]);
/* filter out event counter with no event binded. */
if (event->period == 0) {
if (event->period == 0) { //事件周期
continue;
}
PRINT_EMG("[%s] eventType: 0x%x [core %u]: %llu\n", g_pmu->getName(event), event->eventId, cpuid,
@ -132,7 +135,7 @@ STATIC VOID OsPerfPrintCount(VOID)
PERF_UNLOCK(intSave);
}
STATIC INLINE VOID OsPerfPrintTs(VOID)
STATIC INLINE VOID OsPerfPrintTs(VOID)//打印时间信息
{
#ifdef LOSCFG_PERF_CALC_TIME_BY_TICK
DOUBLE time = (g_perfCb.endTime - g_perfCb.startTime) * 1.0 / LOSCFG_BASE_CORE_TICK_PER_SECOND;
@ -142,7 +145,7 @@ STATIC INLINE VOID OsPerfPrintTs(VOID)
PRINT_EMG("time used: %.6f(s)\r\n", time);
}
STATIC VOID OsPerfStart(VOID)
STATIC VOID OsPerfStart(VOID)//启动及更新CPU和计数器状态
{
UINT32 cpuid = ArchCurrCpuid();
@ -152,7 +155,7 @@ STATIC VOID OsPerfStart(VOID)
}
if (g_perfCb.pmuStatusPerCpu[cpuid] != PERF_PMU_STARTED) {
UINT32 ret = g_pmu->start();
UINT32 ret = g_pmu->start();//若计数器未启动则启动
if (ret != LOS_OK) {
PRINT_ERR("perf start on core:%u failed, ret = 0x%x\n", cpuid, ret);
return;
@ -164,7 +167,7 @@ STATIC VOID OsPerfStart(VOID)
}
}
STATIC VOID OsPerfStop(VOID)
STATIC VOID OsPerfStop(VOID)//停止性能计数器
{
UINT32 cpuid = ArchCurrCpuid();
@ -191,19 +194,21 @@ STATIC VOID OsPerfStop(VOID)
}
STATIC UINT32 OsPerfBackTrace(UINTPTR *callChain, UINT32 maxDepth, PerfRegs *regs)
//获取当前函数调用链的信息,并将结果存储在 callChain 数组中
{
UINT32 i;
UINT32 count = ArchBackTraceGet(regs->fp, callChain, maxDepth);
UINT32 count = ArchBackTraceGet(regs->fp, callChain, maxDepth);//获取当前状态的帧指针值
PRINT_DEBUG("backtrace depth = %u, fp = 0x%x\n", count, regs->fp);
for (i = 0; i < count; i++) {
PRINT_DEBUG("ip[%u]: 0x%x\n", i, callChain[i]);
PRINT_DEBUG("ip[%u]: 0x%x\n", i, callChain[i]);//打印调用链中每个函数的指令地址
}
return count;
return count;//返回用链的深度
}
STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *regs)
//收集性能计数器的数据,并将其存储在 data 结构体中
{
UINT32 size = 0;
UINT32 depth;
@ -211,12 +216,12 @@ STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *re
CHAR *p = (CHAR *)data;
if (sampleType & PERF_RECORD_CPU) {
*(UINT32 *)(p + size) = ArchCurrCpuid();
*(UINT32 *)(p + size) = ArchCurrCpuid();//函数获取当前CPU的ID并存储在 data->cpuid 字段中
size += sizeof(data->cpuid);
}
if (sampleType & PERF_RECORD_TID) {
*(UINT32 *)(p + size) = LOS_CurTaskIDGet();
*(UINT32 *)(p + size) = LOS_CurTaskIDGet();// 函数获取当前任务的ID并存储在 data->taskId 字段中
size += sizeof(data->taskId);
}
@ -231,7 +236,7 @@ STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *re
}
if (sampleType & PERF_RECORD_TIMESTAMP) {
*(UINT64 *)(p + size) = OsPerfGetCurrTime();
*(UINT64 *)(p + size) = OsPerfGetCurrTime();//获取当前时间戳,并存储在 data->time 字段中
size += sizeof(data->time);
}
@ -254,7 +259,7 @@ STATIC UINT32 OsPerfCollectData(Event *event, PerfSampleData *data, PerfRegs *re
* return TRUE if user haven't specified any taskId(which is supposed
* to instrument the whole system)
*/
STATIC BOOL OsPerfTaskFilter(UINT32 taskId)
STATIC BOOL OsPerfTaskFilter(UINT32 taskId)//过滤任务ID判断一个给定的任务ID是否需要进行性能优化
{
UINT32 i;
@ -262,7 +267,7 @@ STATIC BOOL OsPerfTaskFilter(UINT32 taskId)
return TRUE;
}
for (i = 0; i < g_perfCb.taskIdsNr; i++) {
for (i = 0; i < g_perfCb.taskIdsNr; i++) { //储存允许过滤任务ID的列表
if (g_perfCb.taskIds[i] == taskId) {
return TRUE;
}
@ -270,7 +275,7 @@ STATIC BOOL OsPerfTaskFilter(UINT32 taskId)
return FALSE;
}
STATIC INLINE UINT32 OsPerfParamValid(VOID)
STATIC INLINE UINT32 OsPerfParamValid(VOID)//检查性能函数的有效性
{
UINT32 index;
UINT32 res = 0;
@ -287,7 +292,7 @@ STATIC INLINE UINT32 OsPerfParamValid(VOID)
return res;
}
STATIC UINT32 OsPerfHdrInit(UINT32 id)
STATIC UINT32 OsPerfHdrInit(UINT32 id)//初始化性能数据的头部信息
{
PerfDataHdr head = {
.magic = PERF_DATA_MAGIC_WORD,
@ -299,7 +304,7 @@ STATIC UINT32 OsPerfHdrInit(UINT32 id)
return OsPerfOutPutWrite((CHAR *)&head, head.len);
}
VOID OsPerfUpdateEventCount(Event *event, UINT32 value)
VOID OsPerfUpdateEventCount(Event *event, UINT32 value)//更新上传事件的技术
{
if (event == NULL) {
return;
@ -307,46 +312,46 @@ VOID OsPerfUpdateEventCount(Event *event, UINT32 value)
event->count[ArchCurrCpuid()] += (value & 0xFFFFFFFF); /* event->count is UINT64 */
}
VOID OsPerfHandleOverFlow(Event *event, PerfRegs *regs)
VOID OsPerfHandleOverFlow(Event *event, PerfRegs *regs)//处理性能计数器溢出的情况
{
PerfSampleData data;
UINT32 len;
(VOID)memset_s(&data, sizeof(PerfSampleData), 0, sizeof(PerfSampleData));
if ((g_perfCb.needSample) && OsPerfTaskFilter(LOS_CurTaskIDGet())) {
if ((g_perfCb.needSample) && OsPerfTaskFilter(LOS_CurTaskIDGet())) {//判断是否优化
len = OsPerfCollectData(event, &data, regs);
OsPerfOutPutWrite((CHAR *)&data, len);
}
}
UINT32 LOS_PerfInit(VOID *buf, UINT32 size)
UINT32 LOS_PerfInit(VOID *buf, UINT32 size)//初始化性能统计模块
{
UINT32 ret;
UINT32 intSave;
PERF_LOCK(intSave);
PERF_LOCK(intSave);//保存中断状态
if (g_perfCb.status != PERF_UNINIT) {
ret = LOS_ERRNO_PERF_STATUS_INVALID;
goto PERF_INIT_ERROR;
}
ret = OsPmuInit();
ret = OsPmuInit();//函数性能计数器初始化
if (ret != LOS_OK) {
goto PERF_INIT_ERROR;
}
ret = OsPerfOutPutInit(buf, size);
ret = OsPerfOutPutInit(buf, size);//性能输出缓冲区进行初始化
if (ret != LOS_OK) {
ret = LOS_ERRNO_PERF_BUF_ERROR;
goto PERF_INIT_ERROR;
}
g_perfCb.status = PERF_STOPED;
PERF_INIT_ERROR:
PERF_UNLOCK(intSave);
PERF_UNLOCK(intSave);//解锁中断处理
return ret;
}
UINT32 LOS_PerfConfig(PerfConfigAttr *attr)
UINT32 LOS_PerfConfig(PerfConfigAttr *attr)//配置性能统计模块的属性
{
UINT32 ret;
UINT32 intSave;
@ -355,20 +360,20 @@ UINT32 LOS_PerfConfig(PerfConfigAttr *attr)
return LOS_ERRNO_PERF_CONFIG_NULL;
}
PERF_LOCK(intSave);
PERF_LOCK(intSave);//保存中断状态
if (g_perfCb.status != PERF_STOPED) {
ret = LOS_ERRNO_PERF_STATUS_INVALID;
PRINT_ERR("perf config status error : 0x%x\n", g_perfCb.status);
goto PERF_CONFIG_ERROR;
}
g_pmu = NULL;
g_pmu = NULL;//将全局标量PMU计数器置零
g_perfCb.needSample = attr->needSample;
g_perfCb.taskFilterEnable = attr->taskFilterEnable;
g_perfCb.sampleType = attr->sampleType;
if (attr->taskFilterEnable) {
if (attr->taskFilterEnable) {//开启任务过滤功能
ret = memcpy_s(g_perfCb.taskIds, PERF_MAX_FILTER_TSKS * sizeof(UINT32), attr->taskIds,
g_perfCb.taskIdsNr * sizeof(UINT32));
if (ret != EOK) {
@ -377,29 +382,29 @@ UINT32 LOS_PerfConfig(PerfConfigAttr *attr)
}
g_perfCb.taskIdsNr = MIN(attr->taskIdsNr, PERF_MAX_FILTER_TSKS);
}
ret = OsPerfConfig(&attr->eventsCfg);
ret = OsPerfConfig(&attr->eventsCfg);//对事件配置进行处理
PERF_CONFIG_ERROR:
PERF_UNLOCK(intSave);
return ret;
}
VOID LOS_PerfStart(UINT32 sectionId)
VOID LOS_PerfStart(UINT32 sectionId)//启动性能统计模块
{
UINT32 intSave;
UINT32 ret;
PERF_LOCK(intSave);
if (g_perfCb.status != PERF_STOPED) {
if (g_perfCb.status != PERF_STOPED) {//判断统计模块是否打开
PRINT_ERR("perf start status error : 0x%x\n", g_perfCb.status);
goto PERF_START_ERROR;
}
if (!OsPerfParamValid()) {
if (!OsPerfParamValid()) {//检车行呢个统计模块的参数是否有效
PRINT_ERR("forgot call `LOS_Config(...)` before instrumenting?\n");
goto PERF_START_ERROR;
}
if (g_perfCb.needSample) {
if (g_perfCb.needSample) {//判断是否需要抽样
ret = OsPerfHdrInit(sectionId); /* section header init */
if (ret != LOS_OK) {
PRINT_ERR("perf hdr init error 0x%x\n", ret);
@ -407,7 +412,7 @@ VOID LOS_PerfStart(UINT32 sectionId)
}
}
SMP_CALL_PERF_FUNC(OsPerfStart); /* send to all cpu to start pmu */
SMP_CALL_PERF_FUNC(OsPerfStart); /* 所有CPU开始PMU计数器启动性能统计模块i奥 */
g_perfCb.status = PERF_STARTED;
g_perfCb.startTime = OsPerfGetCurrTime();
PERF_START_ERROR:
@ -415,7 +420,7 @@ PERF_START_ERROR:
return;
}
VOID LOS_PerfStop(VOID)
VOID LOS_PerfStop(VOID)//停止性能统计模块的运行,进行一些清理操作
{
UINT32 intSave;
@ -427,12 +432,12 @@ VOID LOS_PerfStop(VOID)
SMP_CALL_PERF_FUNC(OsPerfStop); /* send to all cpu to stop pmu */
OsPerfOutPutFlush();
OsPerfOutPutFlush();//刷新输出操作
if (g_perfCb.needSample) {
OsPerfOutPutInfo();
}
//更新了两个全局变量的值,表示性能统计模块已经在状态上和时间上停止了
g_perfCb.status = PERF_STOPED;
g_perfCb.endTime = OsPerfGetCurrTime();
@ -442,21 +447,21 @@ PERF_STOP_ERROR:
return;
}
UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size)
UINT32 LOS_PerfDataRead(CHAR *dest, UINT32 size)//从性能统计门票快的输出缓冲区中读取数据到指定的内存
{
return OsPerfOutPutRead(dest, size);
}
VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func)
VOID LOS_PerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func)//注册型那个统计模块的通知hook函数
{
UINT32 intSave;
//保存中断状态,恢复中断状态
PERF_LOCK(intSave);
OsPerfNotifyHookReg(func);
PERF_UNLOCK(intSave);
}
VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)
VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)//刷新hook
{
UINT32 intSave;
@ -465,7 +470,7 @@ VOID LOS_PerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)
PERF_UNLOCK(intSave);
}
VOID OsPerfSetIrqRegs(UINTPTR pc, UINTPTR fp)
VOID OsPerfSetIrqRegs(UINTPTR pc, UINTPTR fp)//设置中断相关的寄存器,用于中断时的性能统计
{
LosTaskCB *runTask = (LosTaskCB *)ArchCurrTaskGet();
runTask->pc = pc;

@ -39,11 +39,14 @@ STATIC PERF_BUF_FLUSH_HOOK g_perfBufFlushHook = NULL;
STATIC PerfOutputCB g_perfOutputCb;
STATIC VOID OsPerfDefaultNotify(VOID)
//默认的性能缓冲区通知回调函数,在性能缓冲区的水位线达到一定值时打印一条信息
{
PRINT_INFO("perf buf waterline notify!\n");
}
UINT32 OsPerfOutPutInit(VOID *buf, UINT32 size)
//初始化性能输出模块。如果传入的缓冲区指针为空则使用LOS_MemAlloc函数动态分配内存。
//然后初始化环形缓冲区,设置水位线,并注册默认的性能缓冲区通知回调函数
{
UINT32 ret;
BOOL releaseFlag = FALSE;
@ -69,21 +72,22 @@ RELEASE:
return ret;
}
VOID OsPerfOutPutFlush(VOID)
VOID OsPerfOutPutFlush(VOID)//刷新性能输出缓冲区
{
if (g_perfBufFlushHook != NULL) {
g_perfBufFlushHook(g_perfOutputCb.ringbuf.fifo, g_perfOutputCb.ringbuf.size);
}
}
UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size)
UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size)//从性能输出缓冲区中读取数据
{
OsPerfOutPutFlush();
return LOS_RingbufRead(&g_perfOutputCb.ringbuf, dest, size);
}
STATIC BOOL OsPerfOutPutBegin(UINT32 size)
STATIC BOOL OsPerfOutPutBegin(UINT32 size)//开始写入性能输出缓冲区
{
//检查是否有足够空间
if (g_perfOutputCb.ringbuf.remain < size) {
PRINT_INFO("perf buf has no enough space for 0x%x\n", size);
return FALSE;
@ -91,9 +95,9 @@ STATIC BOOL OsPerfOutPutBegin(UINT32 size)
return TRUE;
}
STATIC VOID OsPerfOutPutEnd(VOID)
STATIC VOID OsPerfOutPutEnd(VOID)//结束性能输出
{
OsPerfOutPutFlush();
OsPerfOutPutFlush();//刷新缓冲区
if (LOS_RingbufUsedSize(&g_perfOutputCb.ringbuf) >= g_perfOutputCb.waterMark) {
if (g_perfBufNotifyHook != NULL) {
g_perfBufNotifyHook();
@ -101,7 +105,7 @@ STATIC VOID OsPerfOutPutEnd(VOID)
}
}
UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size)
UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size)//将数据写入性能输入缓冲区
{
if (!OsPerfOutPutBegin(size)) {
return LOS_NOK;
@ -113,17 +117,17 @@ UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size)
return LOS_OK;
}
VOID OsPerfOutPutInfo(VOID)
VOID OsPerfOutPutInfo(VOID)//打印性能输出缓冲区的信息,包括地址和长度
{
PRINT_EMG("dump section data, addr: %p length: %#x \r\n", g_perfOutputCb.ringbuf.fifo, g_perfOutputCb.ringbuf.size);
}
VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func)
VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func)//注册性能缓冲区通知
{
g_perfBufNotifyHook = func;
}
VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)
VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func)//注册性能缓冲区刷新的函数
{
g_perfBufFlushHook = func;
}

@ -43,13 +43,13 @@ typedef struct {
UINT32 waterMark; /* notify water mark */
} PerfOutputCB;
extern UINT32 OsPerfOutPutInit(VOID *buf, UINT32 size);
extern UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size);
extern UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size);
extern VOID OsPerfOutPutInfo(VOID);
extern VOID OsPerfOutPutFlush(VOID);
extern VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func);
extern VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func);
extern UINT32 OsPerfOutPutInit(VOID *buf, UINT32 size);//初始化性能输出模块
extern UINT32 OsPerfOutPutRead(CHAR *dest, UINT32 size);//从性能输出缓冲区中读取数据,将数据拷贝到指定的目标缓冲区中
extern UINT32 OsPerfOutPutWrite(CHAR *data, UINT32 size);//将数据写入性能输出缓冲区
extern VOID OsPerfOutPutInfo(VOID);//输出性能统计信息
extern VOID OsPerfOutPutFlush(VOID);//刷新性能输出缓冲区
extern VOID OsPerfNotifyHookReg(const PERF_BUF_NOTIFY_HOOK func);//注册性能输出缓冲区通知
extern VOID OsPerfFlushHookReg(const PERF_BUF_FLUSH_HOOK func);//注册性能输出缓冲区刷新
#ifdef __cplusplus
#if __cplusplus

@ -36,11 +36,11 @@ extern "C" {
STATIC Pmu *g_pmuMgr[PERF_EVENT_TYPE_MAX] = {NULL};
UINT32 OsPerfPmuRegister(Pmu *pmu)
UINT32 OsPerfPmuRegister(Pmu *pmu)//注册性能计数器
{
UINT32 type;
if ((pmu == NULL) || (pmu->type >= PERF_EVENT_TYPE_MAX)) {
if ((pmu == NULL) || (pmu->type >= PERF_EVENT_TYPE_MAX)) {//如果传入PMU为空指针或者type超出了有效范围
return LOS_NOK;
}
@ -52,19 +52,20 @@ UINT32 OsPerfPmuRegister(Pmu *pmu)
return LOS_NOK;
}
Pmu *OsPerfPmuGet(UINT32 type)
Pmu *OsPerfPmuGet(UINT32 type)//获取指定类型的性能计数器
{
if (type >= PERF_EVENT_TYPE_MAX) {
return NULL;
}
if (type == PERF_EVENT_TYPE_RAW) { /* process hardware raw events with hard pmu */
type = PERF_EVENT_TYPE_HW;
if (type == PERF_EVENT_TYPE_RAW) { //如果是原始事件类型
/* process hardware raw events with hard pmu */
type = PERF_EVENT_TYPE_HW;//则将其转化为硬件事件类型
}
return g_pmuMgr[type];
}
VOID OsPerfPmuRm(UINT32 type)
VOID OsPerfPmuRm(UINT32 type)//删除指定类型的性能计数器
{
if (type >= PERF_EVENT_TYPE_MAX) {
return;

@ -53,7 +53,7 @@ typedef struct {
VOID (*setPeriod)(Event *event);
UINTPTR (*readCnt)(Event *event);
UINT32 (*mapEvent)(UINT32 eventType, BOOL reverse);
} HwPmu;
} HwPmu;//硬件性能计数器结构体,包括硬件计数器、计数器是否能被分频、分频系数、启用、禁用、开始、停止、清除、设置周期、读取计数器值和事件映射等函数指针
typedef struct {
Pmu pmu;
@ -69,35 +69,35 @@ typedef struct {
};
#endif
};
} SwPmu;
} SwPmu;//软件性能计数器结构体,包括软件计数器、是否启用标志位、定时器配置时间
#define GET_HW_PMU(item) LOS_DL_LIST_ENTRY(item, HwPmu, pmu)
#define TIMER_PERIOD_LOWER_BOUND_US 100
#define TIMER_PERIOD_LOWER_BOUND_US 100//定时器最小周期
#define CCNT_FULL 0xFFFFFFFF
#define CCNT_PERIOD_LOWER_BOUND 0x00000000
#define CCNT_PERIOD_UPPER_BOUND 0xFFFFFF00
#define PERIOD_CALC(p) (CCNT_FULL - (p))
#define CCNT_FULL 0xFFFFFFFF//计数器最大值
#define CCNT_PERIOD_LOWER_BOUND 0x00000000//最小周期
#define CCNT_PERIOD_UPPER_BOUND 0xFFFFFF00//最大周期
#define PERIOD_CALC(p) (CCNT_FULL - (p))//计算给定周期对应的计数器值
#define VALID_PERIOD(p) ((PERIOD_CALC(p) > CCNT_PERIOD_LOWER_BOUND) \
&& (PERIOD_CALC(p) < CCNT_PERIOD_UPPER_BOUND))
&& (PERIOD_CALC(p) < CCNT_PERIOD_UPPER_BOUND))//判断给定周期是否合法
#define PERF_HW_INVAILD_EVENT_TYPE 0xFFFFFFFF
#define PERF_HW_INVAILD_EVENT_TYPE 0xFFFFFFFF//无效的事件类型
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
extern UINT32 OsPerfPmuRegister(Pmu *pmu);
extern VOID OsPerfPmuRm(UINT32 type);
extern Pmu *OsPerfPmuGet(UINT32 type);
extern UINT32 OsPerfPmuRegister(Pmu *pmu);//注册硬件性能计数器
extern VOID OsPerfPmuRm(UINT32 type);//删除硬件性能计数器
extern Pmu *OsPerfPmuGet(UINT32 type);//获取指定类型的硬件性能计数器
extern UINT32 OsHwPmuInit(VOID);
extern UINT32 OsSwPmuInit(VOID);
extern UINT32 OsTimedPmuInit(VOID);
extern UINT32 OsHwPmuInit(VOID);//初始化硬件性能计数器
extern UINT32 OsSwPmuInit(VOID);//初始化软件性能计数器
extern UINT32 OsTimedPmuInit(VOID);//初始化定时器性能计数器
extern UINT32 OsGetPmuCounter0(VOID);
extern UINT32 OsGetPmuMaxCounter(VOID);
extern UINT32 OsGetPmuCycleCounter(VOID);
extern UINT32 OsPerfHwInit(HwPmu *hwPmu);
extern UINT32 OsGetPmuCounter0(VOID);//获取0核计数器值
extern UINT32 OsGetPmuMaxCounter(VOID);//获取最大计数器数
extern UINT32 OsGetPmuCycleCounter(VOID);//获取周期性计数器值
extern UINT32 OsPerfHwInit(HwPmu *hwPmu);//初始化硬件性能计数器
#ifdef __cplusplus
#if __cplusplus

@ -34,7 +34,7 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
STATIC Pmu *g_perfHw = NULL;
STATIC Pmu *g_perfHw = NULL;//指向性能计数器相关的数据结构或对象
STATIC CHAR *g_eventName[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = "cycles",
@ -53,39 +53,41 @@ STATIC CHAR *g_eventName[PERF_COUNT_HW_MAX] = {
* 2.Find available counter for each event.
* 3.Decide whether this hardware pmu need prescaler (once every 64 cycle counts).
*/
STATIC UINT32 OsPerfHwConfig(VOID)
STATIC UINT32 OsPerfHwConfig(VOID)//性能计数器的配置函数,用于初始化和配置硬件性能计数器
{
UINT32 i;
HwPmu *armPmu = GET_HW_PMU(g_perfHw);
UINT32 maxCounter = OsGetPmuMaxCounter();
UINT32 counter = OsGetPmuCounter0();
UINT32 cycleCounter = OsGetPmuCycleCounter();
UINT32 maxCounter = OsGetPmuMaxCounter();//获得最大计数器数量
UINT32 counter = OsGetPmuCounter0();//获取0核计数器的值
UINT32 cycleCounter = OsGetPmuCycleCounter();//周期计数器的值
UINT32 cycleCode = armPmu->mapEvent(PERF_COUNT_HW_CPU_CYCLES, PERF_EVENT_TO_CODE);
if (cycleCode == PERF_HW_INVAILD_EVENT_TYPE) {
return LOS_NOK;
}
//获取性能事件的列表的和数量并进行遍历
PerfEvent *events = &g_perfHw->events;
UINT32 eventNum = events->nr;
for (i = 0; i < eventNum; i++) {
Event *event = &(events->per[i]);
if (!VALID_PERIOD(event->period)) {
if (!VALID_PERIOD(event->period)) {//检查事件周期是否合法
PRINT_ERR("Config period: 0x%x invalid, should be in (%#x, %#x)\n", event->period,
PERIOD_CALC(CCNT_PERIOD_UPPER_BOUND), PERIOD_CALC(CCNT_PERIOD_LOWER_BOUND));
return LOS_NOK;
}
if (g_perfHw->type == PERF_EVENT_TYPE_HW) { /* do map */
//映射编码
UINT32 eventId = armPmu->mapEvent(event->eventId, PERF_EVENT_TO_CODE);
if (eventId == PERF_HW_INVAILD_EVENT_TYPE) {
return LOS_NOK;
}
event->eventId = eventId;
}
//函数根据事件编码是否与周期计数器的事件编码相同,来确定该事件使用的计数器。
//如果相同,则使用周期计数器;否则,使用普通计数器,并递增计数器的值。
if (event->eventId == cycleCode) {
event->counter = cycleCounter;
} else {
@ -93,11 +95,11 @@ STATIC UINT32 OsPerfHwConfig(VOID)
counter++;
}
if (counter >= maxCounter) {
if (counter >= maxCounter) {//检查计数器是否超过了最大计数器数量
PRINT_ERR("max events: %u excluding cycle event\n", maxCounter - 1);
return LOS_NOK;
}
//打印结果,设置根据平台支持的分频
PRINT_DEBUG("Perf Config %u eventId = 0x%x, counter = 0x%x, period = 0x%x\n", i, event->eventId, event->counter,
event->period);
}
@ -106,21 +108,21 @@ STATIC UINT32 OsPerfHwConfig(VOID)
return LOS_OK;
}
STATIC UINT32 OsPerfHwStart(VOID)
STATIC UINT32 OsPerfHwStart(VOID)//用于启动硬件性能计数器
{
UINT32 i;
UINT32 cpuid = ArchCurrCpuid();
HwPmu *armPmu = GET_HW_PMU(g_perfHw);
HwPmu *armPmu = GET_HW_PMU(g_perfHw);//获取硬件性能计数器的指针
PerfEvent *events = &g_perfHw->events;
UINT32 eventNum = events->nr;
armPmu->clear();
armPmu->clear();//清零计数器
for (i = 0; i < eventNum; i++) {
Event *event = &(events->per[i]);
armPmu->setPeriod(event);
armPmu->enable(event);
armPmu->setPeriod(event);//设置事件的计数周期
armPmu->enable(event);//启用事件的计数器
event->count[cpuid] = 0;
}
@ -128,7 +130,7 @@ STATIC UINT32 OsPerfHwStart(VOID)
return LOS_OK;
}
STATIC UINT32 OsPerfHwStop(VOID)
STATIC UINT32 OsPerfHwStop(VOID)//停止硬件性能计数器
{
UINT32 i;
UINT32 cpuid = ArchCurrCpuid();
@ -148,7 +150,9 @@ STATIC UINT32 OsPerfHwStop(VOID)
/* multiplier of cycle counter */
UINT32 eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT);
if ((eventId == PERF_COUNT_HW_CPU_CYCLES) && (armPmu->cntDivided != 0)) {
//如果该事件的事件ID与周期计数器事件ID相同并且硬件性能计数器的分频设置armPmu->cntDivided不为0
PRINT_DEBUG("perf stop is cycle\n");
//此处将该事件的计数值左移6位相当于乘以64
event->count[cpuid] = event->count[cpuid] << 6; /* CCNT counts every 64th cpu cycle */
}
PRINT_DEBUG("perf stop eventCount[0x%x] : [%s] = %llu\n", event->eventId, g_eventName[eventId],
@ -157,11 +161,11 @@ STATIC UINT32 OsPerfHwStop(VOID)
return LOS_OK;
}
STATIC CHAR *OsPerfGetEventName(Event *event)
STATIC CHAR *OsPerfGetEventName(Event *event)//获取事件名称
{
UINT32 eventId;
HwPmu *armPmu = GET_HW_PMU(g_perfHw);
eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT);
HwPmu *armPmu = GET_HW_PMU(g_perfHw);//获取PMU上的事件信息
eventId = armPmu->mapEvent(event->eventId, PERF_CODE_TO_EVENT);//将事件ID映射位对应计数器事件ID
if (eventId < PERF_COUNT_HW_MAX) {
return g_eventName[eventId];
} else {
@ -169,21 +173,21 @@ STATIC CHAR *OsPerfGetEventName(Event *event)
}
}
UINT32 OsPerfHwInit(HwPmu *hwPmu)
UINT32 OsPerfHwInit(HwPmu *hwPmu)//初始化性能计数器
{
UINT32 ret;
if (hwPmu == NULL) {
return LOS_NOK;
}
//设置性能计数器的类型,配置函数,启动函数,停止函数,获取事件名称函数
hwPmu->pmu.type = PERF_EVENT_TYPE_HW;
hwPmu->pmu.config = OsPerfHwConfig;
hwPmu->pmu.start = OsPerfHwStart;
hwPmu->pmu.stop = OsPerfHwStop;
hwPmu->pmu.getName = OsPerfGetEventName;
//将硬件性能计数器的事件数据结构清零
(VOID)memset_s(&hwPmu->pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent));
ret = OsPerfPmuRegister(&hwPmu->pmu);
ret = OsPerfPmuRegister(&hwPmu->pmu);//注册硬件性能计数器,将其存储在全局变量中
g_perfHw = OsPerfPmuGet(PERF_EVENT_TYPE_HW);
return ret;

@ -51,7 +51,7 @@ STATIC CHAR* g_eventName[PERF_COUNT_SW_MAX] = {
[PERF_COUNT_SW_MUX_PEND] = "mux pend",
};
VOID OsPerfHook(UINT32 eventType)
VOID OsPerfHook(UINT32 eventType)//软件性能计数器的事件处理函数
{
if (!g_perfSw.enable) {
return;
@ -69,7 +69,7 @@ VOID OsPerfHook(UINT32 eventType)
if (event->counter == eventType) {
OsPerfUpdateEventCount(event, 1);
if (event->count[ArchCurrCpuid()] % event->period == 0) {
OsPerfFetchCallerRegs(&regs);
OsPerfFetchCallerRegs(&regs);//获取寄存器信息
OsPerfHandleOverFlow(event, &regs);
}
return;
@ -77,7 +77,7 @@ VOID OsPerfHook(UINT32 eventType)
}
}
STATIC UINT32 OsPerfSwConfig(VOID)
STATIC UINT32 OsPerfSwConfig(VOID)//对软件性能计数器进行配置
{
UINT32 i;
PerfEvent *events = &g_perfSw.pmu.events;
@ -94,29 +94,29 @@ STATIC UINT32 OsPerfSwConfig(VOID)
return LOS_OK;
}
STATIC UINT32 OsPerfSwStart(VOID)
STATIC UINT32 OsPerfSwStart(VOID)//启动软件性能计数器
{
UINT32 i;
UINT32 cpuid = ArchCurrCpuid();
PerfEvent *events = &g_perfSw.pmu.events;
UINT32 eventNum = events->nr;
for (i = 0; i < eventNum; i++) {
for (i = 0; i < eventNum; i++) {//遍历所有事件
Event *event = &(events->per[i]);
event->count[cpuid] = 0;
event->count[cpuid] = 0;//清零当前事件在CPU中的计数器
}
g_perfSw.enable = TRUE;
g_perfSw.enable = TRUE;//启动计数器
return LOS_OK;
}
STATIC UINT32 OsPerfSwStop(VOID)
STATIC UINT32 OsPerfSwStop(VOID)//关闭软件性能计数器
{
g_perfSw.enable = FALSE;
return LOS_OK;
}
STATIC CHAR *OsPerfGetEventName(Event *event)
STATIC CHAR *OsPerfGetEventName(Event *event)//获取事件的名称
{
UINT32 eventId = event->eventId;
if (eventId < PERF_COUNT_SW_MAX) {
@ -125,7 +125,7 @@ STATIC CHAR *OsPerfGetEventName(Event *event)
return "unknown";
}
UINT32 OsSwPmuInit(VOID)
UINT32 OsSwPmuInit(VOID)//对PMU计数器进行初始化
{
g_perfSw.pmu = (Pmu) {
.type = PERF_EVENT_TYPE_SW,

@ -39,12 +39,12 @@ extern "C" {
STATIC SwPmu g_perfTimed;
STATIC BOOL OsPerfTimedPeriodValid(UINT32 period)
STATIC BOOL OsPerfTimedPeriodValid(UINT32 period)//验证定时器中的时间周期是否合法
{
return period >= TIMER_PERIOD_LOWER_BOUND_US;
}
STATIC UINT32 OsPerfTimedStart(VOID)
STATIC UINT32 OsPerfTimedStart(VOID)//启动定时器事件
{
UINT32 i;
UINT32 cpuid = ArchCurrCpuid();
@ -74,7 +74,7 @@ STATIC UINT32 OsPerfTimedStart(VOID)
return LOS_OK;
}
STATIC UINT32 OsPerfTimedConfig(VOID)
STATIC UINT32 OsPerfTimedConfig(VOID)//配置定时器,检验是否合法
{
UINT32 i;
PerfEvent *events = &g_perfTimed.pmu.events;
@ -101,7 +101,7 @@ STATIC UINT32 OsPerfTimedConfig(VOID)
return LOS_NOK;
}
STATIC UINT32 OsPerfTimedStop(VOID)
STATIC UINT32 OsPerfTimedStop(VOID)//关闭定时器设置
{
UINT32 ret;
if (ArchCurrCpuid() != 0) { /* only need stop on one core */
@ -116,7 +116,7 @@ STATIC UINT32 OsPerfTimedStop(VOID)
return LOS_OK;
}
STATIC VOID OsPerfTimedHandle(VOID)
STATIC VOID OsPerfTimedHandle(VOID)//处理定时器事件
{
UINT32 index;
PerfRegs regs;
@ -125,7 +125,7 @@ STATIC VOID OsPerfTimedHandle(VOID)
UINT32 eventNum = events->nr;
(VOID)memset_s(&regs, sizeof(PerfRegs), 0, sizeof(PerfRegs));
OsPerfFetchIrqRegs(&regs);
OsPerfFetchIrqRegs(&regs);//获取当前寄存器状态
for (index = 0; index < eventNum; index++) {
Event *event = &(events->per[index]);
@ -134,48 +134,50 @@ STATIC VOID OsPerfTimedHandle(VOID)
}
}
STATIC enum hrtimer_restart OsPerfHrtimer(struct hrtimer *hrtimer)
STATIC enum hrtimer_restart OsPerfHrtimer(struct hrtimer *hrtimer)//高精度定时器(hrtimer)的回调函数
{
SMP_CALL_PERF_FUNC(OsPerfTimedHandle); /* send to all cpu to collect data */
//将定时器事件的处理发送给所有CPU进行数据收集
return HRTIMER_RESTART;
}
STATIC CHAR *OsPerfGetEventName(Event *event)
STATIC CHAR *OsPerfGetEventName(Event *event)//获取事件名称
{
if (event->eventId == PERF_COUNT_CPU_CLOCK) {
if (event->eventId == PERF_COUNT_CPU_CLOCK) {//读取事件ID是否与计数器中的事件记录相同
return "timed";
} else {
return "unknown";
}
}
UINT32 OsTimedPmuInit(VOID)
UINT32 OsTimedPmuInit(VOID)//初始化定时器
{
UINT32 ret;
g_perfTimed.time = (union ktime) {
g_perfTimed.time = (union ktime) {//保存定时器信息
.tv.sec = 0,
.tv.usec = HRTIMER_DEFAULT_PERIOD_US,
};
hrtimer_init(&g_perfTimed.hrtimer, 1, HRTIMER_MODE_REL);
hrtimer_init(&g_perfTimed.hrtimer, 1, HRTIMER_MODE_REL);//第一个参数代表定时器对象,第二个参数为时间源类型,代表的是相对时间,最后一个参数代表定时器模式,这里使用的是相对时间模式
ret = hrtimer_create(&g_perfTimed.hrtimer, g_perfTimed.time, OsPerfHrtimer);
ret = hrtimer_create(&g_perfTimed.hrtimer, g_perfTimed.time, OsPerfHrtimer);//创建定时器
if (ret != LOS_OK) {
return ret;
}
g_perfTimed.pmu = (Pmu) {
.type = PERF_EVENT_TYPE_TIMED,
.config = OsPerfTimedConfig,
.start = OsPerfTimedStart,
.stop = OsPerfTimedStop,
.getName = OsPerfGetEventName,
.type = PERF_EVENT_TYPE_TIMED,//此性能计数器是定时器类型
.config = OsPerfTimedConfig,//性能计数器的事件配置
.start = OsPerfTimedStart,//启动
.stop = OsPerfTimedStop,//停止
.getName = OsPerfGetEventName,//获取事件名称
};
(VOID)memset_s(&g_perfTimed.pmu.events, sizeof(PerfEvent), 0, sizeof(PerfEvent));
//执行完之后清零事件结构体,并在下面进行状态码的注册读取
ret = OsPerfPmuRegister(&g_perfTimed.pmu);
return ret;
return ret;//返回值为初始化状态码
}
#ifdef __cplusplus

@ -31,6 +31,7 @@
* @ingroup kernel
*/
//在LiteOS操作系统中atomic.h头文件通常用于提供原子操作的支持。原子操作是不可中断的操作它可以确保在多线程环境中对共享资源进行安全的访问和修改。
#ifndef _ARCH_GENERIC_ATOMIC_H
#define _ARCH_GENERIC_ATOMIC_H
@ -44,17 +45,26 @@ extern "C" {
#endif /* __cplusplus */
#ifndef LOSCFG_KERNEL_SMP
/*ArchAtomicRead 函数用于原子读取一个整数变量的值。
v volatile INT32
*/
STATIC INLINE INT32 ArchAtomicRead(const Atomic *v)
{
return *(volatile INT32 *)v;
}
/*ArchAtomicSet 函数用于原子设置一个整数变量的值。
v volatile INT32
setVal */
STATIC INLINE VOID ArchAtomicSet(Atomic *v, INT32 setVal)
{
*(volatile INT32 *)v = setVal;
}
/*ArchAtomicAdd 函数用于原子增加一个整数变量的值。
addVal v
*/
STATIC INLINE INT32 ArchAtomicAdd(Atomic *v, INT32 addVal)
{
UINT32 intSave;
@ -66,6 +76,9 @@ STATIC INLINE INT32 ArchAtomicAdd(Atomic *v, INT32 addVal)
return *v;
}
/*ArchAtomicSub 函数用于原子减少一个整数变量的值。
ArchAtomicAdd
subVal v */
STATIC INLINE INT32 ArchAtomicSub(Atomic *v, INT32 subVal)
{
UINT32 intSave;
@ -77,6 +90,10 @@ STATIC INLINE INT32 ArchAtomicSub(Atomic *v, INT32 subVal)
return *v;
}
/*ArchAtomicInc 函数用于原子增加一个整数变量的值。
intSave
addr 1
*/
STATIC INLINE VOID ArchAtomicInc(Atomic *addr)
{
UINT32 intSave;
@ -86,6 +103,7 @@ STATIC INLINE VOID ArchAtomicInc(Atomic *addr)
LOS_IntRestore(intSave);
}
//ArchAtomicIncRet 函数与 ArchAtomicInc 类似,但它还返回增加后的变量值。
STATIC INLINE INT32 ArchAtomicIncRet(Atomic *addr)
{
UINT32 intSave;
@ -96,6 +114,7 @@ STATIC INLINE INT32 ArchAtomicIncRet(Atomic *addr)
return *addr;
}
//ArchAtomicDec 函数用于原子减少一个整数变量的值。它的实现类似于 ArchAtomicInc只是将指针 addr 指向的变量减 1。
STATIC INLINE VOID ArchAtomicDec(Atomic *addr)
{
UINT32 intSave;
@ -105,6 +124,7 @@ STATIC INLINE VOID ArchAtomicDec(Atomic *addr)
LOS_IntRestore(intSave);
}
//ArchAtomicDecRet 函数与 ArchAtomicDec 类似,但它还返回减少后的变量值。
STATIC INLINE INT32 ArchAtomicDecRet(Atomic *addr)
{
UINT32 intSave;
@ -115,6 +135,10 @@ STATIC INLINE INT32 ArchAtomicDecRet(Atomic *addr)
return *addr;
}
/*ArchAtomic64Read 函数用于原子读取一个 64 位整数变量的值。
intSave
v 64
*/
STATIC INLINE INT64 ArchAtomic64Read(const Atomic64 *v)
{
UINT32 intSave;
@ -127,6 +151,10 @@ STATIC INLINE INT64 ArchAtomic64Read(const Atomic64 *v)
return val;
}
/*ArchAtomic64Set 函数用于原子设置一个 64 位整数变量的值为 setVal。
intSave
v setVal
*/
STATIC INLINE VOID ArchAtomic64Set(Atomic64 *v, INT64 setVal)
{
UINT32 intSave;
@ -136,6 +164,10 @@ STATIC INLINE VOID ArchAtomic64Set(Atomic64 *v, INT64 setVal)
LOS_IntRestore(intSave);
}
/*ArchAtomic64Add 函数用于原子增加一个 64 位整数变量的值。
intSave
v addVal val
val*/
STATIC INLINE INT64 ArchAtomic64Add(Atomic64 *v, INT64 addVal)
{
UINT32 intSave;
@ -149,6 +181,9 @@ STATIC INLINE INT64 ArchAtomic64Add(Atomic64 *v, INT64 addVal)
return val;
}
/*ArchAtomic64Sub 函数用于原子减少一个 64 位整数变量的值。
ArchAtomic64Add
v subVal*/
STATIC INLINE INT64 ArchAtomic64Sub(Atomic64 *v, INT64 subVal)
{
UINT32 intSave;
@ -162,6 +197,8 @@ STATIC INLINE INT64 ArchAtomic64Sub(Atomic64 *v, INT64 subVal)
return val;
}
/*ArchAtomic64Inc 函数用于原子增加一个 64 位整数变量的值。
ArchAtomic64Add 1*/
STATIC INLINE VOID ArchAtomic64Inc(Atomic64 *v)
{
UINT32 intSave;
@ -171,6 +208,7 @@ STATIC INLINE VOID ArchAtomic64Inc(Atomic64 *v)
LOS_IntRestore(intSave);
}
//ArchAtomic64IncRet 函数与 ArchAtomic64Inc 类似,但它还返回增加后的变量值。
STATIC INLINE INT64 ArchAtomic64IncRet(Atomic64 *v)
{
UINT32 intSave;
@ -184,6 +222,9 @@ STATIC INLINE INT64 ArchAtomic64IncRet(Atomic64 *v)
return val;
}
/*ArchAtomic64Dec 函数用于原子减少一个 64 位整数变量的值。
intSave v 1
*/
STATIC INLINE VOID ArchAtomic64Dec(Atomic64 *v)
{
UINT32 intSave;
@ -193,6 +234,7 @@ STATIC INLINE VOID ArchAtomic64Dec(Atomic64 *v)
LOS_IntRestore(intSave);
}
//ArchAtomic64DecRet 函数与 ArchAtomic64Dec 类似,但它还返回减少后的变量值。
STATIC INLINE INT64 ArchAtomic64DecRet(Atomic64 *v)
{
UINT32 intSave;
@ -206,6 +248,10 @@ STATIC INLINE INT64 ArchAtomic64DecRet(Atomic64 *v)
return val;
}
/*ArchAtomicXchg32bits 函数用于原子交换一个 32 位整数变量的值。
intSave
v prevVal v val
prevVal*/
STATIC INLINE INT32 ArchAtomicXchg32bits(Atomic *v, INT32 val)
{
UINT32 intSave;
@ -219,6 +265,7 @@ STATIC INLINE INT32 ArchAtomicXchg32bits(Atomic *v, INT32 val)
return prevVal;
}
//ArchAtomicXchg64bits 函数类似于 ArchAtomicXchg32bits但它用于原子交换一个 64 位整数变量的值。
STATIC INLINE INT64 ArchAtomicXchg64bits(Atomic64 *v, INT64 val)
{
UINT32 intSave;
@ -232,6 +279,11 @@ STATIC INLINE INT64 ArchAtomicXchg64bits(Atomic64 *v, INT64 val)
return prevVal;
}
/*ArchAtomicCmpXchg32bits 函数用于原子比较和交换一个 32 位整数变量的值。
intSave
v prevVal prevVal oldVal
v val
*/
STATIC INLINE BOOL ArchAtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal)
{
UINT32 intSave;
@ -247,6 +299,7 @@ STATIC INLINE BOOL ArchAtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal)
return (prevVal != oldVal);
}
//ArchAtomicCmpXchg64bits 函数类似于 ArchAtomicCmpXchg32bits但它用于原子比较和交换一个 64 位整数变量的值。
STATIC INLINE BOOL ArchAtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal)
{
UINT32 intSave;

@ -25,18 +25,18 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* --------------------------------------------------------------------------- */
//在LiteOS操作系统中console头文件通常用于定义与控制台交互相关的函数和数据结构。
#ifndef _CONSOLE_H
#define _CONSOLE_H
#include "los_config.h"
#ifdef LOSCFG_FS_VFS
#include "termios.h"
#ifdef LOSCFG_NET_TELNET
#include "telnet_dev.h"
#endif
#include "virtual_serial.h"
#include "los_ringbuf.h"
//代码中,首先使用了条件编译防护,以确保头文件内容只被包含一次。接着定义了控制台输入输出缓冲区的大小,并声明了控制台初始化、打印和读取等函数。
#include "los_config.h"//引用了系统配置文件,用于获取操作系统的一些设置和属性。
#ifdef LOSCFG_FS_VFS//使用条件编译指令判断是否定义了宏LOSCFG_FS_VFS如果已经定义则编译下面的代码块否则跳过。
#include "termios.h"//包含了 POSIX 终端控制定义的头文件,用于对终端进行控制。
#ifdef LOSCFG_NET_TELNET//使用条件编译指令判断是否定义了宏,如果已经定义,则编译下面的代码块,否则跳过。
#include "telnet_dev.h"//包含了 Telnet 设备驱动的头文件,用于实现 Telnet 连接。
#endif//结束条件编译指令。
#include "virtual_serial.h"//包含了虚拟串口的头文件,用于实现虚拟串口的功能。
#include "los_ringbuf.h"//包含了环形缓冲区的头文件,用于实现缓冲区的读写操作。
#endif
#ifdef __cplusplus
@ -57,76 +57,76 @@ extern "C" {
#define CONSOLE "/dev/console"
#define CONSOLE_NAMELEN 16
#define CONSOLE_CMD_RD_BLOCK_SERIAL 0x104
#define CONSOLE_CMD_RD_BLOCK_TELNET 101
#define CONSOLE_RD_BLOCK 1
#define CONSOLE_RD_NONBLOCK 0
#define CONSOLE_SHELL_KEY_EVENT 0x112
#define CONSOLE_SHELL_EXITED 0x400
#define CONSOLE_CONTROL_RIGHTS_CAPTURE 201
#define CONSOLE_CONTROL_RIGHTS_RELEASE 202
#define CONSOLE_CONTROL_CAPTURE_LINE 203
#define CONSOLE_CONTROL_CAPTURE_CHAR 204
#define CONSOLE_FIFO_SIZE 1024
#define CONSOLE_NUM 2
//这段代码定义了一些宏和常量,它们的含义如下:
#define CONSOLE_CMD_RD_BLOCK_SERIAL 0x104//表示从串口读取数据的阻塞命令其值为0x104。
#define CONSOLE_CMD_RD_BLOCK_TELNET 101//表示从Telnet连接读取数据的阻塞命令其值为101。
#define CONSOLE_RD_BLOCK 1//表示阻塞模式其值为1。
#define CONSOLE_RD_NONBLOCK 0//表示非阻塞模式其值为0。
#define CONSOLE_SHELL_KEY_EVENT 0x112//表示shell键盘事件其值为0x112。
#define CONSOLE_SHELL_EXITED 0x400//表示shell已退出其值为0x400。
#define CONSOLE_CONTROL_RIGHTS_CAPTURE 201//表示控制权被捕获其值为201。
#define CONSOLE_CONTROL_RIGHTS_RELEASE 202//表示控制权被释放其值为202。
#define CONSOLE_CONTROL_CAPTURE_LINE 203//表示捕获行命令其值为203。
#define CONSOLE_CONTROL_CAPTURE_CHAR 204//表示捕获字符命令其值为204。
#define CONSOLE_FIFO_SIZE 1024//表示控制台FIFOFirst In First Out缓冲区大小其值为1024。
#define CONSOLE_NUM 2//表示控制台数量其值为2。
typedef struct {
Ringbuf ringbuf; /* Ring buffer */
EVENT_CB_S sendEvent; /* Inform telnet send task */
Ringbuf ringbuf; /* Ring buffer *///表示环形缓冲区,它可能是一个用于缓存数据的循环队列或者环形链表。
EVENT_CB_S sendEvent; /* Inform telnet send task *///表示向telnet发送任务发送事件的回调函数。
} RingbufSendCB;
typedef struct {
UINT32 consoleID;
UINT32 consoleType;
UINT32 consoleSem;
UINT32 shellEntryId;
UINT32 consoleMask;
struct inode *devInode;
CHAR *name;
INT32 fd;
UINT32 refCount;
BOOL isNonBlock;
UINT32 consoleID;//表示控制台的ID。
UINT32 consoleType;//表示控制台的类型。
UINT32 consoleSem;//表示用于同步的控制台信号量。
UINT32 shellEntryId;//表示shell的入口ID。
UINT32 consoleMask;//表示控制台的掩码。
struct inode *devInode;//表示设备节点。
CHAR *name;//表示控制台的名称。
INT32 fd;//表示文件描述符。
UINT32 refCount;//表示引用计数。
BOOL isNonBlock;//表示是否为非阻塞模式。
#ifdef LOSCFG_SHELL
VOID *shellHandle;
VOID *shellHandle;//表示shell的句柄。
#endif
UINT32 sendTaskID;
RingbufSendCB *ringbufSendCB;
UINT8 fifo[CONSOLE_FIFO_SIZE];
UINT32 fifoOut;
UINT32 fifoIn;
UINT32 currentLen;
struct termios consoleTermios;
UINT32 sendTaskID;//表示发送任务的ID。
RingbufSendCB *ringbufSendCB;//表示环形缓冲区发送回调。
UINT8 fifo[CONSOLE_FIFO_SIZE];//表示控制台的FIFO缓冲区。
UINT32 fifoOut;//表示FIFO缓冲区的输出位置。
UINT32 fifoIn;//表示FIFO缓冲区的输入位置。
UINT32 currentLen;//表示当前长度。
struct termios consoleTermios;//表示控制台的终端属性。
} CONSOLE_CB;
extern INT32 system_console_init(const CHAR *deviceName);
extern INT32 system_console_deinit(const CHAR *deviceName);
extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB);
extern BOOL SetSerialBlock(const CONSOLE_CB *consoleCB);
extern BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB);
extern BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB);
extern CONSOLE_CB *OsGetConsoleByID(INT32 consoleId);
extern CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskId);
extern UINT32 ConsoleTaskReg(INT32 consoleId, UINT32 taskId);
extern INT32 ConsoleUpdateFd(VOID);
extern BOOL ConsoleEnable(VOID);
extern BOOL is_nonblock(const CONSOLE_CB *consoleCB);
extern BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB);
extern INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops);
extern INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops);
extern INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen);
extern INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen);
extern INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds);
extern INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg);
extern INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops);
extern INT32 system_console_init(const CHAR *deviceName);//控制台初始化函数用于初始化控制台相关的资源和状态
extern INT32 system_console_deinit(const CHAR *deviceName);//控制台反初始化函数,用于释放控制台相关的资源和状态。
extern BOOL SetSerialNonBlock(const CONSOLE_CB *consoleCB);//设置串口为非阻塞模式。
extern BOOL SetSerialBlock(const CONSOLE_CB *consoleCB);//设置串口为阻塞模式。
extern BOOL SetTelnetNonBlock(const CONSOLE_CB *consoleCB);//设置Telnet连接为非阻塞模式。
extern BOOL SetTelnetBlock(const CONSOLE_CB *consoleCB);//设置Telnet连接为阻塞模式。
extern CONSOLE_CB *OsGetConsoleByID(INT32 consoleId);//根据控制台ID获取控制台的控制块Control Block
extern CONSOLE_CB *OsGetConsoleByTaskID(UINT32 taskId);//根据任务ID获取关联的控制台的控制块。
extern UINT32 ConsoleTaskReg(INT32 consoleId, UINT32 taskId);//将任务与指定的控制台进行关联。
extern INT32 ConsoleUpdateFd(VOID);//更新控制台的文件描述符File Descriptor
extern BOOL ConsoleEnable(VOID);//使能控制台功能。
extern BOOL is_nonblock(const CONSOLE_CB *consoleCB);//判断控制台是否为非阻塞模式。
extern BOOL IsConsoleOccupied(const CONSOLE_CB *consoleCB);//判断控制台是否已经被占用。
extern INT32 FilepOpen(struct file *filep, const struct file_operations_vfs *fops);//打开文件。
extern INT32 FilepClose(struct file *filep, const struct file_operations_vfs *fops);//关闭文件。
extern INT32 FilepRead(struct file *filep, const struct file_operations_vfs *fops, CHAR *buffer, size_t bufLen);//从文件中读取数据。
extern INT32 FilepWrite(struct file *filep, const struct file_operations_vfs *fops, const CHAR *buffer, size_t bufLen);//向文件中写入数据。
extern INT32 FilepPoll(struct file *filep, const struct file_operations_vfs *fops, poll_table *fds);//对文件进行轮询操作。
extern INT32 FilepIoctl(struct file *filep, const struct file_operations_vfs *fops, INT32 cmd, unsigned long arg);//对文件进行IO控制操作。
extern INT32 GetFilepOps(const struct file *filep, struct file **privFilep, const struct file_operations_vfs **fops);//获取文件的操作函数。
#else
STATIC INLINE INT32 ConsoleUpdateFd(VOID)
STATIC INLINE INT32 ConsoleUpdateFd(VOID)//ConsoleUpdateFdINT3232return -1;File Descriptor-1
{
return -1;
}
#endif
#endif//这个宏表示结束了之前的条件编译指令#if。
#ifdef __cplusplus
#ifdef __cplusplus//这一组条件编译指令用于判断是否为C++编译环境。如果是C++编译环境则将后面的代码块用extern "C"包裹起来以保证C和C++之间的函数调用规则一致。
#if __cplusplus
}
#endif /* __cplusplus */

@ -30,12 +30,12 @@
* @defgroup los_atomic Atomic
* @ingroup kernel
*/
#ifndef _LOS_ATOMIC_H
#define _LOS_ATOMIC_H
//los_atomic.h是用于支持原子操作的头文件。
#ifndef _LOS_ATOMIC_H//表示如果宏变量 _LOS_ATOMIC_H 没有被定义过,则执行以下代码,否则忽略这段代码。
#define _LOS_ATOMIC_H//是定义一个宏变量,可以用来判断这个头文件是否已经被包含过。
#include "los_typedef.h"
#include "arch/atomic.h"
#include "arch/atomic.h"//是平台相关的原子操作头文件,具体实现依赖于不同的硬件平台。
#ifdef __cplusplus
#if __cplusplus
@ -60,7 +60,7 @@ extern "C" {
* @see LOS_Atomic64Read
* @since Huawei LiteOS V200R003C00
*/
STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v)
STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v)//函数接受一个Atomic类型的指针参数v并返回一个32位整数。用于读取指定内存位置的原子变量的值。
{
return ArchAtomicRead(v);
}
@ -84,7 +84,7 @@ STATIC INLINE INT32 LOS_AtomicRead(const Atomic *v)
* @see LOS_Atomic64Set
* @since Huawei LiteOS V200R003C00
*/
STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal)
STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal)//函数接受一个Atomic类型的指针参数v和一个32位整数setVal没有返回值返回类型为VOID
{
ArchAtomicSet(v, setVal);
}
@ -114,7 +114,7 @@ STATIC INLINE VOID LOS_AtomicSet(Atomic *v, INT32 setVal)
*/
STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal)
{
return ArchAtomicAdd(v, addVal);
return ArchAtomicAdd(v, addVal);//用于将指定内存位置的原子变量增加指定的值。
}
/**
@ -142,7 +142,7 @@ STATIC INLINE INT32 LOS_AtomicAdd(Atomic *v, INT32 addVal)
*/
STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal)
{
return ArchAtomicSub(v, subVal);
return ArchAtomicSub(v, subVal);//用于将指定内存位置的原子变量减少指定的值。
}
/**
@ -168,7 +168,7 @@ STATIC INLINE INT32 LOS_AtomicSub(Atomic *v, INT32 subVal)
*/
STATIC INLINE VOID LOS_AtomicInc(Atomic *v)
{
ArchAtomicInc(v);
ArchAtomicInc(v);//用于将指定内存位置的原子变量增加1。
}
/**
@ -222,7 +222,7 @@ STATIC INLINE INT32 LOS_AtomicIncRet(Atomic *v)
*/
STATIC INLINE VOID LOS_AtomicDec(Atomic *v)
{
ArchAtomicDec(v);
ArchAtomicDec(v);//该函数通常是由特定的体系结构提供的原子递减函数的实现。通过使用内联函数和宏定义,可以在编译时将这段代码直接嵌入到调用处,从而提高执行效率和节省函数调用的开销。
}
/**
@ -248,7 +248,7 @@ STATIC INLINE VOID LOS_AtomicDec(Atomic *v)
*/
STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v)
{
return ArchAtomicDecRet(v);
return ArchAtomicDecRet(v);//该函数通常是由特定的体系结构提供的原子递减操作并返回递减后的值的函数。
}
/**
@ -270,7 +270,7 @@ STATIC INLINE INT32 LOS_AtomicDecRet(Atomic *v)
*/
STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v)
{
return ArchAtomic64Read(v);
return ArchAtomic64Read(v);//该函数通常是由特定的体系结构提供的原子读取操作的函数。
}
/**
@ -294,7 +294,7 @@ STATIC INLINE INT64 LOS_Atomic64Read(const Atomic64 *v)
*/
STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal)
{
ArchAtomic64Set(v, setVal);
ArchAtomic64Set(v, setVal);//该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -322,7 +322,7 @@ STATIC INLINE VOID LOS_Atomic64Set(Atomic64 *v, INT64 setVal)
*/
STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal)
{
return ArchAtomic64Add(v, addVal);
return ArchAtomic64Add(v, addVal);//函数来完成原子加操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -350,7 +350,7 @@ STATIC INLINE INT64 LOS_Atomic64Add(Atomic64 *v, INT64 addVal)
*/
STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal)
{
return ArchAtomic64Sub(v, subVal);
return ArchAtomic64Sub(v, subVal);//函数来完成原子减操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -376,7 +376,7 @@ STATIC INLINE INT64 LOS_Atomic64Sub(Atomic64 *v, INT64 subVal)
*/
STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v)
{
ArchAtomic64Inc(v);
ArchAtomic64Inc(v);//函数来完成原子增加操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -403,7 +403,7 @@ STATIC INLINE VOID LOS_Atomic64Inc(Atomic64 *v)
*/
STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v)
{
return ArchAtomic64IncRet(v);
return ArchAtomic64IncRet(v);//函数来完成原子增加操作并返回增加后的值,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -430,7 +430,7 @@ STATIC INLINE INT64 LOS_Atomic64IncRet(Atomic64 *v)
*/
STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v)
{
ArchAtomic64Dec(v);
ArchAtomic64Dec(v);//函数来完成原子减少操作,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -456,7 +456,7 @@ STATIC INLINE VOID LOS_Atomic64Dec(Atomic64 *v)
*/
STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v)
{
return ArchAtomic64DecRet(v);
return ArchAtomic64DecRet(v);//函数来完成原子减少操作并返回减少后的值,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -480,7 +480,7 @@ STATIC INLINE INT64 LOS_Atomic64DecRet(Atomic64 *v)
*/
STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val)
{
return ArchAtomicXchg32bits(v, val);
return ArchAtomicXchg32bits(v, val);//函数来完成原子交换操作并返回交换前的值,该函数应该是由底层的架构代码提供的,用于实现 32 位整数的原子操作。
}
/**
@ -504,7 +504,7 @@ STATIC INLINE INT32 LOS_AtomicXchg32bits(Atomic *v, INT32 val)
*/
STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val)
{
return ArchAtomicXchg64bits(v, val);
return ArchAtomicXchg64bits(v, val);//函数来完成原子交换操作并返回交换前的值,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
/**
@ -531,7 +531,7 @@ STATIC INLINE INT64 LOS_AtomicXchg64bits(Atomic64 *v, INT64 val)
*/
STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal)
{
return ArchAtomicCmpXchg32bits(v, val, oldVal);
return ArchAtomicCmpXchg32bits(v, val, oldVal);//函数来完成原子比较和交换操作,并返回比较结果,该函数应该是由底层的架构代码提供的,用于实现 32 位整数的原子操作。
}
/**
@ -558,7 +558,7 @@ STATIC INLINE BOOL LOS_AtomicCmpXchg32bits(Atomic *v, INT32 val, INT32 oldVal)
*/
STATIC INLINE BOOL LOS_AtomicCmpXchg64bits(Atomic64 *v, INT64 val, INT64 oldVal)
{
return ArchAtomicCmpXchg64bits(v, val, oldVal);
return ArchAtomicCmpXchg64bits(v, val, oldVal);//函数来完成原子比较和交换操作,并返回比较结果,该函数应该是由底层的架构代码提供的,用于实现 64 位整数的原子操作。
}
#ifdef __cplusplus

@ -75,19 +75,19 @@ extern "C" {
* @since Huawei LiteOS V100R001C00
*/
#define LOS_ASSERT_COND(expression) LOS_ASSERT(expression)
//这是一个宏函数它接受一个表达式作为参数并将该表达式作为参数传递给另一个名为LOS_ASSERT的宏函数。它的作用是在满足给定条件时执行断言。
/**
* @ingroup los_base
* Define the timeout interval as LOS_NO_WAIT.
*/
#define LOS_NO_WAIT 0
//这是一个常量被定义为0。它表示一个超时时间间隔即表示不等待立即返回。
/**
* @ingroup los_base
* Define the timeout interval as LOS_WAIT_FOREVER.
*/
#define LOS_WAIT_FOREVER 0xFFFFFFFF
//这是另一个常量被定义为0xFFFFFFFF。它表示一个超时时间间隔即表示永远等待直到条件满足或者被中断。
/**
* @ingroup los_base
* @brief Align the value (addr) by some bytes (boundary).
@ -111,8 +111,8 @@ extern "C" {
* @see LOS_Align | TRUNCATE
* @since Huawei LiteOS V100R001C00
*/
#ifndef ALIGN
#define ALIGN(addr, boundary) LOS_Align(addr, boundary)
#ifndef ALIGN//判断ALIGN是否已经被定义过如果没有被定义过则执行接下来的代码。
#define ALIGN(addr, boundary) LOS_Align(addr, boundary)//分别表示需要对齐的地址和对齐边界。在函数体内部它调用了LOS_Align函数进行地址对齐操作将addr地址向上对齐到最接近的boundary的倍数。
#endif
/**
@ -139,10 +139,16 @@ extern "C" {
* @since Huawei LiteOS V100R001C00
*/
#define TRUNCATE(addr, size) ((UINTPTR)(addr) & ~((size) - 1))
//宏接受两个参数 addr 和 size返回一个截断后的地址。具体而言该宏将地址 addr 按照 size 的大小进行对齐,并将低位多余的位置为零。例如,如果 addr 是 0x12345678size 是 4则截断后的地址是 0x12345670。
/**
* Read a UINT8 value from addr and stroed in value.
*/
/*READ_UINT8(value, addr)、READ_UINT16(value, addr) 和 READ_UINT32(value, addr)
addr 8 16 32
value
使 dsb()
dsb()
*/
#define READ_UINT8(value, addr) ({ (value) = *((volatile UINT8 *)((UINTPTR)(addr))); dsb(); })
/**
@ -155,6 +161,9 @@ extern "C" {
*/
#define READ_UINT32(value, addr) ({ (value) = *((volatile UINT32 *)((UINTPTR)(addr))); dsb(); })
//判断编译环境是否为 64 位。如果是 64 位环境,则定义了 READ_UINT64 和 WRITE_UINT64 宏。否则,这两个宏将被忽略。
//宏用于从地址 addr 中读取一个 64 位的整数值,并将结果存储到变量 value 中。这里使用了和之前类似的操作,通过指针间接读取内存中的值,并使用 dsb() 函数进行数据同步操作。
#ifdef __LP64__
/**
* Read a UINT64 value from addr and stroed in value.
@ -162,6 +171,11 @@ extern "C" {
#define READ_UINT64(value, addr) ({ (value) = *((volatile UINT64 *)((UINTPTR)(addr))); dsb(); })
#endif
/*WRITE_UINT8(value, addr)、WRITE_UINT16(value, addr) 和 WRITE_UINT32(value, addr) 宏
8 16 32 value addr
使使 dsb()
*/
/**
* Write a UINT8 value to addr.
*/
@ -177,6 +191,8 @@ extern "C" {
*/
#define WRITE_UINT32(value, addr) ({ dsb(); *((volatile UINT32 *)((UINTPTR)(addr))) = (value); })
//在 64 位环境下,还定义了 WRITE_UINT64 宏,用于将 64 位的整数值 value 写入到地址 addr 中。
#ifdef __LP64__
/**
* Write a UINT64 addr to addr.
@ -187,11 +203,13 @@ extern "C" {
/**
* Get a UINT8 value from addr.
*/
//宏用于从地址 addr 中读取一个 8 位的无符号整数值,并返回读取到的结果。在读取之后,使用 dsb() 函数进行数据同步操作,以确保读取的数据正确。
#define GET_UINT8(addr) ({ UINT8 r = *((volatile UINT8 *)((UINTPTR)(addr))); dsb(); r; })
/**
* Get a UINT16 value from addr.
*/
//GET_UINT16(addr) 和 GET_UINT32(addr) 宏分别用于从地址 addr 中读取 16 位和 32 位的无符号整数值,并返回读取到的结果。同样地,在读取之后也进行数据同步操作。
#define GET_UINT16(addr) ({ UINT16 r = *((volatile UINT16 *)((UINTPTR)(addr))); dsb(); r; })
/**
@ -199,6 +217,8 @@ extern "C" {
*/
#define GET_UINT32(addr) ({ UINT32 r = *((volatile UINT32 *)((UINTPTR)(addr))); dsb(); r; })
//在 64 位环境下,还定义了 GET_UINT64(addr) 宏,用于从地址 addr 中读取一个 64 位的无符号整数值,并返回读取到的结果。
#ifdef __LP64__
/**
* Get a UINT64 value from addr.
@ -226,7 +246,7 @@ extern "C" {
* @see LOS_ASSERT_COND
* @since Huawei LiteOS V100R001C00
*/
#ifdef LOSCFG_DEBUG_VERSION
#ifdef LOSCFG_DEBUG_VERSION//首先,通过条件编译指令 #ifdef LOSCFG_DEBUG_VERSION 来判断是否处于调试版本。如果定义了 LOSCFG_DEBUG_VERSION 宏,则表示处于调试版本,代码块 #ifdef 和 #endif 之间的内容将会生效;否则,代码块 #else 和 #endif 之间的内容将会生效。
#define LOS_ASSERT(judge) do { \
if ((UINTPTR)(judge) == 0) { \
(VOID)LOS_IntLock(); \
@ -234,8 +254,12 @@ extern "C" {
while (1) {} \
} \
} while (0)
//在调试版本下宏定义的代码块中LOS_ASSERT 宏被定义为一个带有参数 judge 的宏函数。它的作用是进行断言检查,如果 judge 表达式的结果为零(即假),则执行以上操作
//调用 LOS_IntLock() 函数,该函数可能是一个用于禁止中断的操作,以确保在断言失败时不会中断处理。
//使用 PRINT_ERR 打印一条错误信息,其中包含了出错的文件名、行号和函数名。
//进入一个无限循环 while (1),程序会一直停留在这个循环中。
#else
#define LOS_ASSERT(judge)
#define LOS_ASSERT(judge)//在非调试版本下宏定义的代码块中LOS_ASSERT 宏被定义为空,即不进行任何操作。
#endif
/**
@ -261,7 +285,8 @@ extern "C" {
* @since Huawei LiteOS V100R001C00
*/
extern UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary);
//具体而言,函数的功能是将 addr 按照 boundary 边界进行对齐,并返回对齐后的地址。例如,如果 addr 是 12boundary 是 8那么对齐后的地址就是 16。
//extern 关键字表示该函数是在其他地方定义的,这里只是对其进行声明。这样做的目的是在当前文件中使用该函数时能够正确引用它,而不需要提供函数的具体实现。
/**
* @ingroup los_base
* @brief Sleep the current task.

@ -31,7 +31,7 @@
* @ingroup kernel
*/
#ifndef _LOS_BITMAP_H
#ifndef _LOS_BITMAP_H//这段代码是一个条件编译指令块,用于判断是否定义了宏 _LOS_BITMAP_H。如果未定义该宏则会执行 #ifndef 和 #endif 之间的代码。
#define _LOS_BITMAP_H
#include "los_typedef.h"
@ -48,6 +48,7 @@ extern "C" {
*
* The effective bit index is from 0 to 31.
*/
//由于这里宏定义的值为 32这个宏的含义是使用 0 到 31 的整数表示位索引值,而 32 则表示无效的位索引值。这种处理方式在计算机编程中比较常见,一般用于标识某些特殊的状态或标志。
#define LOS_INVALID_BIT_INDEX 32
/**
@ -69,6 +70,9 @@ extern "C" {
* @see LOS_BitmapClr
* @since Huawei LiteOS V100R001C00
*/
/*bitmap 是一个指向 UINT32 类型的指针,表示一个位图(或称为位数组)。
pos UINT16
1 1*/
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos);
/**
@ -90,6 +94,9 @@ VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos);
* @see LOS_BitmapSet.
* @since Huawei LiteOS V100R001C00
*/
/*bitmap 是一个指向 UINT32 类型的指针,表示一个位图(或称为位数组)。
pos UINT16
0*/
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos);
/**
@ -108,6 +115,12 @@ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos);
* @see LOS_HighBitGet
* @since Huawei LiteOS V100R001C00
*/
/*函数的作用是在给定的位图中找到最低位(也就是数值最小的位)的索引,
32 LOS_INVALID_BIT_INDEX
UINT16
unsigned short 0 31 0 31 32*/
UINT16 LOS_LowBitGet(UINT32 bitmap);
/**
@ -126,6 +139,12 @@ UINT16 LOS_LowBitGet(UINT32 bitmap);
* @see LOS_LowBitGet
* @since Huawei LiteOS V100R001C00
*/
/*函数的作用是在给定的位图中找到最高位(也就是数值最大的位)的索引,
32 LOS_INVALID_BIT_INDEX
UINT16 unsigned short
0 31 0 31 32*/
UINT16 LOS_HighBitGet(UINT32 bitmap);
#ifdef __cplusplus

@ -35,79 +35,79 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_LITTLE_ENDIAN 0x1234 /* Little endian */
#define OS_BIG_ENDIAN 0x4321 /* Big endian */
#define OS_LITTLE_ENDIAN 0x1234 /* Little endian *///表示小端序,数值为 0x1234
#define OS_BIG_ENDIAN 0x4321 /* Big endian *///表示大端序,数值为 0x4321
#ifndef OS_BYTE_ORDER
#define OS_BYTE_ORDER OS_LITTLE_ENDIAN
#define OS_BYTE_ORDER OS_LITTLE_ENDIAN//如果未定义 OS_BYTE_ORDER则将其设置为 OS_LITTLE_ENDIAN
#endif
/* Define OS code data sections */
/* The indicator function is inline */
#ifndef LITE_OS_SEC_ALW_INLINE
#define LITE_OS_SEC_ALW_INLINE /* __attribute__((always_inline)) */
#define LITE_OS_SEC_ALW_INLINE /* __attribute__((always_inline)) *///定义了一个宏,用于将函数声明为内联函数
#endif
#ifndef LITE_OS_SEC_TEXT
#define LITE_OS_SEC_TEXT /* __attribute__((section(".text.sram"))) */
#define LITE_OS_SEC_TEXT /* __attribute__((section(".text.sram"))) *///定义了一个宏,用于将代码段放置在 .text.sram 段中
#endif
#ifndef LITE_OS_SEC_TEXT_MINOR
#define LITE_OS_SEC_TEXT_MINOR /* __attribute__((section(".text.ddr"))) */
#define LITE_OS_SEC_TEXT_MINOR /* __attribute__((section(".text.ddr"))) *///定义了一个宏,用于将代码段放置在 .text.ddr 段中
#endif
#ifndef LITE_OS_SEC_TEXT_INIT
#define LITE_OS_SEC_TEXT_INIT /* __attribute__((section(".text.init"))) */
#define LITE_OS_SEC_TEXT_INIT /* __attribute__((section(".text.init"))) *///宏定义了一个代码段,用于放置初始化代码,其位置在 .text.init 段中。
#endif
#ifndef LITE_OS_SEC_DATA
#define LITE_OS_SEC_DATA /* __attribute__((section(".data.sram"))) */
#define LITE_OS_SEC_DATA /* __attribute__((section(".data.sram"))) *///宏定义了一个数据段,用于放置数据,其位置在 .data.sram 段中。
#endif
#ifndef LITE_OS_SEC_DATA_MINOR
#define LITE_OS_SEC_DATA_MINOR /* __attribute__((section(".data.ddr"))) */
#define LITE_OS_SEC_DATA_MINOR /* __attribute__((section(".data.ddr"))) *///定义了一个次要数据段,用于放置次要的数据,其位置在 .data.ddr 段中。
#endif
#ifndef LITE_OS_SEC_DATA_INIT
#define LITE_OS_SEC_DATA_INIT /* __attribute__((section(".data.init"))) */
#define LITE_OS_SEC_DATA_INIT /* __attribute__((section(".data.init"))) *///宏定义了一个数据段,用于放置初始化数据,其位置在 .data.init 段中。
#endif
#ifndef LITE_OS_SEC_DATA_VEC
#define LITE_OS_SEC_DATA_VEC __attribute__((section(".data.vector")))
#define LITE_OS_SEC_DATA_VEC __attribute__((section(".data.vector")))//宏定义了一个数据段,用于放置向量表数据,其位置在 .data.vector 段中。
#endif
#ifndef LITE_OS_SEC_BSS
#define LITE_OS_SEC_BSS /* __attribute__((section(".bss.sram"))) */
#define LITE_OS_SEC_BSS /* __attribute__((section(".bss.sram"))) *///宏定义了一个数据段用于放置未初始化的数据BSS段其位置在 .bss.sram 段中。
#endif
#ifndef LITE_OS_SEC_BSS_MINOR
#define LITE_OS_SEC_BSS_MINOR /* __attribute__((section(".bss.ddr"))) */
#define LITE_OS_SEC_BSS_MINOR /* __attribute__((section(".bss.ddr"))) */// 宏定义了一个数据段用于放置未初始化的次要数据BSS段其位置在 .bss.ddr 段中。
#endif
#ifndef LITE_OS_SEC_BSS_INIT
#define LITE_OS_SEC_BSS_INIT /* __attribute__((section(".bss.init"))) */
#define LITE_OS_SEC_BSS_INIT /* __attribute__((section(".bss.init"))) *///宏定义了一个数据段用于放置未初始化的初始化数据BSS段其位置在 .bss.init 段中。
#endif
#ifndef LITE_OS_SEC_ITCM
#define LITE_OS_SEC_ITCM /* __attribute__((section(".itcm "))) */
#define LITE_OS_SEC_ITCM /* __attribute__((section(".itcm "))) */// 宏定义了一个代码段,用于放置代码(指令)和只读数据,在 ITCM 中运行。 ITCM 与其他内存有所不同,它位于 CPU 内部,具有高速访问和低延迟的优势。
#endif
#ifndef LITE_OS_SEC_DTCM
#define LITE_OS_SEC_DTCM /* __attribute__((section(".dtcm"))) */
#define LITE_OS_SEC_DTCM /* __attribute__((section(".dtcm"))) *///宏定义了一个数据段,用于放置数据,位于 DTCM 中。 DTCM 与其他内存有所不同,它位于 CPU 内部,具有高速访问和低延迟的优势。
#endif
#define PACK1
#define PACK1//宏定义了一个结构体成员变量的对齐方式,将结构体的成员变量紧密地打包在一起,不使用空间来对齐。
#ifndef LITE_OS_ATTR_SEC
#define LITE_OS_ATTR_SEC(name) __attribute__((section(#name)))
#define LITE_OS_ATTR_SEC(name) __attribute__((section(#name)))//宏定义了一个函数或变量所在的段,通过 #name 将 name 转换为字符串,将函数或变量放置到指定名称的段中。
#endif
#ifndef LITE_OS_ATTR_ALIGN
#define LITE_OS_ATTR_ALIGN(x) __attribute__((aligned(x)))
#define LITE_OS_ATTR_ALIGN(x) __attribute__((aligned(x)))//宏定义了数据的对齐方式即几个字节对齐x 表示对齐的字节数。
#endif
#ifndef LITE_OS_ATTR_SEC_ALIGN
#define LITE_OS_ATTR_SEC_ALIGN(name, x) __attribute__((section(#name), aligned(x)))
#define LITE_OS_ATTR_SEC_ALIGN(name, x) __attribute__((section(#name), aligned(x)))//宏定义了某段数据的对齐方式,即将数据放置到指定名称的段中,并按照指定的对齐方式对齐。
#endif
#ifndef OS_EMBED_ASM
#define OS_EMBED_ASM __asm__ __volatile__
#define OS_EMBED_ASM __asm__ __volatile__//宏定义了嵌入汇编指令的方式,将 asm volatile 作为嵌入汇编指令的前缀,使得编译器可以将其识别为汇编指令。
#endif
#ifdef __cplusplus

@ -30,6 +30,22 @@
* @defgroup los_config System configuration items
* @ingroup kernel
*/
/*具体而言los_config.h 文件通常包含以下内容:
Task
Interrupt
Memory Management
Timer
Task Scheduling
System Clock
los_config.h
los_config.h LiteOS */
#ifndef _LOS_CONFIG_H
#define _LOS_CONFIG_H
@ -45,53 +61,53 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#ifdef LOSCFG_LIB_CONFIGURABLE
extern UINT32 g_osSysClock;
extern UINT32 g_tickPerSecond;
extern UINT32 g_taskLimit;
extern UINT32 g_taskMinStkSize;
extern UINT32 g_taskIdleStkSize;
extern UINT32 g_taskDfltStkSize;
extern UINT32 g_taskSwtmrStkSize;
extern UINT32 g_swtmrLimit;
extern UINT32 g_semLimit;
extern UINT32 g_muxLimit;
extern UINT32 g_queueLimit;
extern UINT32 g_timeSliceTimeOut;
extern BOOL g_nxEnabled;
extern UINTPTR g_dlNxHeapBase;
extern UINT32 g_dlNxHeapSize;
#define LOS_GET_NX_CFG() (g_nxEnabled)
#define LOS_SET_NX_CFG(value) (g_nxEnabled = (value))
#define LOS_GET_DL_NX_HEAP_BASE() (g_dlNxHeapBase)
#define LOS_SET_DL_NX_HEAP_BASE(addr) (g_dlNxHeapBase = (addr))
#define LOS_GET_DL_NX_HEAP_SIZE() (g_dlNxHeapSize)
#define LOS_SET_DL_NX_HEAP_SIZE(size) (g_dlNxHeapSize = (size))
#define OS_SYS_CLOCK g_osSysClock
#define KERNEL_TICK_PER_SECOND g_tickPerSecond
#define KERNEL_TSK_LIMIT g_taskLimit
#define KERNEL_TSK_MIN_STACK_SIZE g_taskMinStkSize
#define KERNEL_TSK_DEFAULT_STACK_SIZE g_taskDfltStkSize
#define KERNEL_TSK_IDLE_STACK_SIZE g_taskIdleStkSize
#define KERNEL_TSK_SWTMR_STACK_SIZE g_taskSwtmrStkSize
#define KERNEL_SWTMR_LIMIT g_swtmrLimit
#define KERNEL_SEM_LIMIT g_semLimit
#define KERNEL_MUX_LIMIT g_muxLimit
#define KERNEL_QUEUE_LIMIT g_queueLimit
#define KERNEL_TIMESLICE_TIMEOUT g_timeSliceTimeOut
#ifdef LOSCFG_LIB_CONFIGURABLE//判断宏定义 LOSCFG_LIB_CONFIGURABLE 是否被定义。如果该宏被定义,那么以下变量声明将会被编译进程序中。
extern UINT32 g_osSysClock;//系统时钟频率
extern UINT32 g_tickPerSecond;//系统时钟滴答数
extern UINT32 g_taskLimit;//最大任务数量
extern UINT32 g_taskMinStkSize;//任务最小堆栈大小
extern UINT32 g_taskIdleStkSize;//空闲任务堆栈大小
extern UINT32 g_taskDfltStkSize;//默认任务堆栈大小
extern UINT32 g_taskSwtmrStkSize;//软件定时器任务堆栈大小
extern UINT32 g_swtmrLimit;//最大软件定时器数量
extern UINT32 g_semLimit;//最大信号量数量
extern UINT32 g_muxLimit;//最大互斥量数量
extern UINT32 g_queueLimit;//最大队列数量
extern UINT32 g_timeSliceTimeOut;//时间片轮转的时间
extern BOOL g_nxEnabled;//是否启用内存保护机制
extern UINTPTR g_dlNxHeapBase;//内存保护机制的起始地址
extern UINT32 g_dlNxHeapSize;//内存保护机制的大小
#define LOS_GET_NX_CFG() (g_nxEnabled)//宏用于获取一个名为g_nxEnabled的变量的值。
#define LOS_SET_NX_CFG(value) (g_nxEnabled = (value))//宏用于设置一个名为g_nxEnabled的变量的值。
#define LOS_GET_DL_NX_HEAP_BASE() (g_dlNxHeapBase)//宏用于获取一个名为g_dlNxHeapBase的变量的值。
#define LOS_SET_DL_NX_HEAP_BASE(addr) (g_dlNxHeapBase = (addr))//宏用于设置一个名为g_dlNxHeapBase的变量的值。
#define LOS_GET_DL_NX_HEAP_SIZE() (g_dlNxHeapSize)//宏用于获取一个名为g_dlNxHeapSize的变量的值。
#define LOS_SET_DL_NX_HEAP_SIZE(size) (g_dlNxHeapSize = (size))//宏用于设置一个名为g_dlNxHeapSize的变量的值。
#define OS_SYS_CLOCK g_osSysClock//定义系统时间频率
#define KERNEL_TICK_PER_SECOND g_tickPerSecond//定义系统时针滴答数
#define KERNEL_TSK_LIMIT g_taskLimit//定义最大任务数量
#define KERNEL_TSK_MIN_STACK_SIZE g_taskMinStkSize//定义任务最小堆栈大小
#define KERNEL_TSK_DEFAULT_STACK_SIZE g_taskDfltStkSize//定义默认任务堆栈大小
#define KERNEL_TSK_IDLE_STACK_SIZE g_taskIdleStkSize//定义默认任务堆栈大小
#define KERNEL_TSK_SWTMR_STACK_SIZE g_taskSwtmrStkSize//定义软件定时器任务堆栈大小
#define KERNEL_SWTMR_LIMIT g_swtmrLimit//定义最大软件定时器数量
#define KERNEL_SEM_LIMIT g_semLimit//定义最大信号量数量
#define KERNEL_MUX_LIMIT g_muxLimit//定义最大互斥量数量
#define KERNEL_QUEUE_LIMIT g_queueLimit//定义最大对列数量
#define KERNEL_TIMESLICE_TIMEOUT g_timeSliceTimeOut//定义时间片轮转的时间
#else /* LOSCFG_LIB_CONFIGURABLE */
#ifdef LOSCFG_KERNEL_NX
#define LOS_GET_NX_CFG() true
#define LOS_SET_NX_CFG(value)
#define LOS_GET_DL_NX_HEAP_BASE() LOS_DL_HEAP_BASE
#define LOS_SET_DL_NX_HEAP_BASE(addr)
#define LOS_GET_DL_NX_HEAP_SIZE() LOS_DL_HEAP_SIZE
#define LOS_SET_DL_NX_HEAP_SIZE(size)
#define LOS_GET_NX_CFG() true//获取内存保护机制是否开启的配置值,当 LOSCFG_KERNEL_NX 宏被定义时,返回 true否则返回 false。
#define LOS_SET_NX_CFG(value)//设置内存保护机制的配置值,该宏定义为空白,没有实际操作。
#define LOS_GET_DL_NX_HEAP_BASE() LOS_DL_HEAP_BASE//获取内存保护机制的起始地址,当 LOSCFG_KERNEL_NX 宏被定义时,返回 LOS_DL_HEAP_BASE否则返回 NULL。
#define LOS_SET_DL_NX_HEAP_BASE(addr)//设置内存保护机制的起始地址,该宏定义为空白,没有实际操作。
#define LOS_GET_DL_NX_HEAP_SIZE() LOS_DL_HEAP_SIZE//获取内存保护机制的大小,当 LOSCFG_KERNEL_NX 宏被定义时,返回 LOS_DL_HEAP_SIZE否则返回 0。
#define LOS_SET_DL_NX_HEAP_SIZE(size)//设置内存保护机制的大小,该宏定义为空白,没有实际操作。
#else /* LOSCFG_KERNEL_NX */
#define LOS_GET_NX_CFG() false
#define LOS_SET_NX_CFG(value)
@ -101,7 +117,9 @@ extern UINT32 g_dlNxHeapSize;
#define LOS_SET_DL_NX_HEAP_SIZE(size)
#endif /* LOSCFG_KERNEL_NX */
#define KERNEL_TICK_PER_SECOND LOSCFG_BASE_CORE_TICK_PER_SECOND
//这段代码是一系列宏定义,用于将一些配置参数映射到对应的宏定义。
//这样做的目的是将配置参数与代码解耦,使得修改配置参数时只需要修改相应的宏定义,而无需修改引用该参数的代码。这样可以提高代码的可维护性和可移植性。
#define KERNEL_TICK_PER_SECOND LOSCFG_BASE_CORE_TICK_PER_SECOND//如KERNEL_TICK_PER_SECOND宏定义为LOSCFG_BASE_CORE_TICK_PER_SECOND意味着在代码中使用KERNEL_TICK_PER_SECOND时实际上是使用了配置参数
#define KERNEL_TSK_LIMIT LOSCFG_BASE_CORE_TSK_LIMIT
#define KERNEL_TSK_MIN_STACK_SIZE LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE
#define KERNEL_TSK_DEFAULT_STACK_SIZE LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE
@ -112,27 +130,27 @@ extern UINT32 g_dlNxHeapSize;
#define KERNEL_MUX_LIMIT LOSCFG_BASE_IPC_MUX_LIMIT
#define KERNEL_QUEUE_LIMIT LOSCFG_BASE_IPC_QUEUE_LIMIT
#define KERNEL_TIMESLICE_TIMEOUT LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT
//最后的#endif /* LOSCFG_LIB_CONFIGURABLE */表示这组宏定义的结束在条件LOSCFG_LIB_CONFIGURABLE不成立时这组宏定义不起作用因为它们是在这个条件下定义的。
#endif /* LOSCFG_LIB_CONFIGURABLE */
/**
* system sections start and end address
*/
extern CHAR __int_stack_start;
extern CHAR __int_stack_end;
extern CHAR __rodata_start;
extern CHAR __rodata_end;
extern CHAR __bss_start;
extern CHAR __bss_end;
extern CHAR __text_start;
extern CHAR __text_end;
extern CHAR __ram_data_start;
extern CHAR __ram_data_end;
extern CHAR __exc_heap_start;
extern CHAR __exc_heap_end;
extern CHAR __heap_start;
extern CHAR __init_array_start__;
extern CHAR __init_array_end__;
extern CHAR __int_stack_start;//内部栈的起始地址
extern CHAR __int_stack_end;//内部栈的结束地址
extern CHAR __rodata_start;//只读数据段的起始地址。
extern CHAR __rodata_end;//只读数据段的结束地址。
extern CHAR __bss_start;//未初始化的全局变量段BSS Segment的起始地址。
extern CHAR __bss_end;//未初始化的全局变量段BSS Segment的结束地址。
extern CHAR __text_start;//可执行代码段Text Segment的起始地址。
extern CHAR __text_end;//可执行代码段Text Segment的结束地址。
extern CHAR __ram_data_start;//RAM 数据段的起始地址。
extern CHAR __ram_data_end;//RAM 数据段的结束地址。
extern CHAR __exc_heap_start;//异常堆Exception Heap的起始地址。
extern CHAR __exc_heap_end;//异常堆Exception Heap的结束地址。
extern CHAR __heap_start;//堆Heap的起始地址。
extern CHAR __init_array_start__;//初始化数组的起始地址。
extern CHAR __init_array_end__; //初始化数组的结束地址。
/****************************** System clock module configuration ****************************/
/**
@ -140,24 +158,24 @@ extern CHAR __init_array_end__;
* System clock (unit: HZ)
*/
#ifndef OS_SYS_CLOCK
#define OS_SYS_CLOCK (get_bus_clk())
#define OS_SYS_CLOCK (get_bus_clk())//定义系统时钟频率默认值为get_bus_clk()
#endif
/**
* @ingroup los_config
* time timer clock (unit: HZ)
*/
#ifndef OS_TIME_TIMER_CLOCK
#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK
#define OS_TIME_TIMER_CLOCK OS_SYS_CLOCK//定义定时器时钟频率,默认值为 OS_SYS_CLOCK
#endif
/**
* limit addr range when search for 'func local(frame pointer)' or 'func name'
*/
#ifndef OS_SYS_FUNC_ADDR_START
#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start)
#define OS_SYS_FUNC_ADDR_START ((UINTPTR)&__int_stack_start)//定义函数起始地址,默认值为&__int_stack_start
#endif
#ifndef OS_SYS_FUNC_ADDR_END
#define OS_SYS_FUNC_ADDR_END g_sys_mem_addr_end
#define OS_SYS_FUNC_ADDR_END g_sys_mem_addr_end//定义函数终止地址默认值为g_sys_mem_addr_end
#endif
/**
@ -165,14 +183,14 @@ extern CHAR __init_array_end__;
* Microseconds of adjtime in one second
*/
#ifndef LOSCFG_BASE_CORE_ADJ_PER_SECOND
#define LOSCFG_BASE_CORE_ADJ_PER_SECOND 500
#define LOSCFG_BASE_CORE_ADJ_PER_SECOND 500//每秒钟的微调时间。如果没有定义过LOSCFG_BASE_CORE_ADJ_PER_SECOND则将其定义为500。这意味着系统在进行时间微调时每秒钟可以微调500微秒。
#endif
/**
* @ingroup los_config
* Sched clck interval
*/
#define SCHED_CLOCK_INTETRVAL_TICKS 100
#define SCHED_CLOCK_INTETRVAL_TICKS 100//表示调度时钟的间隔。这个宏定义的值为100表示调度时钟的间隔为100个时钟节拍。
/****************************** Interrupt module configuration ****************************/
/**
@ -184,7 +202,7 @@ extern CHAR __init_array_end__;
*/
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
#ifndef MAX_BINARY_POINT_VALUE
#define MAX_BINARY_POINT_VALUE 4
#define MAX_BINARY_POINT_VALUE 4//使用条件编译来检查是否已经定义了MAX_BINARY_POINT_VALUE宏。如果没有定义则将其定义为4。
#endif
#endif
@ -197,6 +215,11 @@ extern CHAR __init_array_end__;
* 0xFFFF: max number of all software timers
*/
#ifndef OS_SWTMR_MAX_TIMERID
/*表示软件定时器ID的最大数量。
((0xFFFF / KERNEL_SWTMR_LIMIT) * KERNEL_SWTMR_LIMIT)
KERNEL_SWTMR_LIMIT
ID
ID*/
#define OS_SWTMR_MAX_TIMERID ((0xFFFF / KERNEL_SWTMR_LIMIT) * KERNEL_SWTMR_LIMIT)
#endif
/**
@ -204,6 +227,11 @@ extern CHAR __init_array_end__;
* Maximum size of a software timer queue. The default value of LOSCFG_BASE_CORE_SWTMR_LIMIT is 16.
*/
#ifndef OS_SWTMR_HANDLE_QUEUE_SIZE
/*示软件定时器队列的最大大小。
KERNEL_SWTMR_LIMIT
*/
#define OS_SWTMR_HANDLE_QUEUE_SIZE KERNEL_SWTMR_LIMIT
#endif
#endif
@ -214,6 +242,10 @@ extern CHAR __init_array_end__;
* Starting address of the system memory
*/
#ifndef OS_SYS_MEM_ADDR
/*__heap_start是在链接脚本中定义的符号
OS_SYS_MEM_ADDR
访*/
#define OS_SYS_MEM_ADDR (&__heap_start)
#endif
@ -223,9 +255,11 @@ extern CHAR __init_array_end__;
* Starting address of dynload heap
*/
#if defined (LOSCFG_KERNEL_NX) && defined (LOSCFG_KERNEL_DYNLOAD)
#define LOS_DL_HEAP_SIZE (LOSCFG_KERNLE_DYN_HEAPSIZE * 0x100000)
#define LOS_DL_HEAP_BASE (SYS_MEM_END - LOS_DL_HEAP_SIZE)
//如果这两个宏都被定义了,那么将动态加载模块堆的大小定义为
#define LOS_DL_HEAP_SIZE (LOSCFG_KERNLE_DYN_HEAPSIZE * 0x100000)//(LOSCFG_KERNLE_DYN_HEAPSIZE * 0x100000)
#define LOS_DL_HEAP_BASE (SYS_MEM_END - LOS_DL_HEAP_SIZE)//SYS_MEM_END - LOS_DL_HEAP_SIZE其中SYS_MEM_END表示系统内存池的结束地址
#else
//如果没有定义LOSCFG_KERNEL_NX和LOSCFG_KERNEL_DYNLOAD宏则将动态加载模块堆的大小和起始地址都定义为0。
#define LOS_DL_HEAP_SIZE 0
#define LOS_DL_HEAP_BASE 0
#endif
@ -236,7 +270,7 @@ extern CHAR __init_array_end__;
*/
#ifndef OS_SYS_MEM_SIZE
#define OS_SYS_MEM_SIZE ((g_sys_mem_addr_end) - \
((LOS_DL_HEAP_SIZE + ((UINTPTR)&__heap_start) + (64 - 1)) & ~(64 - 1)))
((LOS_DL_HEAP_SIZE + ((UINTPTR)&__heap_start) + (64 - 1)) & ~(64 - 1)))//定义内存池的大小
#endif
/****************************** fw Interface configuration **************************/
@ -245,11 +279,12 @@ extern CHAR __init_array_end__;
* The core number is one in non-SMP architecture.
*/
#ifdef LOSCFG_KERNEL_SMP
//LOSCFG_KERNEL_CORE_NUM 将被设置为 LOSCFG_KERNEL_SMP_CORE_NUM 的值否则LOSCFG_KERNEL_CORE_NUM 将被设置为 1。
#define LOSCFG_KERNEL_CORE_NUM LOSCFG_KERNEL_SMP_CORE_NUM
#else
#define LOSCFG_KERNEL_CORE_NUM 1
#endif
//LOSCFG_KERNEL_CPU_MASK 被定义为用于表示 CPU 核心掩码的表达式。它使用了位运算,通过将 1 左移 LOSCFG_KERNEL_CORE_NUM 位,然后减去 1来生成一个包含 LOSCFG_KERNEL_CORE_NUM 个 1 的二进制数。这个数字通常用于设置 CPU 亲和性,以确定线程可以运行在哪些 CPU 核心上。
#define LOSCFG_KERNEL_CPU_MASK ((1 << LOSCFG_KERNEL_CORE_NUM) - 1)
/****************************** trace module configuration **************************/
@ -259,6 +294,10 @@ extern CHAR __init_array_end__;
*/
#ifdef LOSCFG_KERNEL_TRACE
#ifdef LOSCFG_RECORDER_MODE_OFFLINE
/*LOSCFG_KERNEL_TRACE 被定义的情况下,该代码块会被编译。
LOSCFG_RECORDER_MODE_OFFLINE
LOSTRACE_BUFFER_SIZE LOSCFG_TRACE_BUFFER_SIZE
LOSTRACE_BUFFER_SIZE 0*/
#define LOS_TRACE_BUFFER_SIZE LOSCFG_TRACE_BUFFER_SIZE
#else
#define LOS_TRACE_BUFFER_SIZE 0
@ -277,39 +316,44 @@ extern CHAR __init_array_end__;
/**
* Version number
*/
#define _T(x) x
#define HW_LITEOS_SYSNAME "Huawei LiteOS"
#define HW_LITEOS_SEP " "
#define _V(v) _T(HW_LITEOS_SYSNAME)_T(HW_LITEOS_SEP)_T(v)
//这段代码是一组宏定义,用于定义操作系统的版本号和系统名称。
#define _T(x) x//宏定义将传入的参数 x 原样返回,用于在宏定义中表示字符串。
#define HW_LITEOS_SYSNAME "Huawei LiteOS"//宏定义为字符串 "Huawei LiteOS",表示操作系统的名称。
#define HW_LITEOS_SEP " "//宏定义为字符串 " ",表示名称和版本号之间的分隔符。
#define _V(v) _T(HW_LITEOS_SYSNAME)_T(HW_LITEOS_SEP)_T(v)//宏定义通过将操作系统名称和版本号连接起来,生成一个完整的版本字符串。
#define HW_LITEOS_VERSION "V200R005C20B053"
#define HW_LITEOS_VER _V(HW_LITEOS_VERSION"-SMP")
#define HW_LITEOS_VERSION "V200R005C20B053"//宏定义为字符串 "V200R005C20B053",表示操作系统的具体版本号。
#define HW_LITEOS_VER _V(HW_LITEOS_VERSION"-SMP")//宏定义使用了 _V 宏,将操作系统名称和版本号连接起来,形成类似 "Huawei LiteOS V200R005C20B053-SMP" 的完整版本号字符串。
/**
* The Version number of Public
*/
#define MAJ_V 5
#define MIN_V 1
#define REL_V 0
#define MAJ_V 5//宏定义为整数 5表示操作系统的主要版本号。
#define MIN_V 1//宏定义为整数 1表示操作系统的次要版本号。
#define REL_V 0//宏定义为整数 0表示操作系统的发布版本号。
/**
* The release candidate version number
*/
#define EXTRA_V 0
//这些宏定义和函数声明用于管理操作系统的版本号,并提供了一种将版本号转换为字符串格式的机制。
#define EXTRA_V 0//宏定义为整数 0表示操作系统的额外版本号或候选版本号。
#define VERSION_NUM(a, b, c) (((a) << 16) | ((b) << 8) | (c))
#define HW_LITEOS_OPEN_VERSION_NUM VERSION_NUM(MAJ_V, MIN_V, REL_V)
#define VERSION_NUM(a, b, c) (((a) << 16) | ((b) << 8) | (c))//宏定义将主版本号 a、次版本号 b 和发布版本号 c 组合成一个无符号整数,通过位运算实现。
#define HW_LITEOS_OPEN_VERSION_NUM VERSION_NUM(MAJ_V, MIN_V, REL_V)// 宏定义使用了 VERSION_NUM 宏,将主版本号、次版本号和发布版本号组成一个表示版本号的无符号整数。
#define STRINGIFY_1(x) #x
#define STRINGIFY(x) STRINGIFY_1(x)
#define STRINGIFY_1(x) #x//宏定义将参数 x 转换为字符串。
#define STRINGIFY(x) STRINGIFY_1(x)//宏定义调用 STRINGIFY_1 宏,将参数转换为字符串。
#define HW_LITEOS_OPEN_VERSION_STRING STRINGIFY(MAJ_V) "." STRINGIFY(MIN_V) "." STRINGIFY(REL_V)
#define HW_LITEOS_OPEN_VERSION_STRING STRINGIFY(MAJ_V) "." STRINGIFY(MIN_V) "." STRINGIFY(REL_V)//宏定义使用了 STRINGIFY 宏,将主版本号、次版本号和发布版本号转换为形如 "5.1.0" 的字符串格式。
#if (EXTRA_V != 0)
/*不等于 0则 HW_LITEOS_KERNEL_VERSION_STRING 宏定义为带有候选版本号的版本字符串;
*/
#define HW_LITEOS_KERNEL_VERSION_STRING HW_LITEOS_OPEN_VERSION_STRING "-rc" STRINGIFY(EXTRA_V)
#else
#define HW_LITEOS_KERNEL_VERSION_STRING HW_LITEOS_OPEN_VERSION_STRING
#endif
//不等于 0则 HW_LITEOS_KERNEL_VERSION_STRING 宏定义为带有候选版本号的版本字符串;否则,它被定义为不带候选版本号的版本字符串。
extern VOID OsStart(VOID);
extern UINT32 OsMain(VOID);
extern VOID *OsGetMainTask(VOID);

@ -47,6 +47,8 @@ extern "C" {
* If LOS_CppSystemInit() is called in the first stage of scatter load,
* this flag should be passed as the third parameter.
*/
/*如果在散射加载的第一阶段调用 LOS_CppSystemInit
*/
#define BEFORE_SCATTER 0
/**
@ -54,6 +56,8 @@ extern "C" {
* If LOS_CppSystemInit() is called in the second stage of scatter load,
* this flag should be passed as the third parameter.
*/
/*如果在散射加载的第二阶段调用 LOS_CppSystemInit
*/
#define AFTER_SCATTER 1
/**
@ -61,6 +65,8 @@ extern "C" {
* If scatter load is disabled, this flag should be passed as the third
* parameter when LOS_CppSystemInit() is called.
*/
/*如果禁用了分散加载,则在调用 LOS_CppSystemInit 时,
*/
#define NO_SCATTER 2
/**
@ -87,6 +93,16 @@ extern "C" {
* <ul><li>los_cppsupport.h: the header file that contains the API declaration.</li></ul>
* @since Huawei LiteOS V100R001C00
*/
//初始化操作系统C++运行环境的函数
/*具体来说LOS_CppSystemInit函数的主要工作包括
C++
LOS_CppSystemInit
C++
C++
C++*/
extern INT32 LOS_CppSystemInit(UINTPTR initArrayStart, UINTPTR initArrayEnd, INT32 flag);
#ifdef __cplusplus

@ -53,6 +53,9 @@ extern "C" {
*
* Solution: Decrease the maximum number of tasks.
*/
/*在 CPU调度器模块中发生了内存不足的错误
LOS_ERRNO_OS_ERROR IDLOS_MOD_CPUP0x00
*/
#define LOS_ERRNO_CPUP_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x00)
/**
@ -63,6 +66,9 @@ extern "C" {
*
* Solution: Check whether the pointer to the input parameter is usable.
*/
/*在 CPU调度器模块中发生了空指针错误
LOS_ERRNO_OS_ERROR IDLOS_MOD_CPUP0x01
*/
#define LOS_ERRNO_CPUP_TASK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x01)
/**
@ -73,6 +79,9 @@ extern "C" {
*
* Solution: Check whether the CPU usage is initialized.
*/
/*在 CPU调度器模块中发生了未初始化的错误
LOS_ERRNO_OS_ERROR IDLOS_MOD_CPUP0x02
*/
#define LOS_ERRNO_CPUP_NO_INIT LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x02)
/**
@ -83,6 +92,9 @@ extern "C" {
*
* Solution: Check whether the number of threads is applicable for the current operation.
*/
/*在 CPU调度器模块中发生了无效的最大数量错误
LOS_ERRNO_OS_ERROR IDLOS_MOD_CPUP0x03
*/
#define LOS_ERRNO_CPUP_MAXNUM_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x03)
/**
@ -93,6 +105,9 @@ extern "C" {
*
* Solution: Check whether the target thread is created.
*/
/*在 CPU调度器模块中发生了线程未创建的错误
LOS_ERRNO_OS_ERROR IDLOS_MOD_CPUP0x04
*/
#define LOS_ERRNO_CPUP_THREAD_NO_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x04)
/**
@ -103,12 +118,22 @@ extern "C" {
*
* Solution: Check whether the target task ID is applicable for the current operation.
*/
/*在CPU调度器模块中发生了无效的任务ID错误
LOS_ERRNO_OS_ERROR IDLOS_MOD_CPUP0x05
*/
#define LOS_ERRNO_CPUP_TSK_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_CPUP, 0x05)
/**
* @ingroup los_cpup
* The structure of the CPU usage information of all tasks.
*/
/*用于描述CPU调度器的信息。
usStatus 16
uwUsage CPU 使 32 permillage
CPU
CPUP_INFO_S
CPU 使*/
typedef struct tagCpupInfo {
UINT16 usStatus; /**< The task status. */
UINT32 uwUsage; /**< CPU usage of all tasks. It is a permillage. And the value range is [0,1000]. */
@ -118,9 +143,13 @@ typedef struct tagCpupInfo {
* @ingroup los_cpup
* The time period which the CPU usage collects in.
*/
//用于表示 CPU 使用率的时间范围。
enum {
//表示显示最近 10 秒钟的 CPU 使用率值为0。
CPUP_LAST_TEN_SECONDS = 0, /**< Display CPU usage in the last ten seconds, the value is 0. */
//表示显示最近 1 秒钟的 CPU 使用率值为1。
CPUP_LAST_ONE_SECONDS = 1, /**< Display CPU usage in the last one second, the value is 1. */
//表示显示从系统启动到现在的 CPU 使用率,值为 0xffff。
CPUP_ALL_TIME = 0xffff /**< Display CPU usage from system startup to now, the value is 0xffff. */
};
@ -149,6 +178,7 @@ enum {
* @see LOS_HistoryTaskCpuUsage | LOS_AllCpuUsage
* @since Huawei LiteOS V100R001C00
*/
//获取历史系统CPU使用率。参数 mode 是用来指定获取 CPU 使用率的时间范围或者其他相关设置。
extern UINT32 LOS_HistorySysCpuUsage(UINT32 mode);
/**
@ -182,6 +212,9 @@ extern UINT32 LOS_HistorySysCpuUsage(UINT32 mode);
* @see LOS_HistorySysCpuUsage
* @since Huawei LiteOS V100R001C00
*/
/*用于获取历史任务的CPU使用率。
taskId ID
mode CPU使*/
extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskId, UINT32 mode);
/**
@ -224,6 +257,10 @@ extern UINT32 LOS_HistoryTaskCpuUsage(UINT32 taskId, UINT32 mode);
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @since Huawei LiteOS V100R001C00
*/
/*用于获取系统中所有CPU的使用率信息。
maxNum CPUcpupInfo CPU使
mode CPU使
flag */
extern UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT32 mode, UINT16 flag);
/**
@ -244,6 +281,10 @@ extern UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT32 mode,
* <ul><li>los_cpup.h: the header file that contains the API declaration.</li></ul>
* @since Huawei LiteOS V100R001C00
*/
/*LOS_CpupReset 函数会遍历系统中所有任务和中断,
CPU 使
CPU 使*/
extern VOID LOS_CpupReset(VOID);
#ifdef __cplusplus

@ -62,11 +62,12 @@ extern "C" {
* <ul><li>los_err.h: the header file that contains the API declaration.</li></ul>
* @since Huawei LiteOS V100R001C00
*/
typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName,
UINT32 lineNo,
UINT32 errorNo,
UINT32 paraLen,
VOID *para);
//LOS_ERRORHANDLE_FUNC 是一个函数指针类型,它指向一个函数,该函数具有以下特征:
typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName,//表示发生错误的文件名。
UINT32 lineNo,//表示发生错误的行号。
UINT32 errorNo,//表示错误代码或错误号。
UINT32 paraLen,//表示附加参数的长度。
VOID *para);//表示附加参数的指针。
/**
* @ingroup los_err
@ -88,6 +89,15 @@ typedef VOID (*LOS_ERRORHANDLE_FUNC)(CHAR *fileName,
* <ul><li>los_err.h: the header file that contains the API declaration.</li></ul>
* @since Huawei LiteOS V100R001C00
*/
/*函数的作用是处理错误。当程序运行过程中发生错误时,
CHAR *fileName
UINT32 lineNo
UINT32 errorNo
UINT32 paraLen
VOID *para*/
extern UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo,
UINT32 errorNo, UINT32 paraLen,
VOID *para);

@ -46,31 +46,31 @@ extern "C" {
* @ingroup los_errno
* OS error code flag. It is a 24-bit unsigned integer. Its value is 0x000000U.
*/
#define LOS_ERRNO_OS_ID (0x00U << 16)
#define LOS_ERRNO_OS_ID (0x00U << 16)//宏定义为 0x00U << 16表示操作系统相关的错误码。
/**
* @ingroup los_errno
* Define the error level as informative. It is a 32-bit unsigned integer. Its value is 0x00000000U.
*/
#define LOS_ERRTYPE_NORMAL (0x00U << 24)
#define LOS_ERRTYPE_NORMAL (0x00U << 24)//宏定义表示错误级别为 "informative"(信息级别),其值为 0x00U << 24。
/**
* @ingroup los_errno
* Define the error level as warning. It is a 32-bit unsigned integer. Its value is 0x01000000U.
*/
#define LOS_ERRTYPE_WARN (0x01U << 24)
#define LOS_ERRTYPE_WARN (0x01U << 24)//宏定义表示错误级别为 "warning"(警告级别),其值为 0x01U << 24。
/**
* @ingroup los_errno
* Define the error level as critical. It is a 32-bit unsigned integer. Its value is 0x02000000U.
*/
#define LOS_ERRTYPE_ERROR (0x02U << 24)
#define LOS_ERRTYPE_ERROR (0x02U << 24)//宏定义表示错误级别为 "critical"(严重级别),其值为 0x02U << 24。
/**
* @ingroup los_errno
* Define the error level as fatal. It is a 32-bit unsigned integer. Its value is 0x03000000U.
*/
#define LOS_ERRTYPE_FATAL (0x03U << 24)
#define LOS_ERRTYPE_FATAL (0x03U << 24)//宏定义表示错误级别为 "fatal"(致命级别),其值为 0x03U << 24。
/**
* @ingroup los_errno
@ -82,6 +82,14 @@ extern "C" {
* <li>0-7 bits indicate the error code number. It is specified by ERRNO.</li>
* </ul>
*/
/*用于生成操作系统致命错误码。
LOS_ERRTYPE_FATAL "fatal" 0x03U << 24
LOS_ERRNO_OS_ID 0x00U << 16
(UINT32)(MID) << 8 MID 8
(UINT32)(ERRNO)
LOS_ERRNO_OS_FATAL
LOS_ERRTYPE_FATAL+ LOS_ERRNO_OS_ID+ MID+ ERRNO
便*/
#define LOS_ERRNO_OS_FATAL(MID, ERRNO) \
(LOS_ERRTYPE_FATAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO)))
@ -95,6 +103,15 @@ extern "C" {
* <li>0-7 bits indicate the error code number. It is specified by ERRNO.</li>
* </ul>
*/
/*这段代码定义了一个宏 LOS_ERRNO_OS_ERROR用于生成操作系统严重错误码。
使
LOS_ERRTYPE_ERROR "critical" 0x02U << 24
LOS_ERRNO_OS_ID 0x00U << 16
(UINT32)(MID) << 8 MID 8
(UINT32)(ERRNO)
LOS_ERRNO_OS_ERROR
LOS_ERRTYPE_ERROR+ LOS_ERRNO_OS_ID+ MID+ ERRNO
便*/
#define LOS_ERRNO_OS_ERROR(MID, ERRNO) \
(LOS_ERRTYPE_ERROR | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO)))
@ -108,6 +125,15 @@ extern "C" {
* <li>0-7 bits indicate the error code number. It is specified by ERRNO.</li>
* </ul>
*/
/*这段代码定义了一个宏 LOS_ERRNO_OS_WARN用于生成操作系统警告错误码。
使
LOS_ERRTYPE_WARN "warning" 0x01U << 24
LOS_ERRNO_OS_ID 0x00U << 16
(UINT32)(MID) << 8 MID 8
(UINT32)(ERRNO)
LOS_ERRNO_OS_WARN
LOS_ERRTYPE_WARN+ LOS_ERRNO_OS_ID+ MID+ ERRNO
便*/
#define LOS_ERRNO_OS_WARN(MID, ERRNO) \
(LOS_ERRTYPE_WARN | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO)))
@ -121,13 +147,29 @@ extern "C" {
* <li>0-7 bits indicate the error code number. It is specified by ERRNO.</li>
* </ul>
*/
/*这段代码定义了一个宏 LOS_ERRNO_OS_NORMAL用于生成操作系统普通错误码。
使
LOS_ERRTYPE_NORMAL "normal" 0x00U << 24
LOS_ERRNO_OS_ID 0x00U << 16
(UINT32)(MID) << 8 MID 8
(UINT32)(ERRNO)
LOS_ERRNO_OS_NORMAL
LOS_ERRTYPE_NORMAL+ LOS_ERRNO_OS_ID+ MID+ ERRNO
便*/
#define LOS_ERRNO_OS_NORMAL(MID, ERRNO) \
(LOS_ERRTYPE_NORMAL | LOS_ERRNO_OS_ID | ((UINT32)(MID) << 8) | ((UINT32)(ERRNO)))
/**
* @ingroup los_errno
* Define the ID of each module in kernel. The ID is used in error code.
* ID ID
*/
/*这段代码定义了一个枚举类型 LOS_MODULE_ID它包含了一系列的模块标识符及其对应的数值。
LOS_MOD_SYS 0x0LOS_MOD_MEM 0x1
LOS_MOD_BUTT
使便使
使 LOS_MOD_SYS
使*/
enum LOS_MOUDLE_ID {
LOS_MOD_SYS = 0x0, /**< System ID. Its value is 0x0. */
LOS_MOD_MEM = 0x1, /**< Dynamic memory module ID. Its value is 0x1. */

@ -47,19 +47,19 @@ extern "C" {
* @ingroup los_event
* Event reading mode: The task waits for all its expected events to occur.
*/
#define LOS_WAITMODE_AND 4U
#define LOS_WAITMODE_AND 4U//该模式表示任务等待所有期望的事件发生。也就是说,任务只有当所有的事件都发生时才会继续执行。
/**
* @ingroup los_event
* Event reading mode: The task waits for any of its expected events to occur.
*/
#define LOS_WAITMODE_OR 2U
#define LOS_WAITMODE_OR 2U//该模式表示任务等待任何一个期望的事件发生。也就是说,任务只要有任何一个事件发生就会继续执行。
/**
* @ingroup los_event
* Event reading mode: The event flag is immediately cleared after the event is read.
*/
#define LOS_WAITMODE_CLR 1U
#define LOS_WAITMODE_CLR 1U//该模式表示在事件被读取后立即清除事件标志。也就是说,一旦任务读取了事件,事件标志就会被清除。
/**
* @ingroup los_event
@ -69,6 +69,14 @@ extern "C" {
* Value: 0x02001c00.
*
* Solution: Set bits excluding bit 25 of the event mask to events.
* LOS_ERRNO_EVENT_SETBIT_INVALID
使 LOS_ERRNO_OS_ERROR
LOS_MOD_EVENT
0x00
使便
*/
#define LOS_ERRNO_EVENT_SETBIT_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x00)
@ -81,6 +89,13 @@ extern "C" {
* Solution: Increase the waiting time for event reading, or make another task write a
* mask for the event.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_TIMEOUT表示事件读取超时。同样地该宏定义中也使用了 LOS_ERRNO_OS_ERROR 宏,表示该错误码属于操作系统的错误码,并且在事件模块内部的具体编号是 0x01。
*/
#define LOS_ERRNO_EVENT_READ_TIMEOUT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x01)
/**
@ -92,6 +107,13 @@ extern "C" {
*
* Solution: Pass in a valid EVENTMASK value.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_EVENTMASK_INVALID表示事件掩码无效。
使 LOS_ERRNO_OS_ERROR
0x02
*/
#define LOS_ERRNO_EVENT_EVENTMASK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x02)
/**
@ -102,6 +124,15 @@ extern "C" {
*
* Solution: Read the event in a task.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_IN_INTERRUPT表示在中断中进行事件读取。
使 LOS_ERRNO_OS_ERROR
0x03
*/
#define LOS_ERRNO_EVENT_READ_IN_INTERRUPT LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x03)
/**
@ -115,6 +146,15 @@ extern "C" {
*
* Solution: Pass in a valid flag value.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_FLAGS_INVALID表示事件标志无效。
使 LOS_ERRNO_OS_ERROR
0x04
使
*/
#define LOS_ERRNO_EVENT_FLAGS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x04)
/**
@ -125,6 +165,15 @@ extern "C" {
*
* Solution: Unlock the task and read the event.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_IN_LOCK表示在锁定状态下进行事件读取。
使 LOS_ERRNO_OS_ERROR
0x05
*/
#define LOS_ERRNO_EVENT_READ_IN_LOCK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x05)
/**
@ -135,6 +184,14 @@ extern "C" {
*
* Solution: Check whether the input parameter is null.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_PTR_NULL表示传入的指针为空指针。
使 LOS_ERRNO_OS_ERROR
0x06
访
*/
#define LOS_ERRNO_EVENT_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x06)
/**
@ -147,6 +204,15 @@ extern "C" {
* Solution: Read the event in a vailid task.
* @deprecated This error code is obsolete since LiteOS 5.0.0.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK
使 LOS_ERRNO_OS_ERROR
0x07
*/
#define LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x07)
/**
@ -157,12 +223,29 @@ extern "C" {
*
* Solution: Check whether the event list is not empty.
*/
/*这段代码定义了一个错误码 LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY
使 LOS_ERRNO_OS_ERROR
0x08
线使
*/
#define LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY LOS_ERRNO_OS_ERROR(LOS_MOD_EVENT, 0x08)
/**
* @ingroup los_event
* Event control structure
*/
/*这段代码定义了一个名为 tagEvent 的结构体,其中包含两个成员变量:
uwEventID
stEventList
typedef struct tagEvent EVENT_CB_S
EVENT_CB_S PEVENT_CB_S
使
*/
typedef struct tagEvent {
UINT32 uwEventID; /**< Event mask in the event control block,
indicating the event that has been logically processed. */
@ -187,6 +270,15 @@ typedef struct tagEvent {
* @see LOS_EventClear
* @since Huawei LiteOS V100R001C00
*/
/*UINT32 LOS_EventInit(PEVENT_CB_S eventCB) 是 LiteOS 操作系统中的一个函数,
eventCB EVENT_CB_S
UINT32
LOS_OK
LOS_EventInit 使
使*/
extern UINT32 LOS_EventInit(PEVENT_CB_S eventCB);
/**
@ -223,6 +315,25 @@ extern UINT32 LOS_EventInit(PEVENT_CB_S eventCB);
* @see LOS_EventRead | LOS_EventWrite
* @since Huawei LiteOS V100R001C00
*/
/*UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode) 是 LiteOS 操作系统中的一个函数,用于轮询事件。
:
eventId ID
eventMask
mode
OS_EVENT_OR
OS_EVENT_AND
UINT32
LOS_OK
LOS_EventPoll
ID eventId LOS_OK
LOS_ERRNO_EVENT_UNAVAILABLE
使
*/
extern UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode);
/**
@ -263,6 +374,24 @@ extern UINT32 LOS_EventPoll(UINT32 *eventId, UINT32 eventMask, UINT32 mode);
* @see LOS_EventPoll | LOS_EventWrite
* @since Huawei LiteOS V100R001C00
*/
/*UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
LiteOS
:
eventCB EVENT_CB_S
eventMask
mode
OS_EVENT_OR
OS_EVENT_AND
timeout
UINT32
LOS_OK
LOS_EventRead
LOS_OK
使
*/
extern UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout);
/**
@ -311,6 +440,17 @@ extern UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events);
* @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite
* @since Huawei LiteOS V100R001C00
*/
/*UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events) 是 LiteOS 操作系统中的一个函数,用于写入事件。
:
eventCB EVENT_CB_S
events
UINT32
LOS_OK
LOS_EventWrite
1
使
*/
extern UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events);
/**
@ -333,6 +473,22 @@ extern UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events);
* @see LOS_EventPoll | LOS_EventRead | LOS_EventWrite
* @since Huawei LiteOS V100R001C00
*/
/*UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB) 是 LiteOS 操作系统中的一个函数,用于销毁事件控制块。
:
eventCB EVENT_CB_S
UINT32
LOS_OK
LOS_EventDestroy
使
LOS_EventDestroy
使
*/
extern UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB);
#ifdef __cplusplus

@ -61,6 +61,23 @@ extern "C" {
* los_exc.h: the header file that contains the API declaration.
* @since Huawei LiteOS V100R001C00
*/
/*LOS_Panic(const CHAR *fmt, ...) 是 LiteOS 操作系统中的一个函数,用于触发系统崩溃。
:
fmt
... fmt
LOS_Panic
LOS_Panic 使使
*/
VOID LOS_Panic(const CHAR *fmt, ...);
/**
@ -79,8 +96,22 @@ VOID LOS_Panic(const CHAR *fmt, ...);
* los_exc.h: the header file that contains the API declaration.
* @since Huawei LiteOS V200R005C10
*/
/*VOID LOS_BackTrace(VOID) 是 LiteOS 操作系统中的函数,用于获取当前线程的函数调用栈信息。
LOS_BackTrace 线
LOS_BackTrace
LOS_BackTrace
使*/
extern VOID LOS_BackTrace(VOID);
#define OsBackTrace LOS_BackTrace
//宏定义将 OsBackTrace 替换为 LOS_BackTrace意味着在代码中使用 OsBackTrace 时,实际上是调用 LOS_BackTrace 函数。
/**
* @ingroup los_exc
@ -99,9 +130,28 @@ extern VOID LOS_BackTrace(VOID);
* los_exc.h: the header file that contains the API declaration.
* @since Huawei LiteOS V100R001C00
*/
/*VOID LOS_TaskBackTrace(UINT32 taskID) 是 LiteOS 操作系统中的函数,用于获取指定任务的函数调用栈信息。
:
taskID ID
LOS_TaskBackTrace
LOS_TaskBackTrace
LOS_TaskBackTrace
使
IDID
*/
extern VOID LOS_TaskBackTrace(UINT32 taskID);
#define OsTaskBackTrace LOS_TaskBackTrace
//宏定义将 OsTaskBackTrace 替换为 LOS_TaskBackTrace意味着在代码中使用 OsTaskBackTrace 时,实际上是调用 LOS_TaskBackTrace 函数。
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
/**
* @ingroup los_exc
@ -122,7 +172,14 @@ extern VOID LOS_TaskBackTrace(UINT32 taskID);
* <ul><li>los_exc.h: the header file that contains the type definition.</li></ul>
* @since Huawei LiteOS V200R005C10
*/
/*这是一个函数指针类型的定义。它定义了一个名为 LogReadWriteFunc 的函数指针类型,
VOID
UINTPTR startAddrUINT32 spaceUINT32 rwFlag CHAR *buf
便使*/
typedef VOID (*LogReadWriteFunc)(UINTPTR startAddr, UINT32 space, UINT32 rwFlag, CHAR *buf);
/*这是一个宏定义,将 log_read_write_fn 替换为 LogReadWriteFunc。
API使
log_read_write_fn LogReadWriteFunc*/
#define log_read_write_fn LogReadWriteFunc /* old API since V200R002C00, please avoid use of it */
/**
@ -146,6 +203,22 @@ typedef VOID (*LogReadWriteFunc)(UINTPTR startAddr, UINT32 space, UINT32 rwFlag,
* <ul><li>los_exc.h: the header file that contains the API declaration.</li></ul>
* @since Huawei LiteOS V200R002C00
*/
/*函数 LOS_ExcInfoRegHook 是在 LiteOS 操作系统中的一个函数。它的作用是设置异常信息寄存器的回调钩子函数。
startAddr
space
buf
hook LogReadWriteFunc
LiteOS LOS_ExcInfoRegHook
LOS_ExcInfoRegHook
hook
便*/
VOID LOS_ExcInfoRegHook(UINTPTR startAddr, UINT32 space, CHAR *buf, LogReadWriteFunc hook);
#endif

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save