From fd795161cba39ad8d067b66a3cbf59d72819079b Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Tue, 20 Apr 2021 11:37:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BB=BB=E5=8A=A1=E5=9C=A8?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=80=81=E8=BF=90=E8=A1=8C=E7=9A=84=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=20=20=20=20=20=E7=99=BE=E4=B8=87=E6=B1=89=E5=AD=97?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3=20+=20=E7=99=BE=E7=AF=87=E5=8D=9A=E5=AE=A2?= =?UTF-8?q?=E5=88=86=E6=9E=90=20=3D>=20=E6=8C=96=E9=80=8F=E9=B8=BF?= =?UTF-8?q?=E8=92=99=E5=86=85=E6=A0=B8=E6=BA=90=E7=A0=81=20=20=20=20=20htt?= =?UTF-8?q?ps://my.oschina.net/weharmony?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/base/core/los_task.c | 44 ++++++++++++++--------------- kernel/base/include/los_sched_pri.h | 10 +++---- kernel/base/include/los_task_pri.h | 15 +++++----- kernel/common/los_config.c | 2 +- kernel/include/los_task.h | 10 +++---- kernel/user/src/los_user_init.c | 4 +-- zzz/git/push.sh | 2 +- 7 files changed, 43 insertions(+), 44 deletions(-) diff --git a/kernel/base/core/los_task.c b/kernel/base/core/los_task.c index 1a2e156e..266ec157 100644 --- a/kernel/base/core/los_task.c +++ b/kernel/base/core/los_task.c @@ -154,7 +154,7 @@ LITE_OS_SEC_BSS LosTaskCB *g_taskCBArray;//任务池 128个 LITE_OS_SEC_BSS LOS_DL_LIST g_losFreeTask;//空闲任务链表 LITE_OS_SEC_BSS LOS_DL_LIST g_taskRecyleList;//回收任务链表 LITE_OS_SEC_BSS UINT32 g_taskMaxNum;//任务最大个数 -LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores *///任务调度器,每个CPU都有对应位 +LITE_OS_SEC_BSS UINT32 g_taskScheduled; /* one bit for each cores *///任务调度器,每个CPU都有对应位 LITE_OS_SEC_BSS EVENT_CB_S g_resourceEvent;//资源的事件 /* spinlock for task module, only available on SMP mode */ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_taskSpin); @@ -961,7 +961,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskCreate(UINT32 *taskID, TSK_INIT_PARAM_S *in /* in case created task not running on this core, schedule or not depends on other schedulers status. */ - LOS_MpSchedule(OS_MP_CPU_ALL);//如果创建的任务没有在这个核心上运行,是否调度取决于其他调度程序的状态。 + LOS_MpSchedule(OS_MP_CPU_ALL);//向所有cpu发送调度 if (OS_SCHEDULER_ACTIVE) {//当前CPU核处于可调度状态 LOS_Schedule();//发起调度 } @@ -998,8 +998,8 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) taskCB->taskStatus &= ~OS_TASK_STATUS_SUSPEND; if (!(taskCB->taskStatus & OS_CHECK_TASK_BLOCK)) { - OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, OS_PROCESS_STATUS_PEND); - if (OS_SCHEDULER_ACTIVE) { + OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, OS_PROCESS_STATUS_PEND);//去掉任务阻塞标签,加入就绪队列 + if (OS_SCHEDULER_ACTIVE) {//当前CPU是否可调度 needSched = TRUE; } } @@ -1007,7 +1007,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_TaskResume(UINT32 taskID) SCHEDULER_UNLOCK(intSave); if (needSched) {//需要调度 - LOS_MpSchedule(OS_MP_CPU_ALL);// + LOS_MpSchedule(OS_MP_CPU_ALL); LOS_Schedule(); } @@ -1631,7 +1631,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa } taskCB->cpuAffiMask = cpuAffiMask;//参数set给tcb - currCpuMask = CPUID_TO_AFFI_MASK(taskCB->currCpu); + currCpuMask = CPUID_TO_AFFI_MASK(taskCB->currCpu);//获取掩码位 0100 代表 2号CPU if (!(currCpuMask & cpuAffiMask)) { needSched = TRUE;//需要调度 taskCB->signal = SIGNAL_AFFI;//设置信号 @@ -1639,7 +1639,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa SCHEDULER_UNLOCK(intSave); if (needSched && OS_SCHEDULER_ACTIVE) { - LOS_MpSchedule(currCpuMask);//发送信号调度信号给currCpuMask 1位上的CPU + LOS_MpSchedule(currCpuMask);//发送信号调度信号给目标CPU LOS_Schedule();//申请调度 } #endif @@ -1647,7 +1647,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_TaskCpuAffiSet(UINT32 taskID, UINT16 cpuAffiMa (VOID)cpuAffiMask; return LOS_OK; } -//查询任务绑在哪个CPU上 +//查询任务被绑在哪个CPU上 LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) { #if (LOSCFG_KERNEL_SMP == YES) @@ -1660,20 +1660,20 @@ LITE_OS_SEC_TEXT_MINOR UINT16 LOS_TaskCpuAffiGet(UINT32 taskID) return INVALID_CPU_AFFI_MASK; } - 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 INVALID_CPU_AFFI_MASK; } - cpuAffiMask = taskCB->cpuAffiMask; + cpuAffiMask = taskCB->cpuAffiMask; //获取亲和力掩码 SCHEDULER_UNLOCK(intSave); return cpuAffiMask; #else (VOID)taskID; - return 1; + return 1;//单核情况直接返回1 ,0号cpu对应0x01 #endif } @@ -1841,7 +1841,7 @@ LITE_OS_SEC_TEXT VOID OsTaskExitGroup(UINT32 status) #endif SCHEDULER_UNLOCK(intSave); - LOS_ASSERT(processCB->threadNumber == 1);//这一趟下来,断言进程只有一个正在活动的任务了 + LOS_ASSERT(processCB->threadNumber == 1);//这一趟下来,进程只有一个正在活动的任务 return; } //任务退群并销毁,进入任务的回收链表之后再进入空闲链表,等着再次被分配使用. @@ -1909,18 +1909,18 @@ LITE_OS_SEC_TEXT_INIT STATIC UINT32 OsCreateUserTaskParamCheck(UINT32 processID, } userParam = ¶m->userParam; - if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) { + if ((processID == OS_INVALID_VALUE) && !LOS_IsUserAddress(userParam->userArea)) {//堆地址必须在用户空间 return OS_INVALID_VALUE; } - if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) { + if (!LOS_IsUserAddress((UINTPTR)param->pfnTaskEntry)) {//入口函数必须在用户空间 return OS_INVALID_VALUE; } - + //堆栈必须在用户空间 if ((!userParam->userMapSize) || !LOS_IsUserAddressRange(userParam->userMapBase, userParam->userMapSize)) { return OS_INVALID_VALUE; } - + //检查堆,栈范围 if (userParam->userArea && ((userParam->userSP <= userParam->userMapBase) || (userParam->userSP > (userParam->userMapBase + userParam->userMapSize)))) { @@ -1937,13 +1937,13 @@ LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S UINT32 ret; UINT32 intSave; - ret = OsCreateUserTaskParamCheck(processID, initParam); + ret = OsCreateUserTaskParamCheck(processID, initParam);//检查参数,堆栈,入口地址必须在用户空间 if (ret != LOS_OK) { return ret; } - - initParam->uwStackSize = OS_USER_TASK_SYSCALL_SATCK_SIZE;//设置任务栈大小,这里用了用户态下系统调用的栈大小(12K) - initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置默认优先级 + //这里可看出一个任务有两个栈,内核态栈(内核指定栈大小)和用户态栈(用户指定栈大小) + initParam->uwStackSize = OS_USER_TASK_SYSCALL_SATCK_SIZE;//设置内核栈大小,即处理系统调用的栈(12K) + initParam->usTaskPrio = OS_TASK_PRIORITY_LOWEST;//设置最低优先级 31级 initParam->policy = LOS_SCHED_RR;//调度方式为抢占式,注意鸿蒙不仅仅只支持抢占式调度方式 if (processID == OS_INVALID_VALUE) {//外面没指定进程ID的处理 SCHEDULER_LOCK(intSave); @@ -1953,7 +1953,7 @@ LITE_OS_SEC_TEXT_INIT INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S SCHEDULER_UNLOCK(intSave); } else {//进程已经创建 processCB = OS_PCB_FROM_PID(processID);//通过ID拿到进程PCB - if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {//进程状态有初始和正在运行两个标签时 + if (!(processCB->processStatus & (OS_PROCESS_STATUS_INIT | OS_PROCESS_STATUS_RUNNING))) {//进程未初始化和未正在运行时 return OS_INVALID_VALUE;//@note_why 为什么这两种情况下会创建任务失败 } initParam->processID = processID;//进程ID赋值 diff --git a/kernel/base/include/los_sched_pri.h b/kernel/base/include/los_sched_pri.h index 24a03235..5b354788 100644 --- a/kernel/base/include/los_sched_pri.h +++ b/kernel/base/include/los_sched_pri.h @@ -42,20 +42,20 @@ extern "C" { #endif /* __cplusplus */ extern UINT32 g_taskScheduled; -//调度标志,一个位代表一个CPU核,这么看鸿蒙最大支持32核,例如:4个CPU,每个4核 就一共16个核,足够了.该标志用于在调用OSStartToRun之前防止内核调度 +//设置调度标识位,对应位设置为1,一个位代表一个CPU核,此标志用于在OSStartRun之前阻止内核调度 /* * 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);//对应位设置为1 - +} while (0); +//清楚调度标识位,对应位设置为0 #define OS_SCHEDULER_CLR(cpuid) do { \ g_taskScheduled &= ~(1U << (cpuid)); \ -} while (0);//对应位设置为0 +} while (0); -#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//代表位上是否为1 +#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))//用于判断当前cpu是否可调度 typedef enum { INT_NO_RESCH = 0, /* no needs to schedule */ diff --git a/kernel/base/include/los_task_pri.h b/kernel/base/include/los_task_pri.h index 4612967e..0043e2a1 100644 --- a/kernel/base/include/los_task_pri.h +++ b/kernel/base/include/los_task_pri.h @@ -294,7 +294,7 @@ extern SPIN_LOCK_S g_taskSpin;//任务自旋锁 #define OS_TCB_NAME_LEN 32 typedef struct { - VOID *stackPointer; /**< Task stack pointer */ //内核栈指针位置,内核栈默认保存了初始的上下文信息. + VOID *stackPointer; /**< Task stack pointer */ //栈指针SP,任务当前执行栈的位置(用户栈和内核栈切换) UINT16 taskStatus; /**< Task status */ //各种状态标签,可以拥有多种标签,按位标识 UINT16 priority; /**< Task priority */ //任务优先级[0:31],默认是31级 UINT16 policy; //任务的调度方式(三种 .. LOS_SCHED_RR ) @@ -312,7 +312,7 @@ typedef struct { LOS_DL_LIST pendList; /**< Task pend node */ //如果任务阻塞时就通过它挂到各种阻塞情况的链表上,比如OsTaskWait时 LOS_DL_LIST threadList; /**< thread list */ //挂到所属进程的线程链表上 SortLinkList sortList; /**< Task sortlink node */ //task wait,delay时挂到cpu core的taskSortLink链表上 - UINT32 eventMask; /**< Event mask */ //对哪些事件进行屏蔽 + UINT32 eventMask; /**< Event mask */ //任务对哪些事件进行屏蔽 UINT32 eventMode; /**< Event mode */ //事件三种模式(LOS_WAITMODE_AND,LOS_WAITMODE_OR,LOS_WAITMODE_CLR) UINT32 priBitMap; /**< BitMap for recording the change of task priority, //任务在执行过程中优先级会经常变化,这个变量用来记录所有曾经变化 the priority can not be greater than 31 */ //过的优先级,例如 ..01001011 曾经有过 0,1,3,6 优先级 @@ -334,9 +334,9 @@ typedef struct { SchedStat schedStat; /**< Schedule statistics */ //调度统计 #endif #endif - UINTPTR userArea; //用户空间,由运行时划定,根据运行态不同而不同 - UINTPTR userMapBase; //用户态栈基地址,内存来自用户空间,和topOfStack有本质的区别. - UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */ + UINTPTR userArea; //用户空间的堆区开始位置 + UINTPTR userMapBase; //用户空间的栈顶位置,内存来自用户空间,和topOfStack有本质的区别. + UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE *///用户栈大小 UINT32 processID; /**< Which belong process *///所属进程ID FutexNode futex; //实现快锁功能 LOS_DL_LIST joinList; /**< join list */ //联结链表,允许任务之间相互释放彼此 @@ -456,9 +456,8 @@ STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) #define OS_TASK_PRI_QUEUE_DEQUEUE(processCB, taskCB) \ OsPriQueueDequeue((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), &((taskCB)->pendList)) -//入和出 任务调度就绪队列 -#define OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, status) OsTaskSchedQueueEnqueue(taskCB, status) -#define OS_TASK_SCHED_QUEUE_DEQUEUE(taskCB, status) OsTaskSchedQueueDequeue(taskCB, status) +#define OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, status) OsTaskSchedQueueEnqueue(taskCB, status) //加入任务调度就绪队列 +#define OS_TASK_SCHED_QUEUE_DEQUEUE(taskCB, status) OsTaskSchedQueueDequeue(taskCB, status) //退出任务调度就绪队列 //入和出 进程的就绪队列 ,还提供了从头部入队列的方法 #define OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB) \ OsPriQueueEnqueue(g_priQueueList, &g_priQueueBitmap, &((processCB)->pendList), (processCB)->priority) diff --git a/kernel/common/los_config.c b/kernel/common/los_config.c index 49573829..540ea276 100644 --- a/kernel/common/los_config.c +++ b/kernel/common/los_config.c @@ -162,7 +162,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsStart(VOID) runProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(runProcess->processStatus); #endif - OS_SCHEDULER_SET(cpuid);//设置调度cpu id + OS_SCHEDULER_SET(cpuid);//设置可发生调度的cpuid PRINTK("cpu %d entering scheduler\n", cpuid); OsStartToRun(taskCB);//任务开始跑,注意OsStartToRun是一个汇编函数 见于 los_dispatch.s diff --git a/kernel/include/los_task.h b/kernel/include/los_task.h index a4ae5c22..b6dd1181 100644 --- a/kernel/include/los_task.h +++ b/kernel/include/los_task.h @@ -50,7 +50,7 @@ extern "C" { #endif /* __cplusplus */ #endif /* __cplusplus */ - +//cpuid转换 2 -> 0100 #define CPUID_TO_AFFI_MASK(cpuid) (0x1u << (cpuid)) /** @@ -479,10 +479,10 @@ typedef VOID *(*TSK_ENTRY_FUNC)(UINTPTR param1, * You are not allowed to add any fields and adjust fields to the structure */ typedef struct {//用户态栈信息,(按递减满栈方式注解) - UINTPTR userArea; //用户区域 - UINTPTR userSP; //用户态下栈底位置 - UINTPTR userMapBase;//用户态下映射基地址,代表栈顶位置. - UINT32 userMapSize;//用户态下映射大小,代表栈大小 + UINTPTR userArea; //用户空间的堆区开始位置 + UINTPTR userSP; //用户空间当前栈指针位置 + UINTPTR userMapBase;//用户空间的栈顶位置. + UINT32 userMapSize;//用户空间的栈大小,栈底 = userMapBase + userMapSize } UserTaskParam; /** diff --git a/kernel/user/src/los_user_init.c b/kernel/user/src/los_user_init.c index 830122e6..660a3791 100644 --- a/kernel/user/src/los_user_init.c +++ b/kernel/user/src/los_user_init.c @@ -45,7 +45,7 @@ LITE_USER_SEC_TEXT STATIC UINT32 sys_call3(UINT32 nbr, UINT32 parm1, UINT32 parm register UINT32 reg1 __asm__("r1") = (UINT32)(parm2);//R1 = 参数2 register UINT32 reg0 __asm__("r0") = (UINT32)(parm1);//R0 = 参数1 -//SVC指令会触发一个“特权调用”异常。这为非特权软件调用操作系统或其他只能在PL1级别访问的系统组件提供了一种机制。 + //SVC指令会触发一个特权调用异常。这为非特权软件调用操作系统或其他只能在PL1级别访问的系统组件提供了一种机制。 __asm__ __volatile__ ( "svc %1" //管理模式(svc) [10011]:操作系统使用的保护模式 @@ -53,7 +53,7 @@ LITE_USER_SEC_TEXT STATIC UINT32 sys_call3(UINT32 nbr, UINT32 parm1, UINT32 parm : "i"(SYS_CALL_VALUE), "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2) : "memory", "r14" ); -//相当于执行了 reset_vector_mp.S 中的 向量表0x08对应的 _osExceptSwiHdl + //相当于执行了 reset_vector_mp.S 中的 向量表0x08对应的 _osExceptSwiHdl return reg0;//reg0的值将在汇编中改变. } diff --git a/zzz/git/push.sh b/zzz/git/push.sh index 9a1ceaff..5ec0e289 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m '完善之前的一些注解 +git commit -m '完善任务在用户态运行的注解 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 https://my.oschina.net/weharmony ' -- GitLab