diff --git a/arch/arm/arm/src/los_dispatch.S b/arch/arm/arm/src/los_dispatch.S index 8fd88bf0d800964f1e71b06755cdf33b6245b38d..8b0f41c445c6f9e01ccc2c078cbd6f9691a3fac7 100644 --- a/arch/arm/arm/src/los_dispatch.S +++ b/arch/arm/arm/src/los_dispatch.S @@ -254,30 +254,30 @@ OsKernelTaskLoad: @内核任务的加载 ADD SP, SP, #4 @sp=SP+4 LDMFD SP!, {LR, PC}^ @返回地址赋给pc指针 -OsIrqHandler: +OsIrqHandler: @中断处理 SUB LR, LR, #4 /* push r0-r3 to irq stack */ STMFD SP, {R0-R3} SUB R0, SP, #(4 * 4) - MRS R1, SPSR + MRS R1, SPSR @获取程序状态控制寄存器 MOV R2, LR /* disable irq, switch to svc mode */ - CPSID i, #0x13 + CPSID i, #0x13 @禁止中断,切换到SVC模式 /* push spsr and pc in svc stack */ STMFD SP!, {R1, R2} STMFD SP, {LR} - AND R3, R1, #CPSR_MASK_MODE - CMP R3, #CPSR_USER_MODE - BNE OsIrqFromKernel + AND R3, R1, #CPSR_MASK_MODE + CMP R3, #CPSR_USER_MODE @中断是否发生在用户模式 + BNE OsIrqFromKernel @中断不发生在用户模式下则跳转到OsIrqFromKernel /* push user sp, lr in svc stack */ STMFD SP, {R13, R14}^ -OsIrqFromKernel: +OsIrqFromKernel: @从内核发起中断 /* from svc not need save sp and lr */ SUB SP, SP, #(2 * 4) diff --git a/arch/arm/arm/src/los_hwi.c b/arch/arm/arm/src/los_hwi.c index f121a533e3c74cef9132a272da64e4d57209d59c..755e341e368beb9b059f9bac33d31fc759f7c946 100644 --- a/arch/arm/arm/src/los_hwi.c +++ b/arch/arm/arm/src/los_hwi.c @@ -161,7 +161,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数 *intCnt = *intCnt + 1; #ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断 - OsCpupIrqStart(); + OsCpupIrqStart();//开始统计本次中断处理还是时间 #endif #ifdef LOSCFG_KERNEL_TICKLESS @@ -191,10 +191,10 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数 *intCnt = *intCnt - 1; //@note_why 这里没看明白为什么要 -1 #ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断 - OsCpupIrqEnd(intNum); + OsCpupIrqEnd(intNum);//结束统计本次中断处理还是时间 #endif } -//copy 硬中断参数 +//申请内核空间拷贝硬中断参数 STATIC HWI_ARG_T OsHwiCpIrqParam(const HwiIrqParam *irqParam) { HwiIrqParam *paramByAlloc = NULL; @@ -236,7 +236,7 @@ STATIC UINT32 OsHwiCreateNoShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, if (g_hwiForm[hwiNum].pfnHook == NULL) { g_hwiForm[hwiNum].pfnHook = hwiHandler;//记录上回调函数 - retParam = OsHwiCpIrqParam(irqParam);//参数copy一份出来记录 + retParam = OsHwiCpIrqParam(irqParam);//获取中断处理函数的参数 if (retParam == LOS_NOK) { HWI_UNLOCK(intSave); return OS_ERRNO_HWI_NO_MEMORY; @@ -307,7 +307,7 @@ STATIC UINT32 OsHwiDelShared(HWI_HANDLE_T hwiNum, const HwiIrqParam *irqParam) HWI_UNLOCK(intSave); return LOS_OK; } -//创建一个共享硬件中断 +//创建一个共享硬件中断,共享中断就是一个中断能触发多个响应函数 STATIC UINT32 OsHwiCreateShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler, const HwiIrqParam *irqParam) { @@ -321,39 +321,39 @@ STATIC UINT32 OsHwiCreateShared(HWI_HANDLE_T hwiNum, HWI_MODE_T hwiMode, return OS_ERRNO_HWI_SHARED_ERROR; } - HWI_LOCK(intSave); + HWI_LOCK(intSave);//中断自旋锁 - hwiForm = &g_hwiForm[hwiNum]; + hwiForm = &g_hwiForm[hwiNum];//获取中断处理项 if ((hwiForm->pstNext != NULL) && ((modeResult == 0) || (!(hwiForm->uwParam & IRQF_SHARED)))) { HWI_UNLOCK(intSave); return OS_ERRNO_HWI_SHARED_ERROR; } - while (hwiForm->pstNext != NULL) { - hwiForm = hwiForm->pstNext; - hwiParam = (HwiIrqParam *)(hwiForm->uwParam); - if (hwiParam->pDevId == irqParam->pDevId) { + while (hwiForm->pstNext != NULL) {//pstNext指向 共享中断的各处理函数节点,此处一直撸到最后一个 + hwiForm = hwiForm->pstNext;//找下一个中断 + hwiParam = (HwiIrqParam *)(hwiForm->uwParam);//获取中断参数,用于检测该设备ID是否已经有中断处理函数 + if (hwiParam->pDevId == irqParam->pDevId) {//设备ID一致时,说明设备对应的中断处理函数已经存在了. HWI_UNLOCK(intSave); return OS_ERRNO_HWI_ALREADY_CREATED; } } - hwiFormNode = (HwiHandleForm *)LOS_MemAlloc(m_aucSysMem0, sizeof(HwiHandleForm)); + hwiFormNode = (HwiHandleForm *)LOS_MemAlloc(m_aucSysMem0, sizeof(HwiHandleForm));//创建一个中断处理节点 if (hwiFormNode == NULL) { HWI_UNLOCK(intSave); return OS_ERRNO_HWI_NO_MEMORY; } - hwiFormNode->uwParam = OsHwiCpIrqParam(irqParam); + hwiFormNode->uwParam = OsHwiCpIrqParam(irqParam);//获取中断处理函数的参数 if (hwiFormNode->uwParam == LOS_NOK) { HWI_UNLOCK(intSave); (VOID)LOS_MemFree(m_aucSysMem0, hwiFormNode); return OS_ERRNO_HWI_NO_MEMORY; } - hwiFormNode->pfnHook = hwiHandler; - hwiFormNode->pstNext = (struct tagHwiHandleForm *)NULL; - hwiForm->pstNext = hwiFormNode; + hwiFormNode->pfnHook = hwiHandler;//绑定中断处理函数 + hwiFormNode->pstNext = (struct tagHwiHandleForm *)NULL;//指定下一个中断为NULL,用于后续遍历找到最后一个中断项(见于以上 while (hwiForm->pstNext != NULL)处) + hwiForm->pstNext = hwiFormNode;//共享中断 if ((irqParam != NULL) && (irqParam->pName != NULL)) { g_hwiFormName[hwiNum] = (CHAR *)irqParam->pName; @@ -373,7 +373,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID)//硬件中断初始化 { UINT32 hwiNum; - for (hwiNum = 0; hwiNum < OS_HWI_MAX_NUM; hwiNum++) { + for (hwiNum = 0; hwiNum < OS_HWI_MAX_NUM; hwiNum++) {//初始化中断向量表,默认128个中断 g_hwiForm[hwiNum].pfnHook = NULL; g_hwiForm[hwiNum].uwParam = 0; g_hwiForm[hwiNum].pstNext = NULL; diff --git a/arch/arm/include/los_hwi.h b/arch/arm/include/los_hwi.h index c790af85fd38824a1262fb42c210374e984f6b36..b50d735800811ce8494bfeb70c99d4f76debe038 100644 --- a/arch/arm/include/los_hwi.h +++ b/arch/arm/include/los_hwi.h @@ -105,7 +105,7 @@ extern size_t g_intCount[]; * Value: 0x02000901 * * Solution: Pass in a valid non-null hardware interrupt handling function. - */ + */ //创建中断时,传入的中断处理程序指针为空 #define OS_ERRNO_HWI_PROC_FUNC_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x01) /** @@ -115,7 +115,7 @@ extern size_t g_intCount[]; * Value: 0x02000902 * * Solution: Increase the configured maximum number of supported hardware interrupts. - */ + */ //无可用中断资源 #define OS_ERRNO_HWI_CB_UNAVAILABLE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x02) /** @@ -125,7 +125,7 @@ extern size_t g_intCount[]; * Value: 0x02000903 * * Solution: Expand the configured memory. - */ + */ //创建中断时,出现内存不足的情况 #define OS_ERRNO_HWI_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x03) /** @@ -135,7 +135,7 @@ extern size_t g_intCount[]; * Value: 0x02000904 * * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. - */ + */ //创建中断时,发现要注册的中断号已经创建 #define OS_ERRNO_HWI_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x04) /** @@ -145,7 +145,7 @@ extern size_t g_intCount[]; * Value: 0x02000905 * * Solution: Ensure that the interrupt priority is valid. - */ + */ //创建中断时,传入的中断优先级无效 #define OS_ERRNO_HWI_PRIO_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x05) /** @@ -156,7 +156,7 @@ extern size_t g_intCount[]; * * Solution: The interrupt creation mode can be only set to OS_HWI_MODE_COMM or OS_HWI_MODE_FAST of * which the value can be 0 or 1. - */ + */ //中断模式无效 #define OS_ERRNO_HWI_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x06) /** @@ -166,7 +166,7 @@ extern size_t g_intCount[]; * Value: 0x02000907 * * Solution: Check whether the interrupt specified by the passed-in interrupt number has already been created. - */ + */ //创建硬中断时,发现要注册的中断号,已经创建为快速中断 #define OS_ERRNO_HWI_FASTMODE_ALREADY_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x07) /** @@ -176,7 +176,7 @@ extern size_t g_intCount[]; * Value: 0x02000908 * * * Solution: Do not call the API during an interrupt. - */ + */ //接口在中断中调用 #define OS_ERRNO_HWI_INTERR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x08) /** @@ -187,7 +187,7 @@ extern size_t g_intCount[]; * * * Solution: Check the input params hwiMode and irqParam of LOS_HwiCreate or * LOS_HwiDelete whether adapt the current hwi. - */ + */ //中断共享出现错误 #define OS_ERRNO_HWI_SHARED_ERROR LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x09) /** @@ -197,7 +197,7 @@ extern size_t g_intCount[]; * Value: 0x0200090a * * * Solution: Check the interrupt Arg, Arg should not be NULL and pDevId should not be NULL. - */ + */ //注册中断入参有误 #define OS_ERRNO_HWI_ARG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0a) /** @@ -207,7 +207,7 @@ extern size_t g_intCount[]; * Value: 0x0200090b * * * Solution: Check the hwi number or devid, make sure the hwi number or devid need to delete. - */ + */ //中断共享情况下,删除中断时,中断号对应的链表中,无法匹配到相应的设备ID #define OS_ERRNO_HWI_HWINUM_UNCREATE LOS_ERRNO_OS_ERROR(LOS_MOD_HWI, 0x0b) /** @@ -252,7 +252,7 @@ typedef VOID (*HWI_PROC_FUNC)(VOID); typedef struct tagHwiHandleForm { HWI_PROC_FUNC pfnHook; //中断处理函数 HWI_ARG_T uwParam; //中断处理函数参数 - struct tagHwiHandleForm *pstNext; //节点,指向下一个中断 + struct tagHwiHandleForm *pstNext; //节点,指向下一个中断,用于共享中断的情况 } HwiHandleForm; typedef struct tagIrqParam { //中断参数 diff --git a/kernel/base/core/los_process.c b/kernel/base/core/los_process.c index 06e80f3bbe0ba198194dabe1d15ee7b4d5ca7221..a7b670fd9d1dde44e2a337ef78ef9644f5da895b 100644 --- a/kernel/base/core/los_process.c +++ b/kernel/base/core/los_process.c @@ -878,7 +878,7 @@ STATIC UINT32 OsProcessCreateInit(LosProcessCB *processCB, UINT32 flags, const C #endif #ifdef LOSCFG_KERNEL_CPUP //CPU性能统计开关,默认是打开的 - OsCpupSet(processCB->processID); + OsCpupSet(processCB->processID);//初始化进程性能统计 #endif return LOS_OK; diff --git a/kernel/base/core/los_tick.c b/kernel/base/core/los_tick.c index a924c5569835babec1c9c711e8e08b9179680546..9d372362bfda73258d396e7f5c8cb5173aea2e1c 100644 --- a/kernel/base/core/los_tick.c +++ b/kernel/base/core/los_tick.c @@ -61,7 +61,7 @@ LITE_OS_SEC_TEXT VOID OsTickHandler(VOID) { UINT32 intSave; - TICK_LOCK(intSave); + TICK_LOCK(intSave);//tick自旋锁 g_tickCount[ArchCurrCpuid()]++;// 累加当前CPU核tick数 TICK_UNLOCK(intSave); diff --git a/kernel/base/ipc/los_futex.c b/kernel/base/ipc/los_futex.c index 7d95d12ef00a604847d652dff234fbd86344e64f..8d14c21b2ccbbfa35c9e8e53cf549a8febc37559 100644 --- a/kernel/base/ipc/los_futex.c +++ b/kernel/base/ipc/los_futex.c @@ -43,7 +43,7 @@ extern "C" { #endif #endif /* __cplusplus */ -// Futex 是Fast Userspace muTexes的缩写 就是快速用户空间互斥体 ,注解简称它会 快锁 +// Futex 是Fast Userspace muTexes的缩写 就是快速用户空间互斥体 ,注解简称它为快锁 #define OS_FUTEX_FROM_FUTEXLIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, futexList) //从 futexList 位置拿节点FutexNode #define OS_FUTEX_FROM_QUEUELIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, queueList) //从 queueList 位置拿节点FutexNode// #define OS_FUTEX_KEY_BASE USER_ASPACE_BASE diff --git a/kernel/extended/cpup/los_cpup.c b/kernel/extended/cpup/los_cpup.c index 4fcdefa9deed8973226738c058fb35d738a81473..de8b17229c620ae7f1df9aa2ab5583a1b9867d29 100644 --- a/kernel/extended/cpup/los_cpup.c +++ b/kernel/extended/cpup/los_cpup.c @@ -1,557 +1,557 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * 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_cpup_pri.h" -#include "los_process_pri.h" -#include "los_base.h" -#include "los_swtmr.h" - -#ifdef __cplusplus -#if __cplusplus -extern "C" { -#endif /* __cplusplus */ -#endif /* __cplusplus */ - -#ifdef LOSCFG_KERNEL_CPUP - -LITE_OS_SEC_BSS STATIC UINT16 swtmrID; -LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg = 0; -LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL; -LITE_OS_SEC_BSS STATIC UINT16 cpupMaxNum; -LITE_OS_SEC_BSS STATIC UINT16 hisPos = 0; /* current Sampling point of historyTime */ -LITE_OS_SEC_BSS STATIC UINT64 cpuHistoryTime[OS_CPUP_HISTORY_RECORD_NUM + 1]; - -LITE_OS_SEC_BSS STATIC UINT64 startCycles = 0; -#ifdef LOSCFG_CPUP_INCLUDE_IRQ -LITE_OS_SEC_BSS STATIC UINT64 timeInIrqPerProcessSwitch[LOSCFG_KERNEL_CORE_NUM]; -LITE_OS_SEC_BSS STATIC UINT64 intTimeStart[LOSCFG_KERNEL_CORE_NUM]; -#endif - -#define OS_CPUP_UNUSED 0x0U -#define OS_CPUP_USED 0x1U -#define HIGH_BITS 32 - -#define CPUP_PRE_POS(pos) (((pos) == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : ((pos) - 1)) -#define CPUP_POST_POS(pos) (((pos) == (OS_CPUP_HISTORY_RECORD_NUM - 1)) ? 0 : ((pos) + 1)) - -LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID) -{ - UINT16 prevPos; - UINT16 loop; - UINT32 pid; - UINT32 intSave; - UINT64 curCycle; - - SCHEDULER_LOCK(intSave); - - curCycle = OsGetCpuCycle(); - prevPos = hisPos; - hisPos = CPUP_POST_POS(hisPos); - cpuHistoryTime[prevPos] = curCycle; - - for (loop = 0; loop < cpupMaxNum; loop++) { - g_cpup[loop].historyTime[prevPos] = g_cpup[loop].allTime; - } - - for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { - pid = OsCpuProcessIDGetUnsafe(loop); - /* reacquire the cycle to prevent flip */ - curCycle = OsGetCpuCycle(); - g_cpup[pid].historyTime[prevPos] += curCycle - g_cpup[pid].startTime; -#ifdef LOSCFG_CPUP_INCLUDE_IRQ - g_cpup[pid].historyTime[prevPos] -= timeInIrqPerProcessSwitch[loop]; -#endif - } - - SCHEDULER_UNLOCK(intSave); -} - -LITE_OS_SEC_TEXT_INIT VOID OsCpupGuardCreator(VOID) -{ - (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD, - (SWTMR_PROC_FUNC)OsCpupGuard, &swtmrID, 0); - - (VOID)LOS_SwtmrStart(swtmrID); -} - -/* - * Description: initialization of CPUP - * Return : LOS_OK or Error Information - */ -LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit(VOID) -{ - UINT32 size; - - cpupMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT; -#ifdef LOSCFG_CPUP_INCLUDE_IRQ - cpupMaxNum += OS_HWI_MAX_NUM; -#endif - - /* every process has only one record, and it won't operated at the same time */ - size = cpupMaxNum * sizeof(OsCpupCB); - g_cpup = (OsCpupCB *)LOS_MemAlloc(m_aucSysMem0, size); - if (g_cpup == NULL) { - return LOS_ERRNO_CPUP_NO_MEMORY; - } - - (VOID)memset_s(g_cpup, size, 0, size); - cpupInitFlg = 1; - return LOS_OK; -} - -LITE_OS_SEC_TEXT VOID OsCpupSet(UINT32 id) -{ - g_cpup[id].id = id; - g_cpup[id].status = OS_CPUP_USED; -} - -LITE_OS_SEC_TEXT VOID OsCpupClean(UINT32 id) -{ - (VOID)memset_s((VOID *)&g_cpup[id], sizeof(OsCpupCB), 0, sizeof(OsCpupCB)); -} - -LITE_OS_SEC_TEXT_INIT VOID LOS_CpupReset(VOID) -{ - UINT32 cpupIndex; - UINT32 maxNum = cpupMaxNum; - UINT16 loop; - UINT64 curCycle; - UINT32 intSave; - - if (g_cpup == NULL) { - return; - } - - cpupInitFlg = 0; - intSave = LOS_IntLock(); - (VOID)LOS_SwtmrStop(swtmrID); - curCycle = OsGetCpuCycle(); - - for (loop = 0; loop < (OS_CPUP_HISTORY_RECORD_NUM + 1); loop++) { - cpuHistoryTime[loop] = curCycle; - } - - for (cpupIndex = 0; cpupIndex < maxNum; cpupIndex++) { - g_cpup[cpupIndex].startTime = curCycle; - g_cpup[cpupIndex].allTime = curCycle; - for (loop = 0; loop < (OS_CPUP_HISTORY_RECORD_NUM + 1); loop++) { - g_cpup[cpupIndex].historyTime[loop] = curCycle; - } - } - -#ifdef LOSCFG_CPUP_INCLUDE_IRQ - for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { - timeInIrqPerProcessSwitch[loop] = 0; - } -#endif - - (VOID)LOS_SwtmrStart(swtmrID); - LOS_IntRestore(intSave); - cpupInitFlg = 1; - - return; -} - -LITE_OS_SEC_TEXT_MINOR VOID OsSetCpuCycle(UINT64 cycles) -{ - startCycles = cycles; - return; -} - -/* - * Description: get current cycles count - * Return : current cycles count - */ -LITE_OS_SEC_TEXT_MINOR UINT64 OsGetCpuCycle(VOID) -{ - UINT32 high; - UINT32 low; - UINT64 cycles; - - LOS_GetCpuCycle(&high, &low); - cycles = ((UINT64)high << HIGH_BITS) + low; - if (startCycles == 0) { - startCycles = cycles; - } - - /* - * The cycles should keep growing, if the checking failed, - * it mean LOS_GetCpuCycle has the problem which should be fixed. - */ - LOS_ASSERT(cycles >= startCycles); - - return (cycles - startCycles); -} - -#ifdef LOSCFG_CPUP_INCLUDE_IRQ -STATIC VOID OsRemoveInterTimeFromPorcess(UINT32 runPID) -{ - UINT16 loop; - UINT32 pid; - - for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { - pid = OsCpuProcessIDGetUnsafe(loop); - if (pid != runPID) { - continue; - } - - g_cpup[runPID].allTime -= timeInIrqPerProcessSwitch[loop]; - timeInIrqPerProcessSwitch[loop] = 0; - } -} -#endif - -/* - * Description: start process to get cycles count in current process begining - */ -LITE_OS_SEC_TEXT_MINOR STATIC VOID OsProcessCycleStart(VOID) -{ - UINT32 pid; - - if (cpupInitFlg == 0) { - return; - } - - pid = LOS_GetCurrProcessID(); - g_cpup[pid].id = pid; - g_cpup[pid].startTime = OsGetCpuCycle(); - - return; -} - -/* - * Description: quit process and get cycle count - */ -LITE_OS_SEC_TEXT_MINOR STATIC VOID OsProcessCycleEnd(VOID) -{ - UINT16 runTaskCount; - UINT32 runPID; - UINT64 cpuCycle; - LosProcessCB *runProcess = NULL; - - if (cpupInitFlg == 0) { - return; - } - - runProcess = OsCurrProcessGet(); - runPID = runProcess->processID; - if (g_cpup[runPID].startTime == 0) { - return; - } - - cpuCycle = OsGetCpuCycle(); - runTaskCount = OS_PROCESS_GET_RUNTASK_COUNT(runProcess->processStatus); - g_cpup[runPID].allTime += (cpuCycle - g_cpup[runPID].startTime) * runTaskCount; -#ifdef LOSCFG_CPUP_INCLUDE_IRQ - OsRemoveInterTimeFromPorcess(runPID); -#endif - g_cpup[runPID].startTime = 0; - - return; -} - -/* - * Description: start process to get cycles count in current process ending - */ -LITE_OS_SEC_TEXT_MINOR VOID OsProcessCycleEndStart(UINT32 newID, UINT16 runTaskCount) -{ - UINT32 runPID; - UINT64 cpuCycle; - OsCpupCB *cpup = NULL; - - if (cpupInitFlg == 0) { - return; - } - - LOS_ASSERT(runTaskCount != 0); - - cpuCycle = OsGetCpuCycle(); - runPID = LOS_GetCurrProcessID(); - cpup = &g_cpup[runPID]; - if (cpup->startTime != 0) { - cpup->allTime += (cpuCycle - cpup->startTime) * runTaskCount; - cpup->startTime = cpuCycle; -#ifdef LOSCFG_CPUP_INCLUDE_IRQ - OsRemoveInterTimeFromPorcess(runPID); -#endif - } - - cpup = &g_cpup[newID]; - cpup->id = newID; - cpup->startTime = cpuCycle; - - return; -} - -LITE_OS_SEC_TEXT_MINOR STATIC VOID OsCpupGetPos(UINT16 mode, UINT16 *curPosPointer, UINT16 *prePosPointer) -{ - UINT16 curPos; - UINT16 tmpPos; - UINT16 prePos; - - tmpPos = hisPos; - curPos = CPUP_PRE_POS(tmpPos); - - /* - * The current postion has nothing to do with the CPUP modes, - * however, the previous postion differs. - */ - switch (mode) { - case CPUP_LAST_ONE_SECONDS: - prePos = CPUP_PRE_POS(curPos); - break; - case CPUP_LAST_TEN_SECONDS: - prePos = tmpPos; - break; - case CPUP_ALL_TIME: - /* fall-through */ - default: - prePos = OS_CPUP_HISTORY_RECORD_NUM; - break; - } - - *curPosPointer = curPos; - *prePosPointer = prePos; - - return; -} - -LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsCpuUsageParaCheck(UINT32 pid) -{ - if (cpupInitFlg == 0) { - return LOS_ERRNO_CPUP_NO_INIT; - } - - if (OS_PID_CHECK_INVALID(pid)) { - return LOS_ERRNO_CPUP_PID_INVALID; - } - - /* weather the process is created */ - if (g_cpup[pid].id != pid) { - return LOS_ERRNO_CPUP_PROCESS_NO_CREATED; - } - - if (g_cpup[pid].status == OS_CPUP_UNUSED) { - return LOS_ERRNO_CPUP_PROCESS_NO_CREATED; - } - - return LOS_OK; -} - -LITE_OS_SEC_TEXT UINT32 OsHistorySysCpuUsageUnsafe(UINT16 mode) -{ - UINT64 cpuCycleAll; - UINT64 idleCycleAll; - UINT32 cpup = 0; - UINT16 pos; - UINT16 prePos; - UINT32 idlePID; - - if (cpupInitFlg == 0) { - return LOS_ERRNO_CPUP_NO_INIT; - } - - OsProcessCycleEnd(); - - OsCpupGetPos(mode, &pos, &prePos); - cpuCycleAll = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; - - idlePID = OsGetIdleProcessID(); - idleCycleAll = g_cpup[idlePID].historyTime[pos] - g_cpup[idlePID].historyTime[prePos]; - - if (cpuCycleAll) { - cpup = (LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * idleCycleAll) / cpuCycleAll)); - } - - OsProcessCycleStart(); - return cpup; -} - -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode) -{ - UINT32 cpup; - UINT32 intSave; - - /* get end time of current process */ - SCHEDULER_LOCK(intSave); - cpup = OsHistorySysCpuUsageUnsafe(mode); - SCHEDULER_UNLOCK(intSave); - return cpup; -} - -LITE_OS_SEC_TEXT UINT32 OsHistoryProcessCpuUsageUnsafe(UINT32 pid, UINT16 mode) -{ - UINT64 cpuCycleAll; - UINT64 cpuCycleCurProcess; - UINT16 pos; - UINT16 prePos; - UINT32 cpup = 0; - UINT32 ret; - OsCpupCB *processCpup = &g_cpup[pid]; - - ret = OsCpuUsageParaCheck(pid); - if (ret != LOS_OK) { - return ret; - } - - OsProcessCycleEnd(); - - OsCpupGetPos(mode, &pos, &prePos); - cpuCycleAll = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; - cpuCycleCurProcess = processCpup->historyTime[pos] - processCpup->historyTime[prePos]; - if (cpuCycleAll) { - cpup = (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * cpuCycleCurProcess) / cpuCycleAll); - } - - OsProcessCycleStart(); - - return cpup; -} - -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryProcessCpuUsage(UINT32 pid, UINT16 mode) -{ - UINT32 cpup; - UINT32 intSave; - - SCHEDULER_LOCK(intSave); - cpup = OsHistoryProcessCpuUsageUnsafe(pid, mode); - SCHEDULER_UNLOCK(intSave); - - return cpup; -} - -LITE_OS_SEC_TEXT UINT32 OsAllCpuUsageUnsafe(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT16 mode, UINT16 flag) -{ - UINT16 loop; - UINT16 index; - UINT16 pos; - UINT16 prePos; - UINT64 cpuCycleAll; - UINT64 cpuCycleCurProcess; - UINT16 numTmpMax = maxNum; - UINT16 numTmpMin = 0; - UINT16 numMax = g_processMaxNum; - - if (cpupInitFlg == 0) { - return LOS_ERRNO_CPUP_NO_INIT; - } - - if (cpupInfo == NULL) { - return LOS_ERRNO_CPUP_PROCESS_PTR_NULL; - } - - if (maxNum == 0) { - return LOS_ERRNO_CPUP_MAXNUM_INVALID; - } - -#ifdef LOSCFG_CPUP_INCLUDE_IRQ - if (flag == 0) { - numTmpMax += g_processMaxNum; - numTmpMin += g_processMaxNum; - numMax = cpupMaxNum; - } -#endif - - if (numTmpMax > numMax) { - numTmpMax = numMax; - } - - OsProcessCycleEnd(); - - OsCpupGetPos(mode, &pos, &prePos); - cpuCycleAll = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; - - for (loop = numTmpMin; loop < numTmpMax; loop++) { - if (g_cpup[loop].status == OS_CPUP_UNUSED) { - continue; - } - - index = loop - numTmpMin; - cpuCycleCurProcess = g_cpup[loop].historyTime[pos] - g_cpup[loop].historyTime[prePos]; - cpupInfo[index].usStatus = g_cpup[loop].status; - - if (cpuCycleAll) { - cpupInfo[index].uwUsage = (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * cpuCycleCurProcess) / cpuCycleAll); - } - } - - OsProcessCycleStart(); - return LOS_OK; -} -// shell cpup 命令,查看所有CPU的使用情况 89.9% -LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT16 mode, UINT16 flag) -{ - UINT32 intSave; - UINT32 ret; - - SCHEDULER_LOCK(intSave); - ret = OsAllCpuUsageUnsafe(maxNum, cpupInfo, mode, flag);//所有CPU使用情况 - SCHEDULER_UNLOCK(intSave); - - return ret; -} - -#ifdef LOSCFG_CPUP_INCLUDE_IRQ -LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(VOID) -{ - UINT32 high; - UINT32 low; - - LOS_GetCpuCycle(&high, &low); - intTimeStart[ArchCurrCpuid()] = ((UINT64)high << HIGH_BITS) + low; - return; -} - -LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT32 intNum) -{ - UINT32 high; - UINT32 low; - UINT64 intTimeEnd; - UINT32 cpuID = ArchCurrCpuid(); - - LOS_GetCpuCycle(&high, &low); - intTimeEnd = ((UINT64)high << HIGH_BITS) + low; - - g_cpup[g_processMaxNum + intNum].id = intNum; - g_cpup[g_processMaxNum + intNum].status = OS_CPUP_USED; - timeInIrqPerProcessSwitch[cpuID] += (intTimeEnd - intTimeStart[cpuID]); - g_cpup[g_processMaxNum + intNum].allTime += (intTimeEnd - intTimeStart[cpuID]); - - return; -} -#endif - -#endif /* LOSCFG_KERNEL_CPUP */ -#ifdef __cplusplus -#if __cplusplus -} -#endif /* __cplusplus */ -#endif /* __cplusplus */ +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * 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_cpup_pri.h" +#include "los_process_pri.h" +#include "los_base.h" +#include "los_swtmr.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#ifdef LOSCFG_KERNEL_CPUP + +LITE_OS_SEC_BSS STATIC UINT16 swtmrID; +LITE_OS_SEC_BSS STATIC UINT16 cpupInitFlg = 0; +LITE_OS_SEC_BSS OsCpupCB *g_cpup = NULL;//监测CPU使用情况 +LITE_OS_SEC_BSS STATIC UINT16 cpupMaxNum;//监测最大数量 包括(进程+中断号) +LITE_OS_SEC_BSS STATIC UINT16 hisPos = 0; /* current Sampling point of historyTime */ +LITE_OS_SEC_BSS STATIC UINT64 cpuHistoryTime[OS_CPUP_HISTORY_RECORD_NUM + 1]; + +LITE_OS_SEC_BSS STATIC UINT64 startCycles = 0;//开始周期 +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +LITE_OS_SEC_BSS STATIC UINT64 timeInIrqPerProcessSwitch[LOSCFG_KERNEL_CORE_NUM];//统计各CPU核花在切换中断上的时间 +LITE_OS_SEC_BSS STATIC UINT64 intTimeStart[LOSCFG_KERNEL_CORE_NUM];//统计各CPU核花在处理中断上的时间 +#endif + +#define OS_CPUP_UNUSED 0x0U +#define OS_CPUP_USED 0x1U +#define HIGH_BITS 32 + +#define CPUP_PRE_POS(pos) (((pos) == 0) ? (OS_CPUP_HISTORY_RECORD_NUM - 1) : ((pos) - 1)) +#define CPUP_POST_POS(pos) (((pos) == (OS_CPUP_HISTORY_RECORD_NUM - 1)) ? 0 : ((pos) + 1)) + +LITE_OS_SEC_TEXT_INIT VOID OsCpupGuard(VOID) +{ + UINT16 prevPos; + UINT16 loop; + UINT32 pid; + UINT32 intSave; + UINT64 curCycle; + + SCHEDULER_LOCK(intSave); + + curCycle = OsGetCpuCycle(); + prevPos = hisPos; + hisPos = CPUP_POST_POS(hisPos); + cpuHistoryTime[prevPos] = curCycle; + + for (loop = 0; loop < cpupMaxNum; loop++) { + g_cpup[loop].historyTime[prevPos] = g_cpup[loop].allTime; + } + + for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { + pid = OsCpuProcessIDGetUnsafe(loop); + /* reacquire the cycle to prevent flip */ + curCycle = OsGetCpuCycle(); + g_cpup[pid].historyTime[prevPos] += curCycle - g_cpup[pid].startTime; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + g_cpup[pid].historyTime[prevPos] -= timeInIrqPerProcessSwitch[loop]; +#endif + } + + SCHEDULER_UNLOCK(intSave); +} + +LITE_OS_SEC_TEXT_INIT VOID OsCpupGuardCreator(VOID) +{ + (VOID)LOS_SwtmrCreate(LOSCFG_BASE_CORE_TICK_PER_SECOND, LOS_SWTMR_MODE_PERIOD, + (SWTMR_PROC_FUNC)OsCpupGuard, &swtmrID, 0); + + (VOID)LOS_SwtmrStart(swtmrID); +} + +/* + * Description: initialization of CPUP + * Return : LOS_OK or Error Information + */ +LITE_OS_SEC_TEXT_INIT UINT32 OsCpupInit(VOID) +{ + UINT32 size; + + cpupMaxNum = LOSCFG_BASE_CORE_PROCESS_LIMIT; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + cpupMaxNum += OS_HWI_MAX_NUM;//最大中断号数量 默认 128 +#endif + + /* every process has only one record, and it won't operated at the same time *///每个进程只有一条记录,不会同时运行 + size = cpupMaxNum * sizeof(OsCpupCB); + g_cpup = (OsCpupCB *)LOS_MemAlloc(m_aucSysMem0, size); + if (g_cpup == NULL) { + return LOS_ERRNO_CPUP_NO_MEMORY; + } + + (VOID)memset_s(g_cpup, size, 0, size); + cpupInitFlg = 1;//已完成初始化标识 + return LOS_OK; +} +//设置 进程/中断 占用CPU统计 +LITE_OS_SEC_TEXT VOID OsCpupSet(UINT32 id) +{ + g_cpup[id].id = id; + g_cpup[id].status = OS_CPUP_USED; +} +//清除 进程/中断 占用CPU统计 +LITE_OS_SEC_TEXT VOID OsCpupClean(UINT32 id) +{ + (VOID)memset_s((VOID *)&g_cpup[id], sizeof(OsCpupCB), 0, sizeof(OsCpupCB)); +} +//重置 进程/中断 占用CPU统计 +LITE_OS_SEC_TEXT_INIT VOID LOS_CpupReset(VOID) +{ + UINT32 cpupIndex; + UINT32 maxNum = cpupMaxNum; + UINT16 loop; + UINT64 curCycle; + UINT32 intSave; + + if (g_cpup == NULL) { + return; + } + + cpupInitFlg = 0; + intSave = LOS_IntLock(); + (VOID)LOS_SwtmrStop(swtmrID); + curCycle = OsGetCpuCycle(); + + for (loop = 0; loop < (OS_CPUP_HISTORY_RECORD_NUM + 1); loop++) { + cpuHistoryTime[loop] = curCycle; + } + + for (cpupIndex = 0; cpupIndex < maxNum; cpupIndex++) { + g_cpup[cpupIndex].startTime = curCycle; + g_cpup[cpupIndex].allTime = curCycle; + for (loop = 0; loop < (OS_CPUP_HISTORY_RECORD_NUM + 1); loop++) { + g_cpup[cpupIndex].historyTime[loop] = curCycle; + } + } + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { + timeInIrqPerProcessSwitch[loop] = 0; + } +#endif + + (VOID)LOS_SwtmrStart(swtmrID); + LOS_IntRestore(intSave); + cpupInitFlg = 1; + + return; +} +//设置CPU周期 +LITE_OS_SEC_TEXT_MINOR VOID OsSetCpuCycle(UINT64 cycles) +{ + startCycles = cycles; + return; +} + +/* + * Description: get current cycles count + * Return : current cycles count + */ +LITE_OS_SEC_TEXT_MINOR UINT64 OsGetCpuCycle(VOID) +{ + UINT32 high; + UINT32 low; + UINT64 cycles; + + LOS_GetCpuCycle(&high, &low); + cycles = ((UINT64)high << HIGH_BITS) + low; + if (startCycles == 0) { + startCycles = cycles; + } + + /* + * The cycles should keep growing, if the checking failed, + * it mean LOS_GetCpuCycle has the problem which should be fixed. + */ + LOS_ASSERT(cycles >= startCycles); + + return (cycles - startCycles); +} + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +STATIC VOID OsRemoveInterTimeFromPorcess(UINT32 runPID) +{ + UINT16 loop; + UINT32 pid; + + for (loop = 0; loop < LOSCFG_KERNEL_CORE_NUM; loop++) { + pid = OsCpuProcessIDGetUnsafe(loop); + if (pid != runPID) { + continue; + } + + g_cpup[runPID].allTime -= timeInIrqPerProcessSwitch[loop]; + timeInIrqPerProcessSwitch[loop] = 0; + } +} +#endif + +/* + * Description: start process to get cycles count in current process begining + */ +LITE_OS_SEC_TEXT_MINOR STATIC VOID OsProcessCycleStart(VOID) +{ + UINT32 pid; + + if (cpupInitFlg == 0) { + return; + } + + pid = LOS_GetCurrProcessID(); + g_cpup[pid].id = pid; + g_cpup[pid].startTime = OsGetCpuCycle(); + + return; +} + +/* + * Description: quit process and get cycle count + */ +LITE_OS_SEC_TEXT_MINOR STATIC VOID OsProcessCycleEnd(VOID) +{ + UINT16 runTaskCount; + UINT32 runPID; + UINT64 cpuCycle; + LosProcessCB *runProcess = NULL; + + if (cpupInitFlg == 0) { + return; + } + + runProcess = OsCurrProcessGet(); + runPID = runProcess->processID; + if (g_cpup[runPID].startTime == 0) { + return; + } + + cpuCycle = OsGetCpuCycle(); + runTaskCount = OS_PROCESS_GET_RUNTASK_COUNT(runProcess->processStatus); + g_cpup[runPID].allTime += (cpuCycle - g_cpup[runPID].startTime) * runTaskCount; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + OsRemoveInterTimeFromPorcess(runPID); +#endif + g_cpup[runPID].startTime = 0; + + return; +} + +/* + * Description: start process to get cycles count in current process ending + */ +LITE_OS_SEC_TEXT_MINOR VOID OsProcessCycleEndStart(UINT32 newID, UINT16 runTaskCount) +{ + UINT32 runPID; + UINT64 cpuCycle; + OsCpupCB *cpup = NULL; + + if (cpupInitFlg == 0) { + return; + } + + LOS_ASSERT(runTaskCount != 0); + + cpuCycle = OsGetCpuCycle(); + runPID = LOS_GetCurrProcessID(); + cpup = &g_cpup[runPID]; + if (cpup->startTime != 0) { + cpup->allTime += (cpuCycle - cpup->startTime) * runTaskCount; + cpup->startTime = cpuCycle; +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + OsRemoveInterTimeFromPorcess(runPID); +#endif + } + + cpup = &g_cpup[newID]; + cpup->id = newID; + cpup->startTime = cpuCycle; + + return; +} + +LITE_OS_SEC_TEXT_MINOR STATIC VOID OsCpupGetPos(UINT16 mode, UINT16 *curPosPointer, UINT16 *prePosPointer) +{ + UINT16 curPos; + UINT16 tmpPos; + UINT16 prePos; + + tmpPos = hisPos; + curPos = CPUP_PRE_POS(tmpPos); + + /* + * The current postion has nothing to do with the CPUP modes, + * however, the previous postion differs. + */ + switch (mode) { + case CPUP_LAST_ONE_SECONDS: + prePos = CPUP_PRE_POS(curPos); + break; + case CPUP_LAST_TEN_SECONDS: + prePos = tmpPos; + break; + case CPUP_ALL_TIME: + /* fall-through */ + default: + prePos = OS_CPUP_HISTORY_RECORD_NUM; + break; + } + + *curPosPointer = curPos; + *prePosPointer = prePos; + + return; +} + +LITE_OS_SEC_TEXT_MINOR STATIC INLINE UINT32 OsCpuUsageParaCheck(UINT32 pid) +{ + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + if (OS_PID_CHECK_INVALID(pid)) { + return LOS_ERRNO_CPUP_PID_INVALID; + } + + /* weather the process is created */ + if (g_cpup[pid].id != pid) { + return LOS_ERRNO_CPUP_PROCESS_NO_CREATED; + } + + if (g_cpup[pid].status == OS_CPUP_UNUSED) { + return LOS_ERRNO_CPUP_PROCESS_NO_CREATED; + } + + return LOS_OK; +} + +LITE_OS_SEC_TEXT UINT32 OsHistorySysCpuUsageUnsafe(UINT16 mode) +{ + UINT64 cpuCycleAll; + UINT64 idleCycleAll; + UINT32 cpup = 0; + UINT16 pos; + UINT16 prePos; + UINT32 idlePID; + + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + OsProcessCycleEnd(); + + OsCpupGetPos(mode, &pos, &prePos); + cpuCycleAll = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + idlePID = OsGetIdleProcessID(); + idleCycleAll = g_cpup[idlePID].historyTime[pos] - g_cpup[idlePID].historyTime[prePos]; + + if (cpuCycleAll) { + cpup = (LOS_CPUP_PRECISION - (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * idleCycleAll) / cpuCycleAll)); + } + + OsProcessCycleStart(); + return cpup; +} + +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistorySysCpuUsage(UINT16 mode) +{ + UINT32 cpup; + UINT32 intSave; + + /* get end time of current process */ + SCHEDULER_LOCK(intSave); + cpup = OsHistorySysCpuUsageUnsafe(mode); + SCHEDULER_UNLOCK(intSave); + return cpup; +} +//获取参数进程的CPU历史使用情况 +LITE_OS_SEC_TEXT UINT32 OsHistoryProcessCpuUsageUnsafe(UINT32 pid, UINT16 mode) +{ + UINT64 cpuCycleAll; + UINT64 cpuCycleCurProcess; + UINT16 pos; + UINT16 prePos; + UINT32 cpup = 0; + UINT32 ret; + OsCpupCB *processCpup = &g_cpup[pid]; + + ret = OsCpuUsageParaCheck(pid);//参数检查 + if (ret != LOS_OK) { + return ret; + } + + OsProcessCycleEnd(); + + OsCpupGetPos(mode, &pos, &prePos); + cpuCycleAll = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + cpuCycleCurProcess = processCpup->historyTime[pos] - processCpup->historyTime[prePos]; + if (cpuCycleAll) { + cpup = (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * cpuCycleCurProcess) / cpuCycleAll); + } + + OsProcessCycleStart();//进程 + + return cpup; +} +//获取参数进程的CPU历史使用情况 +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_HistoryProcessCpuUsage(UINT32 pid, UINT16 mode) +{ + UINT32 cpup; + UINT32 intSave; + + SCHEDULER_LOCK(intSave);//禁止调度 + cpup = OsHistoryProcessCpuUsageUnsafe(pid, mode); + SCHEDULER_UNLOCK(intSave);//恢复调度 + + return cpup; +} +//获取所有CPU的使用情况 +LITE_OS_SEC_TEXT UINT32 OsAllCpuUsageUnsafe(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT16 mode, UINT16 flag) +{ + UINT16 loop; + UINT16 index; + UINT16 pos; + UINT16 prePos; + UINT64 cpuCycleAll; + UINT64 cpuCycleCurProcess; + UINT16 numTmpMax = maxNum; + UINT16 numTmpMin = 0; + UINT16 numMax = g_processMaxNum; + + if (cpupInitFlg == 0) { + return LOS_ERRNO_CPUP_NO_INIT; + } + + if (cpupInfo == NULL) { + return LOS_ERRNO_CPUP_PROCESS_PTR_NULL; + } + + if (maxNum == 0) { + return LOS_ERRNO_CPUP_MAXNUM_INVALID; + } + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ + if (flag == 0) { + numTmpMax += g_processMaxNum; + numTmpMin += g_processMaxNum; + numMax = cpupMaxNum; + } +#endif + + if (numTmpMax > numMax) { + numTmpMax = numMax; + } + + OsProcessCycleEnd(); + + OsCpupGetPos(mode, &pos, &prePos); + cpuCycleAll = cpuHistoryTime[pos] - cpuHistoryTime[prePos]; + + for (loop = numTmpMin; loop < numTmpMax; loop++) { + if (g_cpup[loop].status == OS_CPUP_UNUSED) { + continue; + } + + index = loop - numTmpMin; + cpuCycleCurProcess = g_cpup[loop].historyTime[pos] - g_cpup[loop].historyTime[prePos]; + cpupInfo[index].usStatus = g_cpup[loop].status; + + if (cpuCycleAll) { + cpupInfo[index].uwUsage = (UINT32)((LOS_CPUP_SINGLE_CORE_PRECISION * cpuCycleCurProcess) / cpuCycleAll); + } + } + + OsProcessCycleStart(); + return LOS_OK; +} +// shell cpup 命令,查看所有CPU的使用情况 89.9% +LITE_OS_SEC_TEXT_MINOR UINT32 LOS_AllCpuUsage(UINT16 maxNum, CPUP_INFO_S *cpupInfo, UINT16 mode, UINT16 flag) +{ + UINT32 intSave; + UINT32 ret; + + SCHEDULER_LOCK(intSave); + ret = OsAllCpuUsageUnsafe(maxNum, cpupInfo, mode, flag);//所有CPU使用情况 + SCHEDULER_UNLOCK(intSave); + + return ret; +} + +#ifdef LOSCFG_CPUP_INCLUDE_IRQ +LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqStart(VOID) +{ + UINT32 high; + UINT32 low; + + LOS_GetCpuCycle(&high, &low);//获取CPU周期 + intTimeStart[ArchCurrCpuid()] = ((UINT64)high << HIGH_BITS) + low;// + return; +} +//统计中断结束数据 +LITE_OS_SEC_TEXT_MINOR VOID OsCpupIrqEnd(UINT32 intNum) +{ + UINT32 high; + UINT32 low; + UINT64 intTimeEnd; + UINT32 cpuID = ArchCurrCpuid(); + + LOS_GetCpuCycle(&high, &low); + intTimeEnd = ((UINT64)high << HIGH_BITS) + low; + + g_cpup[g_processMaxNum + intNum].id = intNum;//(进程ID/中断号) + g_cpup[g_processMaxNum + intNum].status = OS_CPUP_USED;//使用了CPU监测 + timeInIrqPerProcessSwitch[cpuID] += (intTimeEnd - intTimeStart[cpuID]);//累计CPU的耗时 + g_cpup[g_processMaxNum + intNum].allTime += (intTimeEnd - intTimeStart[cpuID]);//累计(进程/中断号)的耗时 + + return; +} +#endif + +#endif /* LOSCFG_KERNEL_CPUP */ +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/platform/hw/arm/interrupt/gic/gic_v2.c b/platform/hw/arm/interrupt/gic/gic_v2.c index 2e5dd5b3590b900cfc570e6cc490e8fcb5c31cad..eaa795aa699feb45bf09aa1247903cb57014bf41 100644 --- a/platform/hw/arm/interrupt/gic/gic_v2.c +++ b/platform/hw/arm/interrupt/gic/gic_v2.c @@ -37,7 +37,7 @@ STATIC_ASSERT(OS_USER_HWI_MAX <= 1020, "hwi max is too large!"); #ifdef LOSCFG_PLATFORM_BSP_GIC_V2 -STATIC UINT32 g_curIrqNum = 0; +STATIC UINT32 g_curIrqNum = 0; //记录当前中断号 #if (LOSCFG_KERNEL_SMP == YES) /* @@ -53,12 +53,12 @@ STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter) GIC_REG_32(GICD_SGIR) = val; } - +//向指定核发送核间中断 VOID HalIrqSendIpi(UINT32 target, UINT32 ipi) { GicWriteSgi(ipi, target, 0); } - +//设置中断的亲和性,即设置中断在固定核响应(该函数仅在SMP模式下支持) VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask) { UINT32 offset = vector / 4; @@ -67,7 +67,7 @@ VOID HalIrqSetAffinity(UINT32 vector, UINT32 cpuMask) GIC_REG_8(GICD_ITARGETSR(offset) + index) = cpuMask; } #endif - +//获取当前中断号 UINT32 HalCurIrqGet(VOID) { return g_curIrqNum; @@ -90,7 +90,7 @@ VOID HalIrqUnmask(UINT32 vector) GIC_REG_32(GICD_ISENABLER(vector >> 5)) = 1U << (vector % 32); } - +//挂起中断 VOID HalIrqPending(UINT32 vector) { if ((vector > OS_USER_HWI_MAX) || (vector < OS_USER_HWI_MIN)) { @@ -155,7 +155,7 @@ VOID HalIrqInit(VOID) VOID HalIrqHandler(VOID) { UINT32 iar = GIC_REG_32(GICC_IAR); - UINT32 vector = iar & 0x3FFU; + UINT32 vector = iar & 0x3FFU;//计算中断向量号 /* * invalid irq number, mainly the spurious interrupts 0x3ff, @@ -167,7 +167,7 @@ VOID HalIrqHandler(VOID) } g_curIrqNum = vector; - OsInterrupt(vector); + OsInterrupt(vector);//调用上层中断处理函数 /* use orignal iar to do the EOI */ GIC_REG_32(GICC_EOIR) = iar; diff --git a/platform/hw/arm/interrupt/gic/gic_v3.c b/platform/hw/arm/interrupt/gic/gic_v3.c index 36a34d925eb3dbdb11e5adf75d4ed4d5aaef155a..96eb56d1583c8e9d04d43d5cb3d22c77d26fcd0d 100644 --- a/platform/hw/arm/interrupt/gic/gic_v3.c +++ b/platform/hw/arm/interrupt/gic/gic_v3.c @@ -78,7 +78,7 @@ GICv3控制器由以下部分组成: #ifdef LOSCFG_PLATFORM_BSP_GIC_V3 -STATIC UINT32 g_curIrqNum = 0; +STATIC UINT32 g_curIrqNum = 0; //记录当前中断号 STATIC INLINE UINT64 MpidrToAffinity(UINT64 mpidr) { @@ -363,10 +363,10 @@ UINT32 HalIrqSetPrio(UINT32 vector, UINT8 priority) VOID HalIrqInitPercpu(VOID) { INT32 idx; - UINT32 cpu = ArchCurrCpuid(); + UINT32 cpu = ArchCurrCpuid();//获取当前CPU /* GICR init */ - GicrSetWaker(cpu); + GicrSetWaker(cpu);//设置CPU为唤醒状态 GicrSetGroup(cpu); GicWaitForRwp(GICR_CTLR(cpu)); @@ -387,8 +387,8 @@ VOID HalIrqInitPercpu(VOID) #ifdef LOSCFG_KERNEL_SMP /* unmask ipi interrupts */ - HalIrqUnmask(LOS_MP_IPI_WAKEUP); - HalIrqUnmask(LOS_MP_IPI_HALT); + HalIrqUnmask(LOS_MP_IPI_WAKEUP);//恢复CPU唤醒信号 + HalIrqUnmask(LOS_MP_IPI_HALT);//恢复CPU停止信号 #endif } //硬中断初始化 @@ -404,16 +404,16 @@ VOID HalIrqInit(VOID) /* set externel interrupts to be level triggered, active low. */ for (i = 32; i < OS_HWI_MAX_NUM; i += 16) {//将外部中断设置为电平触发,低电平有效 - GIC_REG_32(GICD_ICFGR(i / 16)) = 0; + GIC_REG_32(GICD_ICFGR(i / 16)) = 0;//设置16个私有外设中断 } - + //SPI是串行外设接口(Serial Peripheral Interface)的缩写 /* config distributer, mask and clear all spis, set group x */ - for (i = 32; i < OS_HWI_MAX_NUM; i += 32) { - GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff; - GIC_REG_32(GICD_ICPENDR(i / 32)) = 0xffffffff; - GIC_REG_32(GICD_IGRPMODR(i / 32)) = 0; + for (i = 32; i < OS_HWI_MAX_NUM; i += 32) {//配置分配器,屏蔽并清除所有SPI,设置组 + GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff;//屏蔽中断使能寄存器 + GIC_REG_32(GICD_ICPENDR(i / 32)) = 0xffffffff;////屏蔽中断挂起寄存器 + GIC_REG_32(GICD_IGRPMODR(i / 32)) = 0;//清除中断组模式寄存器 - GicdSetGroup(i); + GicdSetGroup(i);//设置中断组 } /* set spi priority as default */ @@ -424,7 +424,7 @@ VOID HalIrqInit(VOID) GicWaitForRwp(GICD_CTLR); /* disable all interrupts. */ - for (i = 0; i < OS_HWI_MAX_NUM; i += 32) { + for (i = 0; i < OS_HWI_MAX_NUM; i += 32) {//让所有中断失效 GIC_REG_32(GICD_ICENABLER(i / 32)) = 0xffffffff; } diff --git a/platform/hw/include/gic_common.h b/platform/hw/include/gic_common.h index 2dee41aad4faea35591f7b355fe508479563b035..ec2da19b2765f410e7a8f025ea1398f80a841d96 100644 --- a/platform/hw/include/gic_common.h +++ b/platform/hw/include/gic_common.h @@ -128,7 +128,7 @@ enum { /* * The preemption level is up to 128, and the maximum value corresponding to the interrupt priority is 254 [7:1]. * If the GIC_MAX_INTERRUPT_PREEMPTION_LEVEL is 0, the minimum priority is 0xff. - */ + *///中断优先级 最高中断优先级为 0 ,最低优先级为 255 #define MIN_INTERRUPT_PRIORITY ((UINT8)((GIC_MAX_INTERRUPT_PREEMPTION_LEVEL - 1) << PRIORITY_SHIFT)) #endif diff --git a/platform/uart/dw-3.0.8a/uart.c b/platform/uart/dw-3.0.8a/uart.c index 0e3da4ac545cac215247e8a7154a87e37b01447a..6b5a046a5f9ed5ef842b0b216064f3cec868e5c1 100644 --- a/platform/uart/dw-3.0.8a/uart.c +++ b/platform/uart/dw-3.0.8a/uart.c @@ -1,215 +1,215 @@ -/* - * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. - * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. - * - * 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_event.h" -#include "hisoc/uart.h" - - -EVENT_CB_S g_uartEvent; -#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS -#ifdef LOSCFG_SHELL -#define UART_BUF 128 -static UINT8 g_uart_buf[UART_BUF]; -extern void shellCmdLineParse(CHAR c, pf_OUTPUT pf_put); -#endif -#endif -UINT8 uart_getc(void) -{ - UINT8 ch = 0; - - while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x08)) { /*lint !e40*/ - LOS_Msleep(100); - } - /* receive one char */ - READ_UINT8(ch, UART_REG_BASE + UART_DR); - return ch; -} - -#if defined(LOSCFG_COREDUMP) || defined(LOSCFG_LLTSER) -UINT8 uart_getc_interrupt(void) -{ - UINT8 ch = 0; - - while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x08)) { /*lint !e40*/ - } - /* receive one char */ - READ_UINT8(ch, UART_REG_BASE + UART_DR); - return ch; -} -#endif -/* send */ -char uart_putc (char c) -{ - /* Wait until THRE is empyt */ - while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x02)); /*lint !e40*/ - /* send one char */ - WRITE_UINT8(c, UART_REG_BASE + UART_DR); - return c; -} - -unsigned int g_uart_fputc_en __attribute__ ((section(".data"))) = 1; -char uart_fputc(char c, void *f) -{ - if (g_uart_fputc_en == 1) { - if (c == '\n') { - uart_putc('\r'); /*lint !e534*/ - } - return (uart_putc(c)); - } else { - return 0; - } -} - -#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS -#ifdef LOSCFG_SHELL -static void uart_notice_adapt(void) -{ - LOS_EventWrite(&g_uartEvent, 0x112); -} - -void uart_get_raw(void) -{ - UINT8 ch; - static int cnt_ii = 0; - if (cnt_ii == 0) { - (VOID)memset_s(g_uart_buf, UART_BUF, 0, UART_BUF); - } - ch = uart_getc(); - g_uart_buf[cnt_ii] = ch; - cnt_ii++; - switch (cnt_ii) { - case 1: // only one char - if (ch != 27) { // un special - uart_notice_adapt(); - cnt_ii = 0; - } - break; - case 2: - if (ch != 91) { - uart_notice_adapt(); - cnt_ii = 0; - } - break; - case 3: - switch (ch) { - default: - case 'A': - case 'B': - case 'C': - case 'D': - { - uart_notice_adapt(); - cnt_ii = 0; - } - break; - case 51: - case 49: - case 52: - break; - } - break; - case 4: - { - uart_notice_adapt(); - cnt_ii = 0; - } - break; - default: - { - uart_notice_adapt(); - cnt_ii = 0; - } - break; - } -} -extern void dprintf(const char *fmt, ...); - -static void uart_irqhandle(void) -{ - UINT8 ch; - shellCmdLineParse(0, dprintf); -} - -int uart_hwiCreate(void) -{ - UINT32 uwRet = 0; - if (uwRet != LOS_HwiCreate(NUM_HAL_INTERRUPT_UART, 0xa0, 0, uart_irqhandle, 0)) { - return uwRet; - } - uart_interrupt_unmask(); - return 0; -} - -#endif -#endif -void uart_init() -{ - unsigned int temp; - unsigned int divider; - unsigned char dividerH, dividerL; - - /* disable UART1 FIFO */ - WRITE_UINT32(0, UART_REG_BASE + UART_FCR); /*lint !e40*/ - - /* reset and enable UART1 FIFO */ - WRITE_UINT32(0x7, UART_REG_BASE + UART_FCR); /*lint !e40*/ - - /* disable UART1 interrupt */ - WRITE_UINT32(0, UART_REG_BASE + UART_IER); /*lint !e40*/ - - /* enable DLL and DLH */ - WRITE_UINT32(0x80, UART_REG_BASE + UART_LCR); /*lint !e40*/ - /* Caculate devide */ - temp = 16 * CONSOLE_UART_BAUDRATE; - divider = CONFIG_UART_CLK_INPUT / temp; - dividerH = ((divider) & 0xff00) >> 8; - dividerL = ((divider) & 0x00ff); - - /* configure DLL and DLH */ - WRITE_UINT32(dividerL, UART_REG_BASE + UART_DLL); /*lint !e40*/ - WRITE_UINT32(dividerH, UART_REG_BASE + UART_DLH); /*lint !e40*/ - - /* disable DLL and DLH */ - WRITE_UINT32(0x0, UART_REG_BASE + UART_LCR); /*lint !e40*/ - - /* 8bit data, 1bit stop,even parity */ - WRITE_UINT32(0x1b, UART_REG_BASE + UART_LCR); /*lint !e40*/ - - /* enable UART1 */ - WRITE_UINT32(0x1, UART_REG_BASE + UART_IER); /*lint !e40*/ - - (VOID)LOS_EventInit(&g_uartEvent); -} - -void uart_interrupt_unmask(void) -{ - HalIrqUnmask(NUM_HAL_INTERRUPT_UART); -} +/* + * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved. + * + * 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_event.h" +#include "hisoc/uart.h" + + +EVENT_CB_S g_uartEvent; +#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS +#ifdef LOSCFG_SHELL +#define UART_BUF 128 +static UINT8 g_uart_buf[UART_BUF]; +extern void shellCmdLineParse(CHAR c, pf_OUTPUT pf_put); +#endif +#endif +UINT8 uart_getc(void) +{ + UINT8 ch = 0; + + while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x08)) { /*lint !e40*/ + LOS_Msleep(100); + } + /* receive one char */ + READ_UINT8(ch, UART_REG_BASE + UART_DR); + return ch; +} + +#if defined(LOSCFG_COREDUMP) || defined(LOSCFG_LLTSER) +UINT8 uart_getc_interrupt(void) +{ + UINT8 ch = 0; + + while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x08)) { /*lint !e40*/ + } + /* receive one char */ + READ_UINT8(ch, UART_REG_BASE + UART_DR); + return ch; +} +#endif +/* send */ +char uart_putc (char c) +{ + /* Wait until THRE is empyt */ + while (!(GET_UINT32(UART_REG_BASE + UART_USR) & 0x02)); /*lint !e40*/ + /* send one char */ + WRITE_UINT8(c, UART_REG_BASE + UART_DR); + return c; +} + +unsigned int g_uart_fputc_en __attribute__ ((section(".data"))) = 1; +char uart_fputc(char c, void *f) +{ + if (g_uart_fputc_en == 1) { + if (c == '\n') { + uart_putc('\r'); /*lint !e534*/ + } + return (uart_putc(c)); + } else { + return 0; + } +} + +#ifdef LOSCFG_PLATFORM_UART_WITHOUT_VFS +#ifdef LOSCFG_SHELL +static void uart_notice_adapt(void) +{ + LOS_EventWrite(&g_uartEvent, 0x112); +} + +void uart_get_raw(void) +{ + UINT8 ch; + static int cnt_ii = 0; + if (cnt_ii == 0) { + (VOID)memset_s(g_uart_buf, UART_BUF, 0, UART_BUF); + } + ch = uart_getc(); + g_uart_buf[cnt_ii] = ch; + cnt_ii++; + switch (cnt_ii) { + case 1: // only one char + if (ch != 27) { // un special + uart_notice_adapt(); + cnt_ii = 0; + } + break; + case 2: + if (ch != 91) { + uart_notice_adapt(); + cnt_ii = 0; + } + break; + case 3: + switch (ch) { + default: + case 'A': + case 'B': + case 'C': + case 'D': + { + uart_notice_adapt(); + cnt_ii = 0; + } + break; + case 51: + case 49: + case 52: + break; + } + break; + case 4: + { + uart_notice_adapt(); + cnt_ii = 0; + } + break; + default: + { + uart_notice_adapt(); + cnt_ii = 0; + } + break; + } +} +extern void dprintf(const char *fmt, ...); +//串口硬中断处理函数 +static void uart_irqhandle(void) +{ + UINT8 ch; + shellCmdLineParse(0, dprintf);//shell解析输入的内容 +} +//创建串口硬中断 +int uart_hwiCreate(void) +{ + UINT32 uwRet = 0; + if (uwRet != LOS_HwiCreate(NUM_HAL_INTERRUPT_UART, 0xa0, 0, uart_irqhandle, 0)) { + return uwRet; + } + uart_interrupt_unmask();//取消中断屏蔽 + return 0; +} + +#endif +#endif +void uart_init() +{ + unsigned int temp; + unsigned int divider; + unsigned char dividerH, dividerL; + + /* disable UART1 FIFO */ + WRITE_UINT32(0, UART_REG_BASE + UART_FCR); /*lint !e40*/ + + /* reset and enable UART1 FIFO */ + WRITE_UINT32(0x7, UART_REG_BASE + UART_FCR); /*lint !e40*/ + + /* disable UART1 interrupt */ + WRITE_UINT32(0, UART_REG_BASE + UART_IER); /*lint !e40*/ + + /* enable DLL and DLH */ + WRITE_UINT32(0x80, UART_REG_BASE + UART_LCR); /*lint !e40*/ + /* Caculate devide */ + temp = 16 * CONSOLE_UART_BAUDRATE; + divider = CONFIG_UART_CLK_INPUT / temp; + dividerH = ((divider) & 0xff00) >> 8; + dividerL = ((divider) & 0x00ff); + + /* configure DLL and DLH */ + WRITE_UINT32(dividerL, UART_REG_BASE + UART_DLL); /*lint !e40*/ + WRITE_UINT32(dividerH, UART_REG_BASE + UART_DLH); /*lint !e40*/ + + /* disable DLL and DLH */ + WRITE_UINT32(0x0, UART_REG_BASE + UART_LCR); /*lint !e40*/ + + /* 8bit data, 1bit stop,even parity */ + WRITE_UINT32(0x1b, UART_REG_BASE + UART_LCR); /*lint !e40*/ + + /* enable UART1 */ + WRITE_UINT32(0x1, UART_REG_BASE + UART_IER); /*lint !e40*/ + + (VOID)LOS_EventInit(&g_uartEvent);//初始化串口事件 +} +//取消串口中断屏蔽 +void uart_interrupt_unmask(void) +{ + HalIrqUnmask(NUM_HAL_INTERRUPT_UART);//参考见于 harmony\vendor\hisi\hi35xx\hi3516dv300\config\board\include\hisoc\uart.h +} diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 0438b86609f45f05d7bde99155291945d7f3c1b9..5beee871ce867155adbbdfcea311f7308f105c72 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,6 +1,6 @@ git add -A -git commit -m '鸿蒙内核源码分析(原子操作篇) | 是哪两条汇编指令在为原子操作保驾护航 ? - 百万汉字注解 + 百篇博客分析 -> 读透鸿蒙内核源码 +git commit -m '硬中断代码注释 + 百万汉字注解 + 百篇博客分析 -> 挖透鸿蒙内核源码 ' git push origin master