鸿蒙内核源码分析(中断管理篇) | 硬中断的实现类似观察者模式 | 百篇博客分析鸿蒙源码 | v44.01

    百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
    https://my.oschina.net/weharmony
上级 f6dd06b0
...@@ -75,8 +75,10 @@ ...@@ -75,8 +75,10 @@
### **ARM架构** ### **ARM架构**
* [(中断概念篇) | 外人眼中权势滔天的当红海公公 ](https://weharmony.gitee.io/中断概念篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/115014442) [ | oschina >](https://my.oschina.net/weharmony/blog/4992750)** * [(中断概念篇) | 外人眼中权势滔天的当红海公公 ](https://weharmony.gitee.io/中断概念篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/115014442) [ | oschina >](https://my.oschina.net/weharmony/blog/4992750)**
* [(中断切换篇) | 自下而上逐行分析保存和恢复中断现场全过程 ](https://weharmony.gitee.io/中断切换篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/114988891) [ | oschina >](https://my.oschina.net/weharmony/blog/4990948)** * [(中断管理篇) | 硬中断的实现类似观察者模式 ](https://weharmony.gitee.io/中断管理篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/115130055) [ | oschina >](https://my.oschina.net/weharmony/blog/4995800)**
* [(中断切换篇) | 在中断切换的那一瞬间发生了什么? ](https://weharmony.gitee.io/中断切换篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/114988891) [ | oschina >](https://my.oschina.net/weharmony/blog/4990948)**
* [(汇编汇总篇) | 鸿蒙所有的汇编代码都在这里 ](https://weharmony.gitee.io/汇编汇总篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/114597179) [ | oschina >](https://my.oschina.net/weharmony/blog/4977924)** * [(汇编汇总篇) | 鸿蒙所有的汇编代码都在这里 ](https://weharmony.gitee.io/汇编汇总篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/114597179) [ | oschina >](https://my.oschina.net/weharmony/blog/4977924)**
...@@ -94,7 +96,7 @@ ...@@ -94,7 +96,7 @@
### **进程线程** ### **进程线程**
* [(任务切换篇) | 逐行汇编分析TaskContext保存和恢复全过程 ](https://weharmony.gitee.io/任务切换篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/114890180) [ | oschina >](https://my.oschina.net/weharmony/blog/4988628)** * [(任务切换篇) | 汇编逐行注解分析任务上下文 ](https://weharmony.gitee.io/任务切换篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/114890180) [ | oschina >](https://my.oschina.net/weharmony/blog/4988628)**
* [(CPU篇) | 内核是如何描述CPU的? ](https://weharmony.gitee.io/CPU篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/113782749) [ | oschina >](https://my.oschina.net/weharmony/blog/4952034)** * [(CPU篇) | 内核是如何描述CPU的? ](https://weharmony.gitee.io/CPU篇.html) **[< csdn](https://blog.csdn.net/kuangyufei/article/details/113782749) [ | oschina >](https://my.oschina.net/weharmony/blog/4952034)**
...@@ -209,4 +211,6 @@ ...@@ -209,4 +211,6 @@
![公众号: 鸿蒙内核源码分析](https://gitee.com/weharmony/docs/raw/master/pic/other/so1so.png) ![公众号: 鸿蒙内核源码分析](https://gitee.com/weharmony/docs/raw/master/pic/other/so1so.png)
[进入 >> 百万汉字注解 百篇博客分析 精读鸿蒙源码 深挖地基工程](https://weharmony.gitee.io) **[< gitee ](https://gitee.com/weharmony/kernel_liteos_a_note)[| csdn](https://blog.csdn.net/kuangyufei) [ | oschina >](https://my.oschina.net/weharmony)** [进入 >> 百万汉字注解 百篇博客分析 精读鸿蒙源码 深挖地基工程](https://weharmony.gitee.io) **[< gitee ](https://gitee.com/weharmony/kernel_liteos_a_note)[| csdn](https://blog.csdn.net/kuangyufei) [ | oschina >](https://my.oschina.net/weharmony)**
\ No newline at end of file
...@@ -130,9 +130,9 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_hwiSpin); //注意全局变量 g_hwiSpin 是 ...@@ -130,9 +130,9 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_hwiSpin); //注意全局变量 g_hwiSpin 是
#define HWI_LOCK(state) LOS_SpinLockSave(&g_hwiSpin, &(state)) #define HWI_LOCK(state) LOS_SpinLockSave(&g_hwiSpin, &(state))
#define HWI_UNLOCK(state) LOS_SpinUnlockRestore(&g_hwiSpin, (state)) #define HWI_UNLOCK(state) LOS_SpinUnlockRestore(&g_hwiSpin, (state))
size_t g_intCount[LOSCFG_KERNEL_CORE_NUM] = {0};//记录每个CPU core的中断数量 size_t g_intCount[LOSCFG_KERNEL_CORE_NUM] = {0};//记录每个CPUcore的中断数量
HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; //记录每个硬件中断实体内容 @note_why 用 form 来表示?有种写 HTML的感觉 HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; //中断注册表 @note_why 用 form 来表示?有种写 HTML的感觉
STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0};//记录每个硬中断的名称 OS_HWI_MAX_NUM = 128 定义于 hi3516dv300 STATIC CHAR *g_hwiFormName[OS_HWI_MAX_NUM] = {0};//记录每个硬中断的名称
STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0};//记录每个硬中断的总数量 STATIC UINT32 g_hwiFormCnt[OS_HWI_MAX_NUM] = {0};//记录每个硬中断的总数量
VOID OsIncHwiFormCnt(UINT32 index) //增加一个中断数,递增的,所以只有++ ,没有--, VOID OsIncHwiFormCnt(UINT32 index) //增加一个中断数,递增的,所以只有++ ,没有--,
...@@ -158,7 +158,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数 ...@@ -158,7 +158,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数
UINT32 *intCnt = NULL; UINT32 *intCnt = NULL;
intCnt = &g_intCount[ArchCurrCpuid()];//当前CPU的中断总数量 ++ intCnt = &g_intCount[ArchCurrCpuid()];//当前CPU的中断总数量 ++
*intCnt = *intCnt + 1; *intCnt = *intCnt + 1;//@note_why 这里没看明白为什么要 +1
#ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断 #ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断
OsCpupIrqStart();//记录本次中断处理开始时间 OsCpupIrqStart();//记录本次中断处理开始时间
...@@ -178,7 +178,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数 ...@@ -178,7 +178,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数
UINTPTR *param = (UINTPTR *)(hwiForm->uwParam); UINTPTR *param = (UINTPTR *)(hwiForm->uwParam);
func((INT32)(*param), (VOID *)(*(param + 1)));//运行带参数的回调函数 func((INT32)(*param), (VOID *)(*(param + 1)));//运行带参数的回调函数
} }
} else {//有参数的情况 } else {//有参数的情况
HWI_PROC_FUNC0 func = (HWI_PROC_FUNC0)hwiForm->pfnHook;//获取回调函数 HWI_PROC_FUNC0 func = (HWI_PROC_FUNC0)hwiForm->pfnHook;//获取回调函数
if (func != NULL) { if (func != NULL) {
func();//运行回调函数 func();//运行回调函数
...@@ -187,7 +187,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数 ...@@ -187,7 +187,7 @@ VOID OsInterrupt(UINT32 intNum)//中断实际处理函数
#ifndef LOSCFG_NO_SHARED_IRQ #ifndef LOSCFG_NO_SHARED_IRQ
} }
#endif #endif
++g_hwiFormCnt[intNum];//中断数量计数器++ ++g_hwiFormCnt[intNum];//对应中断号计数器总数累加
*intCnt = *intCnt - 1; //@note_why 这里没看明白为什么要 -1 *intCnt = *intCnt - 1; //@note_why 这里没看明白为什么要 -1
#ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断 #ifdef LOSCFG_CPUP_INCLUDE_IRQ //开启查询系统CPU的占用率的中断
......
...@@ -261,7 +261,7 @@ typedef struct tagIrqParam { //中断参数 ...@@ -261,7 +261,7 @@ typedef struct tagIrqParam { //中断参数
const CHAR *pName; //名称 const CHAR *pName; //名称
} HwiIrqParam; } HwiIrqParam;
extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM]; extern HwiHandleForm g_hwiForm[OS_HWI_MAX_NUM];//中断注册表
/** /**
* @ingroup los_hwi * @ingroup los_hwi
......
/* /*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, Huawei Device 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, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* 3. Neither the name of the copyright holder nor the names of its contributors may be used * 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 * to endorse or promote products derived from this software without specific prior written
* permission. * permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _LOS_MP_H #ifndef _LOS_MP_H
#define _LOS_MP_H #define _LOS_MP_H
#include "los_config.h" #include "los_config.h"
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
#define OS_MP_CPU_ALL LOSCFG_KERNEL_CPU_MASK #define OS_MP_CPU_ALL LOSCFG_KERNEL_CPU_MASK
#define OS_MP_GC_PERIOD 100 /* ticks */ #define OS_MP_GC_PERIOD 100 /* ticks */
typedef enum {//处理器之间发送消息 typedef enum {//核间中断
LOS_MP_IPI_WAKEUP, //唤醒CPU LOS_MP_IPI_WAKEUP, //唤醒CPU
LOS_MP_IPI_SCHEDULE,//调度CPU LOS_MP_IPI_SCHEDULE,//调度CPU
LOS_MP_IPI_HALT, //停止CPU LOS_MP_IPI_HALT, //停止CPU
} MP_IPI_TYPE; } MP_IPI_TYPE;
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
extern VOID LOS_MpSchedule(UINT32 target); extern VOID LOS_MpSchedule(UINT32 target);
extern VOID OsMpWakeHandler(VOID); extern VOID OsMpWakeHandler(VOID);
extern VOID OsMpScheduleHandler(VOID); extern VOID OsMpScheduleHandler(VOID);
extern VOID OsMpHaltHandler(VOID); extern VOID OsMpHaltHandler(VOID);
extern UINT32 OsMpInit(VOID); extern UINT32 OsMpInit(VOID);
#else #else
STATIC INLINE VOID LOS_MpSchedule(UINT32 target) STATIC INLINE VOID LOS_MpSchedule(UINT32 target)
{ {
(VOID)target; (VOID)target;
} }
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* _LOS_MP_H_ */ #endif /* _LOS_MP_H_ */
...@@ -45,13 +45,13 @@ STATIC UINT32 g_curIrqNum = 0; //记录当前中断号 ...@@ -45,13 +45,13 @@ STATIC UINT32 g_curIrqNum = 0; //记录当前中断号
* 0b00: forward to the cpu interfaces specified in cpu_mask * 0b00: forward to the cpu interfaces specified in cpu_mask
* 0b01: forward to all cpu interfaces * 0b01: forward to all cpu interfaces
* 0b10: forward only to the cpu interface that request the irq * 0b10: forward only to the cpu interface that request the irq
*/ *///SGI软件触发中断(Software Generated Interrupt)通常用于多核间通讯
STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter) STATIC VOID GicWriteSgi(UINT32 vector, UINT32 cpuMask, UINT32 filter)
{ {
UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) | UINT32 val = ((filter & 0x3) << 24) | ((cpuMask & 0xFF) << 16) |
(vector & 0xF); (vector & 0xF);
GIC_REG_32(GICD_SGIR) = val; GIC_REG_32(GICD_SGIR) = val;//写SGI寄存器
} }
//向指定核发送核间中断 //向指定核发送核间中断
VOID HalIrqSendIpi(UINT32 target, UINT32 ipi) VOID HalIrqSendIpi(UINT32 target, UINT32 ipi)
...@@ -107,7 +107,7 @@ VOID HalIrqClear(UINT32 vector) ...@@ -107,7 +107,7 @@ VOID HalIrqClear(UINT32 vector)
//给每个CPU core初始化硬件中断 //给每个CPU core初始化硬件中断
VOID HalIrqInitPercpu(VOID) VOID HalIrqInitPercpu(VOID)
{ {
/* unmask interrupts */ //取消屏蔽中断 /* unmask interrupts */ //取消中断屏蔽
GIC_REG_32(GICC_PMR) = 0xFF; GIC_REG_32(GICC_PMR) = 0xFF;
/* enable gic cpu interface */ //启用gic cpu接口 /* enable gic cpu interface */ //启用gic cpu接口
...@@ -138,13 +138,13 @@ VOID HalIrqInit(VOID) ...@@ -138,13 +138,13 @@ VOID HalIrqInit(VOID)
GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0; GIC_REG_32(GICD_ICENABLER(i / 32)) = ~0;
} }
HalIrqInitPercpu(); HalIrqInitPercpu();//初始化当前CPU中断信息
/* enable gic distributor control */ /* enable gic distributor control */
GIC_REG_32(GICD_CTLR) = 1; GIC_REG_32(GICD_CTLR) = 1;//使能分发中断寄存器,该寄存器作用是允许给CPU发送中断信号
#if (LOSCFG_KERNEL_SMP == YES) #if (LOSCFG_KERNEL_SMP == YES)
/* register inter-processor interrupt *///注册寄存器处理器间中断处理函数,啥意思?就是当前CPU核向其他CPU核发送中断信号 /* register inter-processor interrupt *///注册核间中断,啥意思?就是CPU各核直接可以发送中断信号
//处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。 //处理器间中断允许一个CPU向系统其他的CPU发送中断信号,处理器间中断(IPI)不是通过IRQ线传输的,而是作为信号直接放在连接所有CPU本地APIC的总线上。
LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//中断处理函数 LOS_HwiCreate(LOS_MP_IPI_WAKEUP, 0xa0, 0, OsMpWakeHandler, 0);//中断处理函数
LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数 LOS_HwiCreate(LOS_MP_IPI_SCHEDULE, 0xa0, 0, OsMpScheduleHandler, 0);//中断处理函数
...@@ -154,7 +154,7 @@ VOID HalIrqInit(VOID) ...@@ -154,7 +154,7 @@ VOID HalIrqInit(VOID)
//硬中断处理函数,这里由硬件触发,调用见于 ..\arch\arm\arm\src\los_dispatch.S //硬中断处理函数,这里由硬件触发,调用见于 ..\arch\arm\arm\src\los_dispatch.S
VOID HalIrqHandler(VOID) VOID HalIrqHandler(VOID)
{ {
UINT32 iar = GIC_REG_32(GICC_IAR); UINT32 iar = GIC_REG_32(GICC_IAR);//从中断确认寄存器获取中断ID号
UINT32 vector = iar & 0x3FFU;//计算中断向量号 UINT32 vector = iar & 0x3FFU;//计算中断向量号
/* /*
...@@ -165,12 +165,12 @@ VOID HalIrqHandler(VOID) ...@@ -165,12 +165,12 @@ VOID HalIrqHandler(VOID)
if (vector >= OS_HWI_MAX_NUM) { if (vector >= OS_HWI_MAX_NUM) {
return; return;
} }
g_curIrqNum = vector; g_curIrqNum = vector;//记录当前中断ID号
OsInterrupt(vector);//调用上层中断处理函数 OsInterrupt(vector);//调用上层中断处理函数
/* use orignal iar to do the EOI */ /* use orignal iar to do the EOI */
GIC_REG_32(GICC_EOIR) = iar; GIC_REG_32(GICC_EOIR) = iar;//更新中断结束寄存器
} }
//获取中断控制器版本 //获取中断控制器版本
CHAR *HalIrqVersion(VOID) CHAR *HalIrqVersion(VOID)
......
...@@ -63,7 +63,7 @@ enum { ...@@ -63,7 +63,7 @@ enum {
#define GICC_PMR (GICC_OFFSET + 0x04) /* Interrupt Priority Mask Register */ //中断优先级屏蔽寄存器 #define GICC_PMR (GICC_OFFSET + 0x04) /* Interrupt Priority Mask Register */ //中断优先级屏蔽寄存器
#define GICC_BPR (GICC_OFFSET + 0x08) /* Binary Point Register */ //二进制点寄存器 #define GICC_BPR (GICC_OFFSET + 0x08) /* Binary Point Register */ //二进制点寄存器
#define GICC_IAR (GICC_OFFSET + 0x0c) /* Interrupt Acknowledge Register */ //中断确认寄存器 #define GICC_IAR (GICC_OFFSET + 0x0c) /* Interrupt Acknowledge Register */ //中断确认寄存器
#define GICC_EOIR (GICC_OFFSET + 0x10) /* End of Interrupt Register */ //中断结寄存器 #define GICC_EOIR (GICC_OFFSET + 0x10) /* End of Interrupt Register */ //中断结寄存器
#define GICC_RPR (GICC_OFFSET + 0x14) /* Running Priority Register */ //运行优先寄存器 #define GICC_RPR (GICC_OFFSET + 0x14) /* Running Priority Register */ //运行优先寄存器
#define GICC_HPPIR (GICC_OFFSET + 0x18) /* Highest Priority Pending Interrupt Register */ //最高优先级挂起中断寄存器 #define GICC_HPPIR (GICC_OFFSET + 0x18) /* Highest Priority Pending Interrupt Register */ //最高优先级挂起中断寄存器
#endif #endif
......
git add -A git add -A
git commit -m '鸿蒙内核源码分析(中断概念篇) | 外人眼中权势滔天的当红海公公 | 百篇博客分析鸿蒙源码 | v43.01 git commit -m '鸿蒙内核源码分析(中断管理篇) | 硬中断的实现类似观察者模式 | 百篇博客分析鸿蒙源码 | v44.01
百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码 百万汉字注解 + 百篇博客分析 => 挖透鸿蒙内核源码
https://weharmony.gitee.io https://my.oschina.net/weharmony
' '
git push origin master git push origin master
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册