From 9bf0bf86d999b4abee40875cb82f9569caaf1292 Mon Sep 17 00:00:00 2001 From: Dio Date: Fri, 19 Jan 2024 09:51:30 +0800 Subject: [PATCH] =?UTF-8?q?mp=E6=96=87=E4=BB=B6=E5=A4=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=B0=B1=E5=B0=B1=E5=B0=B1=E4=BD=8D=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/kernel_liteos_a/kernel/base/mp/los_mp.c | 80 ++++++++++--------- .../kernel/base/mp/los_percpu.c | 2 +- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/kernel_liteos_a/kernel/base/mp/los_mp.c b/src/kernel_liteos_a/kernel/base/mp/los_mp.c index 67bc7012..e2a13431 100644 --- a/src/kernel_liteos_a/kernel/base/mp/los_mp.c +++ b/src/kernel_liteos_a/kernel/base/mp/los_mp.c @@ -36,43 +36,43 @@ #include "los_swtmr.h" #include "los_task_pri.h" -#ifdef LOSCFG_KERNEL_SMP +#ifdef LOSCFG_KERNEL_SMP +//给参数CPU发送调度信号 #ifdef LOSCFG_KERNEL_SMP_CALL LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_mpCallSpin); #define MP_CALL_LOCK(state) LOS_SpinLockSave(&g_mpCallSpin, &(state)) #define MP_CALL_UNLOCK(state) LOS_SpinUnlockRestore(&g_mpCallSpin, (state)) #endif - -VOID LOS_MpSchedule(UINT32 target) +VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core { UINT32 cpuid = ArchCurrCpuid(); - target &= ~(1U << cpuid); - HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE); + target &= ~(1U << cpuid);//获取除了自身之外的其他CPU + HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//向目标CPU发送调度信号,核间中断(Inter-Processor Interrupts),IPI } - +///硬中断唤醒处理函数 VOID OsMpWakeHandler(VOID) { /* generic wakeup ipi, do nothing */ } - +///硬中断调度处理函数 VOID OsMpScheduleHandler(VOID) -{ +{//将调度标志设置为与唤醒功能不同,这样就可以在硬中断结束时触发调度程序。 /* * set schedule flag to differ from wake function, * so that the scheduler can be triggered at the end of irq. */ OsSchedRunqueuePendingSet(); } - +///硬中断暂停处理函数 VOID OsMpHaltHandler(VOID) { (VOID)LOS_IntLock(); - OsPercpuGet()->excFlag = CPU_HALT; + OsPercpuGet()->excFlag = CPU_HALT;//让当前Cpu停止工作 - while (1) {} + while (1) {}//陷入空循环,也就是空闲状态 } - +///MP定时器处理函数, 递归检查所有可用任务 VOID OsMpCollectTasks(VOID) { LosTaskCB *taskCB = NULL; @@ -80,19 +80,19 @@ VOID OsMpCollectTasks(VOID) UINT32 ret; /* recursive checking all the available task */ - for (; taskID <= g_taskMaxNum; taskID++) { + for (; taskID <= g_taskMaxNum; taskID++) { //递归检查所有可用任务 taskCB = &g_taskCBArray[taskID]; if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) { continue; } - /* + /* 虽然任务状态不是原子的,但此检查可能成功,但无法完成删除,此删除将在下次运行之前处理 * though task status is not atomic, this check may success but not accomplish * the deletion; this deletion will be handled until the next run. */ - if (taskCB->signal & SIGNAL_KILL) { - ret = LOS_TaskDelete(taskID); + if (taskCB->signal & SIGNAL_KILL) {//任务收到被干掉信号 + ret = LOS_TaskDelete(taskID);//干掉任务,回归任务池 if (ret != LOS_OK) { PRINT_WARN("GC collect task failed err:0x%x\n", ret); } @@ -101,6 +101,7 @@ VOID OsMpCollectTasks(VOID) } #ifdef LOSCFG_KERNEL_SMP_CALL + VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) { UINT32 index; @@ -110,13 +111,13 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) return; } - if (!(target & OS_MP_CPU_ALL)) { + if (!(target & OS_MP_CPU_ALL)) {//检查目标CPU是否正确 return; } - for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { + for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {//遍历所有核 if (CPUID_TO_AFFI_MASK(index) & target) { - MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc)); + MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc));//从内核空间 分配回调结构体 if (mpCallFunc == NULL) { PRINT_ERR("smp func call malloc failed\n"); return; @@ -125,59 +126,66 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args) mpCallFunc->args = args; MP_CALL_LOCK(intSave); - LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node)); + LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node));//将回调结构体挂入链表尾部 MP_CALL_UNLOCK(intSave); } } - HalIrqSendIpi(target, LOS_MP_IPI_FUNC_CALL); + HalIrqSendIpi(target, LOS_MP_IPI_FUNC_CALL);//向目标CPU发起核间中断 } +/*! + * @brief OsMpFuncCallHandler + * 回调向当前CPU注册过的函数 + * @return + * + * @see + */ VOID OsMpFuncCallHandler(VOID) { UINT32 intSave; - UINT32 cpuid = ArchCurrCpuid(); + UINT32 cpuid = ArchCurrCpuid();//获取当前CPU LOS_DL_LIST *list = NULL; MpCallFunc *mpCallFunc = NULL; MP_CALL_LOCK(intSave); - while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) { - list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink); - LOS_ListDelete(list); + while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) {//遍历回调函数链表,知道为空 + list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink);//获取链表第一个数据 + LOS_ListDelete(list);//将自己从链表上摘除 MP_CALL_UNLOCK(intSave); - mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node); - mpCallFunc->func(mpCallFunc->args); - (VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc); + mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node);//获取回调函数 + mpCallFunc->func(mpCallFunc->args);//获取参数并回调该函数 + (VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc);//释放回调函数内存 MP_CALL_LOCK(intSave); } MP_CALL_UNLOCK(intSave); } - +/// CPU层级的回调模块初始化 VOID OsMpFuncCallInit(VOID) { UINT32 index; - /* init funclink for each core */ + /* init funclink for each core | 为每个CPU核整一个回调函数链表*/ for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) { - LOS_ListInit(&g_percpu[index].funcLink); + LOS_ListInit(&g_percpu[index].funcLink);//链表初始化 } } #endif /* LOSCFG_KERNEL_SMP_CALL */ - +//MP(multiprocessing) 多核处理器初始化 UINT32 OsMpInit(VOID) { UINT16 swtmrId; - (VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, - (SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0); - (VOID)LOS_SwtmrStart(swtmrId); + (VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, //创建一个周期性,持续时间为 100个tick的定时器 + (SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);//OsMpCollectTasks为超时回调函数 + (VOID)LOS_SwtmrStart(swtmrId);//开始定时任务 #ifdef LOSCFG_KERNEL_SMP_CALL OsMpFuncCallInit(); #endif return LOS_OK; } -LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK); +LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK);//多处理器模块初始化 #endif diff --git a/src/kernel_liteos_a/kernel/base/mp/los_percpu.c b/src/kernel_liteos_a/kernel/base/mp/los_percpu.c index 4d883916..527c028f 100644 --- a/src/kernel_liteos_a/kernel/base/mp/los_percpu.c +++ b/src/kernel_liteos_a/kernel/base/mp/los_percpu.c @@ -33,7 +33,7 @@ #include "los_printf.h" #ifdef LOSCFG_KERNEL_SMP -Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; +Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; ///< CPU池,池大小由CPU核数决定 VOID OsAllCpuStatusOutput(VOID) { -- 2.34.1