From f594658488204272b4d1a575a3fe315d4f952f46 Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Wed, 24 Feb 2021 19:07:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=B0=83=E7=94=A8=E7=94=B1?= =?UTF-8?q?=E8=BD=AF=E4=B8=AD=E6=96=AD=E5=AE=9E=E7=8E=B0,=E5=AF=B9?= =?UTF-8?q?=E5=85=B6=E6=B1=87=E7=BC=96=E4=BB=A3=E7=A0=81=E6=B3=A8=E8=A7=A3?= =?UTF-8?q?=20=20=20=20=20=E7=99=BE=E4=B8=87=E6=B1=89=E5=AD=97=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=20+=20=E7=99=BE=E7=AF=87=E5=8D=9A=E5=AE=A2=E5=88=86?= =?UTF-8?q?=E6=9E=90=20=3D>=20=E6=8C=96=E9=80=8F=E9=B8=BF=E8=92=99?= =?UTF-8?q?=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81=20=20=20=20=20https://weha?= =?UTF-8?q?rmony.gitee.io?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arch/arm/arm/src/los_dispatch.S | 28 ++++++------ arch/arm/arm/src/los_hw_exc.S | 52 +++++++++++----------- arch/arm/arm/src/los_hwi.c | 6 +-- arch/arm/arm/src/startup/reset_vector_mp.S | 4 +- kernel/base/core/los_task.c | 30 ++++++------- kernel/base/include/los_process_pri.h | 2 +- zzz/git/push.sh | 5 ++- 7 files changed, 64 insertions(+), 63 deletions(-) diff --git a/arch/arm/arm/src/los_dispatch.S b/arch/arm/arm/src/los_dispatch.S index 8b0f41c4..b35474d3 100644 --- a/arch/arm/arm/src/los_dispatch.S +++ b/arch/arm/arm/src/los_dispatch.S @@ -254,23 +254,23 @@ 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} + STMFD SP, {R0-R3} @r0-r3寄存器入栈 SUB R0, SP, #(4 * 4) MRS R1, SPSR @获取程序状态控制寄存器 MOV R2, LR - /* disable irq, switch to svc mode */ - CPSID i, #0x13 @禁止中断,切换到SVC模式 - + /* disable irq, switch to svc mode */@超级用户模式(SVC 模式),主要用于 SWI(软件中断)和 OS(操作系统)。 + CPSID i, #0x13 @切换到SVC模式,此处一切换,后续指令将入SVC的栈 + @CPSID i为关中断指令,对应的是CPSIE /* push spsr and pc in svc stack */ - STMFD SP!, {R1, R2} - STMFD SP, {LR} + STMFD SP!, {R1, R2} @实际是将 SPSR,和LR入栈,入栈顺序为 R1,R2,SP自增 + STMFD SP, {LR} @LR再入栈,SP不自增 - AND R3, R1, #CPSR_MASK_MODE + AND R3, R1, #CPSR_MASK_MODE @获取CPU的运行模式 CMP R3, #CPSR_USER_MODE @中断是否发生在用户模式 BNE OsIrqFromKernel @中断不发生在用户模式下则跳转到OsIrqFromKernel @@ -324,15 +324,15 @@ OsIrqFromKernel: @从内核发起中断 ADD SP, SP, #4 -OsIrqContextRestore: - LDR R0, [SP, #(4 * 7)] - MSR SPSR_cxsf, R0 +OsIrqContextRestore: @中断环境恢复 + LDR R0, [SP, #(4 * 7)] @读取 SP+28 位置数据给R0 + MSR SPSR_cxsf, R0 @恢复spsr AND R0, R0, #CPSR_MASK_MODE - CMP R0, #CPSR_USER_MODE + CMP R0, #CPSR_USER_MODE @ - LDMFD SP!, {R0-R3, R12} + LDMFD SP!, {R0-R3, R12} @ - BNE OsIrqContextRestoreToKernel + BNE OsIrqContextRestoreToKernel @CPU工作在非用户模式 /* load user sp and lr, and jump cpsr */ LDMFD SP, {R13, R14}^ diff --git a/arch/arm/arm/src/los_hw_exc.S b/arch/arm/arm/src/los_hw_exc.S index 7a2d6acc..f13f4044 100644 --- a/arch/arm/arm/src/los_hw_exc.S +++ b/arch/arm/arm/src/los_hw_exc.S @@ -158,7 +158,7 @@ __stack_chk_guard_setup: POP {FP, PC} @ Description: Undefined instruction exception handler -_osExceptUndefInstrHdl: +_osExceptUndefInstrHdl:@出现未定义的指令处理 #ifdef LOSCFG_GDB GDB_HANDLE OsUndefIncExcHandleEntry #else @@ -172,43 +172,43 @@ _osExceptUndefInstrHdl: #endif @ Description: Software interrupt exception handler -_osExceptSwiHdl: - SUB SP, SP, #(4 * 16) - STMIA SP, {R0-R12} - MRS R3, SPSR - MOV R4, LR - - AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode - CMP R1, #CPSR_USER_MODE @ User mode - BNE OsKernelSVCHandler @ Branch if not user mode - +_osExceptSwiHdl: @软中断异常处理 + SUB SP, SP, #(4 * 16) @先申请16个栈空间用于处理本次软中断 + STMIA SP, {R0-R12} @保存R0-R12寄存器值 + MRS R3, SPSR @读取本模式下的SPSR值 + MOV R4, LR @保存回跳寄存器LR + + AND R1, R3, #CPSR_MASK_MODE @ Interrupted mode 获取中断模式 + CMP R1, #CPSR_USER_MODE @ User mode 是否为用户模式 + BNE OsKernelSVCHandler @ Branch if not user mode 非用户模式下跳转 + @ 当为用户模式时,获取SP和LR寄出去值 @ we enter from user mode, we need get the values of USER mode r13(sp) and r14(lr). @ stmia with ^ will return the user mode registers (provided that r15 is not in the register list). - MOV R0, SP - STMFD SP!, {R3} @ Save the CPSR - ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage - STMFD R3!, {R4} @ Save the CPSR and r15(pc) - STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) + MOV R0, SP @获取SP值,R0将作为OsArmA32SyscallHandle的参数 + STMFD SP!, {R3} @ Save the CPSR 入栈保存CPSR值 + ADD R3, SP, #(4 * 17) @ Offset to pc/cpsr storage 跳到PC/CPSR存储位置 + STMFD R3!, {R4} @ Save the CPSR and r15(pc) 保存LR寄存器 + STMFD R3, {R13, R14}^ @ Save user mode r13(sp) and r14(lr) 保存用户模式下的SP和LR寄存器 SUB SP, SP, #4 PUSH_FPU_REGS R1 MOV FP, #0 @ Init frame pointer - CPSIE I + CPSIE I @开中断,表明在系统调用期间可响应中断 BLX OsArmA32SyscallHandle /*处理系统调用*/ - CPSID I + CPSID I @执行后续指令前必须先关中断 - POP_FPU_REGS R1 - ADD SP, SP,#4 - LDMFD SP!, {R3} @ Fetch the return SPSR - MSR SPSR_cxsf, R3 @ Set the return mode SPSR + POP_FPU_REGS R1 @弹出FP值给R1 + ADD SP, SP,#4 @ 定位到保存旧SPSR值的位置 + LDMFD SP!, {R3} @ Fetch the return SPSR 弹出旧SPSR值 + MSR SPSR_cxsf, R3 @ Set the return mode SPSR 恢复该模式下的SPSR值 @ we are leaving to user mode, we need to restore the values of USER mode r13(sp) and r14(lr). @ ldmia with ^ will return the user mode registers (provided that r15 is not in the register list) - LDMFD SP!, {R0-R12} - LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 - ADD SP, SP, #(2 * 4) - LDMFD SP!, {PC}^ @ Return to user + LDMFD SP!, {R0-R12} @恢复R0-R12寄存器 + LDMFD SP, {R13, R14}^ @ Restore user mode R13/R14 恢复用户模式的R13/R14寄存器 + ADD SP, SP, #(2 * 4) @定位到保存旧PC值的位置 + LDMFD SP!, {PC}^ @ Return to user 弹出值给PC寄存器 OsKernelSVCHandler: ADD R0, SP, #(4 * 16) diff --git a/arch/arm/arm/src/los_hwi.c b/arch/arm/arm/src/los_hwi.c index 755e341e..a6afb157 100644 --- a/arch/arm/arm/src/los_hwi.c +++ b/arch/arm/arm/src/los_hwi.c @@ -215,14 +215,14 @@ STATIC UINT32 OsHwiDelNoShared(HWI_HANDLE_T hwiNum) { UINT32 intSave; - HWI_LOCK(intSave); + HWI_LOCK(intSave);//申请硬中断自旋锁 g_hwiForm[hwiNum].pfnHook = NULL;//回调函数直接NULL if (g_hwiForm[hwiNum].uwParam) {//如有参数 (VOID)LOS_MemFree(m_aucSysMem0, (VOID *)g_hwiForm[hwiNum].uwParam);//释放内存 } g_hwiForm[hwiNum].uwParam = 0; //NULL - HWI_UNLOCK(intSave); + HWI_UNLOCK(intSave);//释放硬中断自旋锁 return LOS_OK; } //创建一个不支持共享的中断 @@ -258,7 +258,7 @@ STATIC UINT32 OsHwiDelShared(HWI_HANDLE_T hwiNum, const HwiIrqParam *irqParam) UINT32 intSave; HWI_LOCK(intSave); - hwiForm = &g_hwiForm[hwiNum]; + hwiForm = &g_hwiForm[hwiNum];//从全局注册的中断向量表中获取中断项 hwiFormtmp = hwiForm; if ((hwiForm->uwParam & IRQF_SHARED) && ((irqParam == NULL) || (irqParam->pDevId == NULL))) { diff --git a/arch/arm/arm/src/startup/reset_vector_mp.S b/arch/arm/arm/src/startup/reset_vector_mp.S index a64df178..e47c4d3a 100644 --- a/arch/arm/arm/src/startup/reset_vector_mp.S +++ b/arch/arm/arm/src/startup/reset_vector_mp.S @@ -96,10 +96,10 @@ .global __exception_handlers __exception_handlers: - /* + /* //假设:ROM代码在硬件重置地址有这些向量 *Assumption: ROM code has these vectors at the hardware reset address. *A simple jump removes any address-space dependencies [i.e. safer] - */ + *///一个简单的跳转将删除任何地址空间依赖关系 b reset_vector b _osExceptUndefInstrHdl b _osExceptSwiHdl diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 2a5749d3..3996f354 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -436,7 +436,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) UINT32 ret; TSK_INIT_PARAM_S taskInitParam; Percpu *perCpu = OsPercpuGet();//获取CPU信息 - UINT32 *idleTaskID = &perCpu->idleTaskID; + UINT32 *idleTaskID = &perCpu->idleTaskID;//指定CPU的空闲任务 (VOID)memset_s((VOID *)(&taskInitParam), sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//任务初始参数清0 taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsIdleTask;//入口函数指定idle @@ -449,7 +449,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) #endif ret = LOS_TaskCreate(idleTaskID, &taskInitParam);//创建task并申请调度, OS_TCB_FROM_TID(*idleTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//设置task状态为系统任务,系统任务运行在内核态. - //这里说下系统任务有哪些?比如: idle,swtmr(软时钟)等等 + //这里说下系统任务有哪些?比如: idle,swtmr(软时钟),资源回收等等 return ret; } @@ -457,7 +457,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsIdleTaskCreate(VOID) * Description : get id of current running task. * Return : task id */ -LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID) +LITE_OS_SEC_TEXT UINT32 LOS_CurTaskIDGet(VOID)//获取当前任务的ID { LosTaskCB *runTask = OsCurrTaskGet(); @@ -506,10 +506,10 @@ LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status) LosProcessCB *runProcess = NULL; LosTaskCB *mainTask = NULL; - SCHEDULER_LOCK(intSave); + SCHEDULER_LOCK(intSave);//禁止调度 runProcess = OS_PCB_FROM_PID(taskCB->processID);//通过任务ID拿到进程实体 - mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID);//通过线程组ID拿到主任务实体,threadGroupID就是等于mainTask的taskId - SCHEDULER_UNLOCK(intSave); //这个是在线程组创建的时候指定的. + mainTask = OS_TCB_FROM_TID(runProcess->threadGroupID);//通过线程组ID拿到主任务实体,threadGroupID就是等于mainTask的taskId,这个是在线程组创建的时候指定的. + SCHEDULER_UNLOCK(intSave);//恢复调度 if (mainTask == taskCB) {//如果参数任务就是主任务 OsTaskExitGroup(status);//task退出线程组 } @@ -521,8 +521,8 @@ LITE_OS_SEC_TEXT VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status) return; } - if (taskCB->taskStatus & OS_TASK_FLAG_DETACHED) {//任务贴有分离的标签 - (VOID)OsTaskDeleteUnsafe(taskCB, status, intSave);//任务要over了,走起释放占用的资源的流程 + if (taskCB->taskStatus & OS_TASK_FLAG_DETACHED) {//任务状态是否有分离标签 + (VOID)OsTaskDeleteUnsafe(taskCB, status, intSave);//任务要over了,释放占用的资源 } OsTaskJoinPostUnsafe(taskCB);//退出前唤醒跟自己绑在一块的任务 @@ -546,8 +546,8 @@ LITE_OS_SEC_TEXT_INIT VOID OsTaskEntry(UINT32 taskID) * from interrupt and other cores. release task spinlock and enable * interrupt in sequence at the task entry. */ - LOS_SpinUnlock(&g_taskSpin); - (VOID)LOS_IntUnLock(); + LOS_SpinUnlock(&g_taskSpin);//释放任务自旋锁 + (VOID)LOS_IntUnLock();//恢复中断 taskCB = OS_TCB_FROM_TID(taskID); taskCB->joinRetval = taskCB->taskEntry(taskCB->args[0], taskCB->args[1],//调用任务的入口函数 @@ -782,17 +782,17 @@ LITE_OS_SEC_TEXT_INIT STATIC VOID OsTaskCBInitBase(LosTaskCB *taskCB, LOS_ListInit(&(taskCB->msgListHead));//初始化 liteipc的消息链表 (VOID)memset_s(taskCB->accessMap, sizeof(taskCB->accessMap), 0, sizeof(taskCB->accessMap)); #endif - taskCB->policy = (initParam->policy == LOS_SCHED_FIFO) ? LOS_SCHED_FIFO : LOS_SCHED_RR; - taskCB->taskStatus = OS_TASK_STATUS_INIT; + taskCB->policy = (initParam->policy == LOS_SCHED_FIFO) ? LOS_SCHED_FIFO : LOS_SCHED_RR;//调度模式 + taskCB->taskStatus = OS_TASK_STATUS_INIT;//任务初始状态 if (initParam->uwResved & OS_TASK_FLAG_DETACHED) {//分离模式 代表任务与其他任务的关系 - taskCB->taskStatus |= OS_TASK_FLAG_DETACHED; + taskCB->taskStatus |= OS_TASK_FLAG_DETACHED;//任务状态贴上分离标签 } else {//参与模式 LOS_ListInit(&taskCB->joinList); - taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN; + taskCB->taskStatus |= OS_TASK_FLAG_PTHREAD_JOIN;//任务状态贴上联合标签 } taskCB->futex.index = OS_INVALID_VALUE; - LOS_ListInit(&taskCB->lockList); + LOS_ListInit(&taskCB->lockList);//初始化互斥锁链表 } //任务初始化 LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsTaskCBInit(LosTaskCB *taskCB, const TSK_INIT_PARAM_S *initParam, diff --git a/kernel/base/include/los_process_pri.h b/kernel/base/include/los_process_pri.h index 768bac61..718682c0 100644 --- a/kernel/base/include/los_process_pri.h +++ b/kernel/base/include/los_process_pri.h @@ -80,7 +80,7 @@ typedef struct ProcessCB { CHAR processName[OS_PCB_NAME_LEN]; /**< Process name */ //进程名称 UINT32 processID; /**< process ID = leader thread ID */ //进程ID,由进程池分配,范围[0,64] UINT16 processStatus; /**< [15:4] process Status; [3:0] The number of threads currently - running in the process *///这里设计很巧妙.用一个16表示了两层逻辑 数量和状态,点赞! + running in the process *///这里设计很巧妙.用一个变量表示了两层逻辑 数量和状态,点赞! UINT16 priority; /**< process priority */ //进程优先级 UINT16 policy; /**< process policy */ //进程的调度方式,默认抢占式 UINT16 timeSlice; /**< Remaining time slice *///进程时间片,默认2个tick diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 5beee871..2de19c0f 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,6 +1,7 @@ git add -A -git commit -m '硬中断代码注释 - 百万汉字注解 + 百篇博客分析 -> 挖透鸿蒙内核源码 +git commit -m '系统调用由软中断实现,对其汇编代码注解 + 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 + https://weharmony.gitee.io ' git push origin master -- GitLab