百万汉字注解 >> 精读内核源码,中文注解分析, 深挖地基工程,大脑永久记忆,四大码仓每日同步更新< gitee | github | csdn | coding >
百篇博客分析 >> 故事说内核,问答式导读,生活式比喻,表格化说明,图形化展示,主流站点定期更新中< oschina | csdn | 掘金 | weharmony >
关于中断部分系列篇将用三篇详细说明整个过程.
中断概念篇 中断概念很多,比如中断控制器,中断源,中断向量,中断共享,中断处理程序等等.本篇做一次整理.先了解透概念才好理解中断过程.本篇的主角是海公公,用海公公打比方说明白中断各个概念.
中断管理篇 从中断初始化HalIrqInit
开始,到注册中断的LOS_HwiCreate
函数,到消费中断函数的 HalIrqHandler
,剖析鸿蒙内核实现中断的过程,很像设计模式中的观察者模式. 可前往鸿蒙内核源码分析(总目录)查看.
中断切换篇 用自下而上的方式,从中断源头纯汇编代码往上跟踪代码细节.说清楚保存和恢复中断现场TaskIrqContext
过程.可前往鸿蒙内核源码分析(总目录)查看.
中断模块的核心是中断控制器,这可是 皇上(CPU) 身边的大红人海公公,外部人员找皇上办点事都必须经过它.
中断是指出现需要时,CPU暂停执行当前程序,转而执行新程序的过程。即在程序运行过程中,出现了一个必须由CPU立即处理的事务。此时,CPU暂时中止当前程序的执行转而处理这个事务,这个过程就叫做中断。如图:
外设可以在没有CPU介入的情况下完成一定的工作,但某些情况下也需要CPU为其执行一定的工作。通过中断机制,在外设不需要CPU介入时,CPU可以执行其它任务,而当外设需要CPU时,将通过产生中断信号使CPU立即中断当前任务来响应中断请求。这样可以使CPU避免把大量时间耗费在等待、查询外设状态的操作上,大大提高系统实时性以及执行效率。
与中断相关的硬件可以划分为三类:设备(找皇上办事的事多了去)、中断控制器(海公公)、CPU(皇上威武,执天下耳)。
设备
发起中断的源,当设备需要请求CPU时,产生一个中断信号,该信号连接至中断控制器。
中断控制器
中断控制器是CPU众多外设中的一个,管理外设的外设,外设要使用CPU得先经过它仲裁, 它一方面接收其它外设中断引脚的输入,另一方面它会发出中断信号给CPU。所以可以通过对中断控制器编程来打开和关闭中断源、设置中断源的优先级和触发方式。说的是海公公有权屏蔽大臣们的折子,降低娘娘们被临幸的等级,让你们见不到咱皇上.
常用的中断控制器有VIC(Vector Interrupt Controller)和GIC(General Interrupt Controller)。在ARM Cortex-M系列中使用的中断控制器是NVIC(Nested Vector Interrupt Controller)。在ARM Cortex-A7中使用的中断控制器是GIC。
CPU
中断控制器分发的中断源的请求给各个CPU,CPU收到请求便中断当前正在执行的任务,转而执行中断处理程序。
用二张图说明下三者的关系,能看出咱海公公的权利有多大.
中断控制器文档可前往 ARM中断控制器 gic_v2.pdf 查看每个寄存器的作用.以下为鸿蒙内核一小部分GIC寄存器的配置.
#ifdef LOSCFG_PLATFORM_BSP_GIC_V2
#define GICC_CTLR (GICC_OFFSET + 0x00) /* CPU Interface Control Register */ //CPU接口控制寄存器
#define GICC_PMR (GICC_OFFSET + 0x04) /* Interrupt Priority Mask Register */ //中断优先级屏蔽寄存器
#define GICC_BPR (GICC_OFFSET + 0x08) /* Binary Point Register */ //二进制点寄存器
#define GICC_IAR (GICC_OFFSET + 0x0c) /* Interrupt Acknowledge Register */ //中断确认寄存器
#define GICC_EOIR (GICC_OFFSET + 0x10) /* End of Interrupt Register */ //中断结尾寄存器
#define GICC_RPR (GICC_OFFSET + 0x14) /* Running Priority Register */ //运行优先寄存器
#define GICC_HPPIR (GICC_OFFSET + 0x18) /* Highest Priority Pending Interrupt Register */ //最高优先级挂起中断寄存器
#endif
所谓中断源,即引起中断的事件或原因,或发出中断申请的来源.
可分为外部中断源和内部中断源两大类。
外部中断源是指由CPU的外部事件引发的中断。主要包括:
内部中断源是指由CPU的内部事件(异常)引发的中断,主要包括:
这些都是想找咱皇上办事的人.
把中断源划分为三种中断类型
PPI:私有外设中断(Private Peripheral Interrupt),是每个CPU私有的中断。最多支持16个PPI中断,硬件中断号从ID16~ID31。PPI通常会送达到指定的CPU上,应用场景有CPU本地时钟。
类似于皇上自己的一些私事,不方便说的,比如大明湖畔的夏雨荷来了.
SGI:软件触发中断(Software Generated Interrupt)通常用于多核间通讯,最多支持16个SGI中断,硬件中断号从ID0~ID15。SGI通常在内核中被用作核间中断(inter-processor interrupts),信号会送达到系统指定的CPU上.
主要用于多个皇上(CPU)并存的情况,皇上们直接约一起玩.
SPI:公用外设中断(Shared Peripheral Interrupt),最多可以支持988个外设中断,硬件中断号从ID32~ID1019。
属于外部公事,这种事比较多,比如无法预测的吴三桂同志突然造反了,黄河决堤了等等,所以排号也多,除了前面两种其他的都属于这类的.
“紧急事件”需向CPU提出申请(发一个电脉冲信号),要求CPU暂停当前执行的任务,转而处理该“紧急事件”,这一申请过程称为中断请求,这个申请必须经过中断控制器仲裁.
找皇上办事的人先写报告走流程,要求都要经过咱海公公处过滤.
中断源向中断控制器发送中断信号(电平触发或边沿触发),中断控制器对中断进行仲裁,确定优先级,将中断信号送给CPU。中断源产生中断信号的时候,会将中断触发器置“1”,表明该中断源产生了中断,要求CPU去响应该中断。
相当于办事的折子,折子统一到了海公公这处理,编号.
为使系统能够及时响应并处理所有中断,系统根据中断时间的重要性和紧迫程度,将中断源分为若干个级别,称作中断优先级。
海公公给折子分好优先级.如花娘娘优先级最高,西施娘娘给的银子少优先级最低.
当外设产生中断请求后,CPU暂停当前的任务,转而响应中断申请,即执行中断处理程序。产生中断的每个设备都有相应的中断处理程序。
海公公把折子交给了咱皇上,皇上一一处理所有折子.
中断号 :每个中断请求信号都会有特定的标志,使得计算机能够判断是哪个设备提出的中断请求,这个标志就是中断号。
中断向量 :中断服务程序的入口地址。
中断向量表是存储中断向量的存储区,中断向量与中断号对应,中断向量在中断向量表中按照中断号顺序存储。
中断向量表是所有中断处理程序的入口,如下图所示中断处理过程:把一个函数(用户中断服务程序)同一个虚拟中断向量表中的中断向量联系在一起。当中断向量对应中断发生的时候,被挂接的用户中断服务程序就会被调用执行。
所有中断都采用中断向量表的方式进行处理,即当一个中断触发时,处理器将直接判定是哪个中断源,然后直接跳转到相应的固定位置进行处理,每个中断服务程序必须排列在一起放在统一的地址上。中断向量表一般由一个数组定义或在起始代码中给出.
皇上把折子一对一的仔细处理,找到给对应折子办事的人.
在用户中断服务程序(ISR)中,分为两种情况:
TaskIrqContext
切换,用户中断服务程序和中断后续程序运行完毕后退出中断模式,返回被中断的线程。TaskContext
的切换.具体下面办事的人把事办完.
在允许中断嵌套的情况下,在执行中断服务程序的过程中,如果出现高优先级的中断,当前中断服务程序的执行将被打断,以执行高优先级中断的中断服务程序,当高优先级中断的处理完成后,被打断的中断服务程序才又得到继续执行,如果需要进行线程调度,线程的上下文切换将在所有中断处理程序都运行结束时才发生,如下图所示。
先把西施娘娘的事停了,现如花娘娘杀到,优先级高,老奴安排皇上先办如花娘娘,再接着办西施娘娘.奴才担心皇上这身子骨吃不吃得消.
当外设较少时,可以实现一个外设对应一个中断号,但为了支持更多的硬件设备,可以让多个设备共享一个中断号,共享同一个中断号的中断处理程序形成一个链表。当外部设备产生中断申请时,系统会遍历执行中断号对应的中断处理程序链表直到找到对应设备的中断处理程序。在遍历执行过程中,各中断处理程序可以通过检测设备ID,判断是否是这个中断处理程序对应的设备产生的中断。
简单一句话就是:共用一个折子,分别办多件事.
属于SGI中断类型,对于多核系统,中断控制器允许一个CPU的硬件线程去中断其他CPU的硬件线程,这种方式被称为核间中断。核间中断的实现基础是多CPU内存共享,采用核间中断可以减少某个CPU负荷过大,有效提升系统效率。
typedef enum {
//鸿蒙核间中断
LOS_MP_IPI_WAKEUP, //唤醒CPU
LOS_MP_IPI_SCHEDULE,//调度CPU
LOS_MP_IPI_HALT, //停止CPU
} MP_IPI_TYPE;
可以看出CPU之间可以相互唤醒,调度,停止.
核间中断有点特殊,出现于多个皇上(CPU)的情况. 皇上之间可以相互使唤,停止工作.比如:A皇上通过海公公让B皇上休息.
功能分类 | 接口名 | 描述 |
---|---|---|
创建和删除中断 | LOS_HwiCreate | 中断创建,注册中断号、中断触发模式、中断优先级、中断处理程序。中断被触发时,handleIrq会调用该中断处理程序 |
LOS_HwiDelete | 删除中断 | |
打开和关闭所有中断 | LOS_IntUnLock | 打开当前处理器所有中断响应 |
LOS_IntLock | 关闭当前处理器所有中断响应 | |
LOS_IntRestore | 恢复到使用LOS_IntLock关闭所有中断之前的状态 | |
使能和屏蔽指定中断 | LOS_HwiDisable | 中断屏蔽(通过设置寄存器,禁止CPU响应该中断) |
LOS_HwiEnable | 中断使能(通过设置寄存器,允许CPU响应该中断) | |
设置中断优先级 | LOS_HwiSetPriority | 设置中断优先级 |
触发中断 | LOS_HwiTrigger | 触发中断(通过写中断控制器的相关寄存器模拟外部中断) |
清除中断寄存器状态 | LOS_HwiClear | 清除中断号对应的中断寄存器的状态位,此接口依赖中断控制器版本,非必需 |
核间中断 | LOS_HwiSendIpi | 向指定核发送核间中断,此接口依赖中断控制器版本和cpu架构,该函数仅在SMP模式下支持 |
设置中断亲和性 | LOS_HwiSetAffinity | 设置中断的亲和性,即设置中断在固定核响应(该函数仅在SMP模式下支持) |
v44.03 (中断管理篇) | 硬中断的实现<>观察者模式 < csdn | harmony | 掘金 >
v43.03 (中断概念篇) | 外人眼中权势滔天的当红海公公 < csdn | harmony | 掘金 >
v42.03 (中断切换篇) | 中断切换在切换什么? < csdn | harmony | 掘金 >
v41.03 (任务切换篇) | 汇编逐行注解分析任务上下文 < csdn | harmony | 掘金 >
v40.03 (汇编汇总篇) | 所有的汇编代码都在这里 < csdn | harmony | 掘金 >
v39.03 (异常接管篇) | 社会很单纯,复杂的是人 < csdn | harmony | 掘金 >
v38.03 (寄存器篇) | ARM所有寄存器一网打尽,不再神秘 < csdn | harmony | 掘金 >
v37.03 (系统调用篇) | 全盘解剖系统调用实现过程 < csdn | harmony | 掘金 >
v36.03 (工作模式篇) | CPU是韦小宝,有哪七个老婆? < csdn | harmony | 掘金 >
v35.03 (时间管理篇) | Tick是操作系统的基本时间单位 < csdn | harmony | 掘金 >
v34.03 (原子操作篇) | 是谁在为原子操作保驾护航? < csdn | harmony | 掘金 >
v33.03 (消息队列篇) | 进程间如何异步解耦传递大数据 ? < csdn | harmony | 掘金 >
v32.03 (CPU篇) | 内核是如何描述CPU的? < csdn | harmony | 掘金 >
v31.03 (定时器篇) | 内核最高优先级任务是谁? < csdn | harmony | 掘金 >
v30.03 (事件控制篇) | 任务间多对多的同步方案 < csdn | harmony | 掘金 >
v29.03 (信号量篇) | 信号量解决任务同步问题 < csdn | harmony | 掘金 >
v28.03 (进程通讯篇) | 进程间通讯有哪九大方式? < csdn | harmony | 掘金 >
v27.03 (互斥锁篇) | 互斥锁比自旋锁可丰满许多 < csdn | harmony | 掘金 >
v26.03 (自旋锁篇) | 想为自旋锁立贞节牌坊! < csdn | harmony | 掘金 >
v25.03 (并发并行篇) | 怎么记住并发并行的区别? < csdn | harmony | 掘金 >
v24.03 (进程概念篇) | 进程在管理哪些资源? < csdn | harmony | 掘金 >
v23.02 (汇编传参篇) | 汇编如何传递复杂的参数? < csdn | harmony | 掘金 >
v22.02 (汇编基础篇) | CPU在哪里打卡上班? < csdn | harmony | 掘金 >
v21.02 (线程概念篇) | 是谁在不断的折腾CPU? < csdn | harmony | 掘金 >
v20.02 (用栈方式篇) | 栈是构建底层运行的基础 < csdn | harmony | 掘金 >
v19.02 (位图管理篇) | 为何进程和线程优先级都是32个? < csdn | harmony | 掘金 >
v18.02 (源码结构篇) | 内核500问你能答对多少? < csdn | harmony | 掘金 >
v17.02 (物理内存篇) | 这样记伙伴算法永远不会忘 < csdn | harmony | 掘金 >
v16.02 (内存规则篇) | 内存管理到底在管什么? < csdn | harmony | 掘金 >
v15.02 (内存映射篇) | 什么是内存最重要的实现基础 ? < csdn | harmony | 掘金 >
v14.02 (内存汇编篇) | 什么是虚拟内存的实现基础? < csdn | harmony | 掘金 >
v13.02 (源码注释篇) | 热爱是所有的理由和答案 < csdn | harmony | 掘金 >
v12.02 (内存管理篇) | 虚拟内存全景图是怎样的? < csdn | harmony | 掘金 >
v11.02 (内存分配篇) | 内存有哪些分配方式? < csdn | harmony | 掘金 >
v10.02 (内存主奴篇) | 紫禁城的主子和奴才如何相处? < csdn | harmony | 掘金 >
v09.02 (调度故事篇) | 用故事说内核调度 < csdn | harmony | 掘金 >
v08.02 (总目录) | 百万汉字注解 百篇博客分析 < csdn | harmony | 掘金 >
v07.02 (调度机制篇) | 任务是如何被调度执行的? < csdn | harmony | 掘金 >
v06.02 (调度队列篇) | 就绪队列对调度的作用 < csdn | harmony | 掘金 >
v05.02 (任务管理篇) | 谁在让CPU忙忙碌碌? < csdn | harmony | 掘金 >
v04.02 (任务调度篇) | 任务是内核调度的单元 < csdn | harmony | 掘金 >
v03.02 (时钟任务篇) | 触发调度最大的动力来自哪里? < csdn | harmony | 掘金 >
v02.02 (进程管理篇) | 进程是内核资源管理单元 < csdn | harmony | 掘金 >
v01.09 (双向链表篇) | 谁是内核最重要结构体? < csdn | harmony | 掘金 >
访问注解仓库地址
Fork 本仓库 >> 新建 Feat_xxx 分支 >> 提交代码注解 >> 新建 Pull Request
新建 Issue
各大站点搜 “鸿蒙内核源码分析” .欢迎转载,请注明出处.