From d2d991944124cb548de7297d77ad5abf65c98acb Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Tue, 27 Oct 2020 07:00:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E6=A0=88=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E7=A9=BA=E9=97=B4=E5=85=A8=E6=99=AF=E5=9B=BE,CPU=E5=A4=9A?= =?UTF-8?q?=E6=A0=B8=E8=B0=83=E5=BA=A6=E9=83=A8=E5=88=86=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=20=E9=B8=BF=E8=92=99=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81?= =?UTF-8?q?=E5=88=86=E6=9E=90=E7=B3=BB=E5=88=97=20https://blog.csdn.net/ku?= =?UTF-8?q?angyufei=20https://my.oschina.net/u/3751245=20=E9=B8=BF?= =?UTF-8?q?=E8=92=99=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E7=89=88=20=E3=80=90=20CSDN=E4=BB=93=20|=20G?= =?UTF-8?q?itee=E4=BB=93=20|=20Github=E4=BB=93=20|=20Coding=E4=BB=93?= =?UTF-8?q?=E3=80=91=E5=9B=9B=E5=A4=A7=E4=BB=93=E5=BA=93=E6=AF=8F=E6=97=A5?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E6=9B=B4=E6=96=B0=20=E7=BB=99=E9=B8=BF?= =?UTF-8?q?=E8=92=99=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81=E9=80=90=E8=A1=8C?= =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E4=B8=AD=E6=96=87=E6=B3=A8=E9=87=8A=20,?= =?UTF-8?q?=E8=AE=A9=20HarmonyOS=20=E6=A5=9A=E6=A5=9A=E5=8A=A8=E4=BA=BA,?= =?UTF-8?q?=20=E4=BB=8E=E6=AD=A4=E4=B8=8D=E5=86=8D=E7=A5=9E=E7=A7=98.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arch/arm/arm/include/arch_config.h | 28 +++++++++++ arch/arm/arm/src/los_exc.c | 10 ++-- kernel/base/core/los_task.c | 78 +++++++++++++++-------------- kernel/base/include/los_vm_common.h | 4 +- kernel/base/include/los_vm_zone.h | 6 +-- kernel/base/misc/los_stackinfo.c | 14 +++--- kernel/base/mp/los_mp.c | 2 +- zzz/git/push.sh | 6 ++- 8 files changed, 90 insertions(+), 58 deletions(-) diff --git a/arch/arm/arm/include/arch_config.h b/arch/arm/arm/include/arch_config.h index 183164a0..cd10ccb7 100644 --- a/arch/arm/arm/include/arch_config.h +++ b/arch/arm/arm/include/arch_config.h @@ -67,6 +67,34 @@ #define OS_STACK_INIT 0xCACACACA //栈指针初始化值 0b 1010 1010 1010 /* Bit32 stack top magic number. */ #define OS_STACK_MAGIC_WORD 0xCCCCCCCC //用于栈顶值,可标识为栈是否被使用过,神奇的 "烫烫烫烫"的根源所在! 0b 1100 1100 1100 +/*************************************************************************** @note_pic +* 鸿蒙虚拟内存-栈空间运行时图 +* 鸿蒙源码分析系列篇: https://blog.csdn.net/kuangyufei + https://my.oschina.net/u/3751245 +**************************************************************************** +* + |-------------------| + | 0xCCCCCCCC |0x00000000 <---- stack top == OS_STACK_MAGIC_WORD + |-------------------| + | 0xCACACACA |0x00000004 == OS_STACK_INIT + |-------------------| + | 0xCACACACA |0x00000008 + |-------------------| + | 0xCACACACA |//1.一个栈初始化时 栈顶为 0xCCCCCCCC 其余空间全为 0xCACACACA 这样很容易通过值得比较知道栈有没有溢出 + |-------------------|//2.在虚拟地址的序列上 栈底是高于栈顶的 + | 0xCACACACA |//3.sp在初始位置是指向栈底的 + |-------------------|//4.还有多少0xCACACACA就代表使用的最高峰 peak used + | 0xCACACACA |//5.一旦栈顶不是0xCCCCCCCC,说明已经溢出了,检测栈的溢出就是通过 栈顶值是否等于0xCCCCCCCC + |-------------------| + | 0x89EF3245 | + |-------------------| + | 0x83 |0x0FFFFFF8 <--- sp + |-------------------| + | 0x75AB |0x0FFFFFFB + |-------------------| + | 0xC32F | + |-------------------|0x10000000 <---- stack bottom +*/ #ifdef LOSCFG_GDB #define OS_EXC_UNDEF_STACK_SIZE 512 diff --git a/arch/arm/arm/src/los_exc.c b/arch/arm/arm/src/los_exc.c index c951ba65..31a0a11f 100644 --- a/arch/arm/arm/src/los_exc.c +++ b/arch/arm/arm/src/los_exc.c @@ -108,10 +108,10 @@ STATIC UINT32 g_nextExcWaitCpu = INVALID_CPUID; STATIC const StackInfo g_excStack[] = { { &__undef_stack, OS_EXC_UNDEF_STACK_SIZE, "udf_stack" }, { &__abt_stack, OS_EXC_ABT_STACK_SIZE, "abt_stack" }, - { &__fiq_stack, OS_EXC_FIQ_STACK_SIZE, "fiq_stack" }, - { &__svc_stack, OS_EXC_SVC_STACK_SIZE, "svc_stack" }, - { &__irq_stack, OS_EXC_IRQ_STACK_SIZE, "irq_stack" }, - { &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } + { &__fiq_stack, OS_EXC_FIQ_STACK_SIZE, "fiq_stack" }, //快中断栈 + { &__svc_stack, OS_EXC_SVC_STACK_SIZE, "svc_stack" }, + { &__irq_stack, OS_EXC_IRQ_STACK_SIZE, "irq_stack" }, //中断请求栈 + { &__exc_stack, OS_EXC_STACK_SIZE, "exc_stack" } //运行栈 }; UINT32 OsGetSystemStatus(VOID) @@ -663,7 +663,7 @@ VOID BackTrace(UINT32 regFP) BackTraceSub(regFP); } - +//运行初始化 VOID OsExcInit(VOID) { OsExcStackInfoReg(g_excStack, sizeof(g_excStack) / sizeof(g_excStack[0])); diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 24f6c1f4..fdc4e4b9 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -1433,18 +1433,18 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskYield(VOID) SCHEDULER_UNLOCK(intSave); return LOS_OK; } -//任务锁 +//任务加锁 LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskLock(VOID) { UINT32 intSave; UINT32 *losTaskLock = NULL; - intSave = LOS_IntLock(); + intSave = LOS_IntLock();//禁止所有IRQ和FIQ中断 losTaskLock = &OsPercpuGet()->taskLockCnt;//task lock 的计数器 (*losTaskLock)++; - LOS_IntRestore(intSave); + LOS_IntRestore(intSave);//启用所有IRQ和FIQ中断 } - +//任务解锁 LITE_OS_SEC_TEXT_MINOR VOID LOS_TaskUnlock(VOID) { UINT32 intSave; @@ -1510,16 +1510,17 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskInfoGet(UINT32 taskID, TSK_INFO_S *taskInf } taskInfo->acName[LOS_TASK_NAMELEN - 1] = '\0'; - taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize), + taskInfo->uwBottomOfStack = TRUNCATE(((UINTPTR)taskCB->topOfStack + taskCB->stackSize),//这里可以看出栈底地址是高于栈顶 OS_TASK_STACK_ADDR_ALIGN); - taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP); + taskInfo->uwCurrUsed = (UINT32)(taskInfo->uwBottomOfStack - taskInfo->uwSP);//当前已使用了多少 - taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack, + taskInfo->bOvf = OsStackWaterLineGet((const UINTPTR *)taskInfo->uwBottomOfStack,//获取栈的使用情况 (const UINTPTR *)taskInfo->uwTopOfStack, &taskInfo->uwPeakUsed); SCHEDULER_UNLOCK(intSave); return LOS_OK; } - +//CPU亲和性(affinity)就是进程要在某个给定的CPU上尽量长时间地运行而不被迁移到其他处理器 +//把任务设置为由那个CPU核调度,用于多核CPU情况 LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMask) { #if (LOSCFG_KERNEL_SMP == YES) @@ -1528,39 +1529,40 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa BOOL needSched = FALSE; UINT16 currCpuMask; - if (OS_TID_CHECK_INVALID(taskID)) { + if (OS_TID_CHECK_INVALID(taskID)) {//检测taskid是否有效,task由task池分配,鸿蒙默认128个任务 ID范围[0:127] return LOS_ERRNO_TSK_ID_INVALID; } - if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) { + if (!(cpuAffiMask & LOSCFG_KERNEL_CPU_MASK)) {//检测cpu亲和力 return LOS_ERRNO_TSK_CPU_AFFINITY_MASK_ERR; } - taskCB = OS_TCB_FROM_TID(taskID); + taskCB = OS_TCB_FROM_TID(taskID);//获取任务实体 SCHEDULER_LOCK(intSave); - if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {//贴有未使用标签的处理 SCHEDULER_UNLOCK(intSave); return LOS_ERRNO_TSK_NOT_CREATED; } - taskCB->cpuAffiMask = cpuAffiMask; + taskCB->cpuAffiMask = cpuAffiMask;//参数set给tcb currCpuMask = CPUID_TO_AFFI_MASK(taskCB->currCpu); if (!(currCpuMask & cpuAffiMask)) { - needSched = TRUE; - taskCB->signal = SIGNAL_AFFI; + needSched = TRUE;//需要调度 + taskCB->signal = SIGNAL_AFFI;//设置信号 } SCHEDULER_UNLOCK(intSave); if (needSched && OS_SCHEDULER_ACTIVE) { - LOS_MpSchedule(currCpuMask); - LOS_Schedule(); + LOS_MpSchedule(currCpuMask);//发送信号调度信号给currCpuMask 1位上的CPU + LOS_Schedule();//申请调度 } #endif (VOID)taskID; (VOID)cpuAffiMask; return LOS_OK; } - +//CPU亲和性(affinity)就是进程要在某个给定的CPU上尽量长时间地运行而不被迁移到其他处理器 +//获取task和CPU的亲和性信息 LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) { #if (LOSCFG_KERNEL_SMP == YES) @@ -1592,19 +1594,19 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) /* * Description : Process pending signals tagged by others cores - */ + *///处理由其他CPU核标记为挂起信号 LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskProcSignal(VOID) { Percpu *percpu = NULL; LosTaskCB *runTask = NULL; UINT32 intSave, ret; - +//私有且不可中断,无需保护。这个任务在其他CPU核看到它时总是在运行,所以它在执行代码的同时也可以继续接收信号 /* * private and uninterruptable, no protection needed. * while this task is always running when others cores see it, * so it keeps recieving signals while follow code excuting. */ - runTask = OsCurrTaskGet(); + runTask = OsCurrTaskGet();//获取当前任务 if (runTask->signal == SIGNAL_NONE) { goto EXIT; } @@ -1613,7 +1615,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskProcSignal(VOID) /* * clear the signal, and do the task deletion. if the signaled task has been * scheduled out, then this deletion will wait until next run. - */ + *///清除信号,删除任务。如果发出信号的任务已出调度就绪队列,则此删除将等待下次运行 SCHEDULER_LOCK(intSave); runTask->signal = SIGNAL_NONE; ret = OsTaskDeleteUnsafe(runTask, OS_PRO_EXIT_OK, intSave); @@ -1644,7 +1646,7 @@ EXIT: return INT_NO_RESCH; } - +//设置任务名称 LITE_OS_SEC_TEXT INT32 OsSetCurrTaskName(const CHAR *name) { UINT32 intSave; @@ -1697,7 +1699,7 @@ EXIT: SCHEDULER_UNLOCK(intSave); return err; } - +//任务退群操作 LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) { LosProcessCB *processCB = NULL; @@ -1717,9 +1719,9 @@ LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) return; } - processCB->processStatus |= OS_PROCESS_FLAG_EXIT; - runTask[ArchCurrCpuid()] = OsCurrTaskGet(); - runTask[ArchCurrCpuid()]->sig.sigprocmask = OS_INVALID_VALUE; + processCB->processStatus |= OS_PROCESS_FLAG_EXIT;//贴上进程要退出的标签 + runTask[ArchCurrCpuid()] = OsCurrTaskGet();//记录当前任务 + runTask[ArchCurrCpuid()]->sig.sigprocmask = OS_INVALID_VALUE;// list = &processCB->threadSiblingList; head = list; @@ -1753,13 +1755,13 @@ LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) LOS_ASSERT(processCB->threadNumber == 1); return; } - +//任务退群并销毁,进入任务的回收链表之后再进入空闲链表,等着再次被分配使用. LITE_OS_SEC_TEXT VOID OsExecDestroyTaskGroup(VOID) { OsTaskExitGroup(OS_PRO_EXIT_OK); OsTaskCBRecyleToFree(); } - +//暂停进程的所有任务 LITE_OS_SEC_TEXT VOID OsProcessSuspendAllTask(VOID) { LosProcessCB *process = NULL; @@ -1771,22 +1773,22 @@ LITE_OS_SEC_TEXT VOID OsProcessSuspendAllTask(VOID) UINT32 ret; SCHEDULER_LOCK(intSave); - process = OsCurrProcessGet(); - runTask = OsCurrTaskGet(); + process = OsCurrProcessGet();//获取当前进程 + runTask = OsCurrTaskGet();//获取当前任务 - list = &process->threadSiblingList; + list = &process->threadSiblingList;//threadSiblingList上挂了进程下面的所有线程(task) head = list; do { - taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList); - if (taskCB != runTask) { - ret = OsTaskSuspend(taskCB); - if ((ret != LOS_OK) && (ret != LOS_ERRNO_TSK_ALREADY_SUSPENDED)) { + taskCB = LOS_DL_LIST_ENTRY(list->pstNext, LosTaskCB, threadList);//通过threadList找到任务控制块(TCB) + if (taskCB != runTask) {//只要不是当前任务就怎样? + ret = OsTaskSuspend(taskCB);//暂停掉他们 + if ((ret != LOS_OK) && (ret != LOS_ERRNO_TSK_ALREADY_SUSPENDED)) {//暂停失败的处理 PRINT_ERR("process(%d) suspend all task(%u) failed! ERROR: 0x%x\n", process->processID, taskCB->taskID, ret); } } - list = list->pstNext; - } while (head != list->pstNext); + list = list->pstNext;//下一个 + } while (head != list->pstNext);//一直从头到尾的轮询一遍 SCHEDULER_UNLOCK(intSave); return; diff --git a/kernel/base/include/los_vm_common.h b/kernel/base/include/los_vm_common.h index 65ff25e6..1be5b537 100644 --- a/kernel/base/include/los_vm_common.h +++ b/kernel/base/include/los_vm_common.h @@ -42,11 +42,11 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/*************************************************************************** +/*************************************************************************** @note_pic * 鸿蒙虚拟内存-用户空间图 从 USER_ASPACE_BASE 至 USER_ASPACE_TOP_MAX * 鸿蒙源码分析系列篇: https://blog.csdn.net/kuangyufei * https://my.oschina.net/u/3751245 -***************************************************************************/ +*************************************************************************** // | /\ | // | || | // |---------------------------|内核空间结束位置KERNEL_ASPACE_BASE + KERNEL_ASPACE_SIZE diff --git a/kernel/base/include/los_vm_zone.h b/kernel/base/include/los_vm_zone.h index 34214fcc..8a4ab412 100644 --- a/kernel/base/include/los_vm_zone.h +++ b/kernel/base/include/los_vm_zone.h @@ -39,11 +39,11 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ -/*************************************************************************** -* 鸿蒙虚拟内存全景图 从 0x00000000U 至 0xFFFFFFFFU +/*************************************************************************** @note_pic +* 鸿蒙虚拟内存全景图 从 0x00000000U 至 0xFFFFFFFFU * 鸿蒙源码分析系列篇: https://blog.csdn.net/kuangyufei * https://my.oschina.net/u/3751245 -***************************************************************************/ +*************************************************************************** // |---------------------------|0xFFFFFFFFU // | IO设备未缓存 | // | PERIPH_PMM_SIZE | diff --git a/kernel/base/misc/los_stackinfo.c b/kernel/base/misc/los_stackinfo.c index b48ef197..ddee9897 100644 --- a/kernel/base/misc/los_stackinfo.c +++ b/kernel/base/misc/los_stackinfo.c @@ -39,25 +39,25 @@ const StackInfo *g_stackInfo = NULL; UINT32 g_stackNum; - +//获取栈的水平线 UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed) { UINT32 size; const UINTPTR *tmp = NULL; - if (*stackTop == OS_STACK_MAGIC_WORD) { + if (*stackTop == OS_STACK_MAGIC_WORD) {//栈顶值是否等于 magic 0xCCCCCCCC tmp = stackTop + 1; - while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) { + while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) {//记录从栈顶到栈低有多少个连续的 0xCACACACA tmp++; } - size = (UINT32)((UINTPTR)stackBottom - (UINTPTR)tmp); - *peakUsed = (size == 0) ? size : (size + sizeof(CHAR *)); + size = (UINT32)((UINTPTR)stackBottom - (UINTPTR)tmp);//剩余多少非0xCACACACA的栈空间 + *peakUsed = (size == 0) ? size : (size + sizeof(CHAR *));//得出高峰用值 return LOS_OK; } else { - *peakUsed = OS_INVALID_WATERLINE; + *peakUsed = OS_INVALID_WATERLINE;//栈溢出了 return LOS_NOK; } } - +//执行栈检查 VOID OsExcStackCheck(VOID) { UINT32 index; diff --git a/kernel/base/mp/los_mp.c b/kernel/base/mp/los_mp.c index 189cf602..27aebccf 100644 --- a/kernel/base/mp/los_mp.c +++ b/kernel/base/mp/los_mp.c @@ -42,7 +42,7 @@ extern "C" { #endif /* __cplusplus */ #if (LOSCFG_KERNEL_SMP == YES) - +//给target对应位CPU发送调度信号 VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core { UINT32 cpuid = ArchCurrCpuid(); diff --git a/zzz/git/push.sh b/zzz/git/push.sh index eade015e..e390a082 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,6 +1,8 @@ git add -A -git commit -m '内存,进程,task模块注释基本完成. 本次提交涉及 LOS_TaskYield PendList IRQ ,FIQ等知识点 -鸿蒙内核源码分析系列 https://blog.csdn.net/kuangyufei https://my.oschina.net/u/3751245' +git commit -m '提交栈运行空间全景图,CPU多核调度部分注释 +鸿蒙内核源码分析系列 https://blog.csdn.net/kuangyufei https://my.oschina.net/u/3751245 +鸿蒙内核源码注释中文版 【 CSDN仓 | Gitee仓 | Github仓 | Coding仓】四大仓库每日同步更新 +给鸿蒙内核源码逐行加上中文注释 ,让 HarmonyOS 楚楚动人, 从此不再神秘.' git push origin git push gitee_origin master -- GitLab