社区编辑申请
注册/登录
Linux 中断子系统(一):框架
系统 Linux
中断是大家用的最多的功能,不管是单片机还是 Linux 系统,都需要用到中断,对它的深入理解是非常必要的。

中断是大家用的最多的功能,不管是单片机还是 Linux 系统,都需要用到中断,对它的深入理解是非常必要的。

为什么需要中断?

答案:处理器的速度比外设快很多,内核必须要处理其他任务,只有当外设准备好了,CPU才转过来处理外设的事务。

一般通讯方式为:轮询(polling)、中断(interrupt),除了网络传输适合用轮询外,一般其他情况都是用中断。

中断分类

中断是指 CPU 正常运行期间,由于内外部事件或程序预先安排的事件,引起的 CPU 暂时停止正在运行的程序,转而为该内部或外部预先安排的事件服务的程序中去,服务完毕后再返回去继续执行被暂时中断的程序。

常说的中断其实是第一种,异步中断。

陷阱就是系统调用,从用户态陷入到内核态,比如调用 open、write 等系统调用,也算中断。这两种很正常,所以会返回到下一条指令。

故障就是遇到了内存缺页等情况,会返回到当前指令继续执行,看看内核是否会修复完毕,如果修复不了就挂掉了。终止就是系统直接挂掉了。

中断子系统硬件架构

一个完整的设备中,与中断相关的硬件可以划分为3类,它们分别是:设备、中断控制器和CPU本身。

设备:设备是发起中断的源,当设备需要请求某种服务的时候,它会发起一个硬件中断信号,通常,该信号会连接至中断控制器,由中断控制器做进一步的处理。在现代的移动设备中,发起中断的设备可以位于soc(system-on-chip)芯片的外部,也可以位于芯片的内部,因为目前大多数 soc 都集成了大量的硬件 IP,例如 I2C、SPI、Display Controller 等等,就是内部中断源。

中断控制器:中断控制器负责收集所有中断源发起的中断,现有的中断控制器几乎都是可编程的,通过对中断控制器的编程,我们可以控制每个中断源的优先级、中断的电气类型,还可以打开和关闭某一个中断源,在smp系统中,甚至可以控制某个中断源发往哪一个 CPU 进行处理。对于 ARM 架构的 soc,使用较多的中断控制器是VIC(Vector Interrupt Controller),进入多核时代以后,GIC(General Interrupt Controller)的应用也开始逐渐变多。STM32 单片机的中断控制器叫 NVIC,ARM架构的中断控制器一般为GIC,不同架构有不同的中断控制器。

CPU:最终响应中断的部件,它通过对可编程中断控制器的编程操作,控制和管理者系统中的每个中断,当中断控制器最终判定一个中断可以被处理时,他会根据事先的设定,通知其中一个或者是某几个 cpu 对该中断进行处理,虽然中断控制器可以同时通知数个 cpu 对某一个中断进行处理,实际上,最后只会有一个 cpu 相应这个中断请求,但具体是哪个 cpu 进行响应是可能是随机的,中断控制器在硬件上对这一特性进行了保证,不过这也依赖于操作系统对中断系统的软件实现。

为什么需要中断控制器?

CPU 要做的事情主要是运算。一个 CPU 有很多个中断可以使用,他们之间也有优先级。由于中断过多,我们需要中断进入 CPU 处理之前,先进入中断控制器,让中断控制器来控制中断的优先级、触发方式、enable 和 disable等,为CPU减轻负担,让CPU专注于运算。

中断控制器的级联

根据中断数量的不同,中断控制器可以级联,以此来满足需求。比如在 GIC 中断控制器之前都会连接 EINT 中断控制器,或者其他中断控制器,对不同的中断分级管控。

中断控制器的级联有两种类型:

机器级别的级联,级联的初始化代码理所当然地位于板子的初始化代码中(arch/xxx/mach-xxx),因为只要是使用这个板子或SOC的设备,必然要使用这个子控制器。

设备级别的级联,因为该设备并不一定是系统的标配设备,所以中断控制器的级联操作应该在该设备的驱动程序中实现。

机器设备的级联,因为得益于事先已经知道子控制器的硬件连接信息,内核可以方便地为子控制器保留相应的 irq_desc 结构和 irq 编号,处理起来相对简单。

设备级别的级联则不一样,驱动程序必须动态地决定组合设备中各个子设备的 irq 编号和 irq_desc 结构。我只讨论机器级别的级联,设备级别的关联可以使用同样的原理。

中断子系统架构

整个中断子系统的架构分为 4 层,最底层(第四层)为硬件,包括 CPU、中断控制器。第三层是 CPU 的驱动和中断控制器的驱动,由芯片原厂负责。第二层是 Linux 内核提供的通用中断处理模块,这一层存在的意义在于,希望用户在第一层写的驱动在移植的时候更方便,保持接口不变,不让用户直接使用芯片原厂的 API,而是 Linux 的 API。第一层就是驱动工程师日常写的驱动啦。

责任编辑:姜华 来源: 嵌入式Linux系统开发
相关推荐

2021-08-03 15:10:26

2017-07-14 14:35:27

2021-12-14 08:51:23

2021-12-10 08:45:45

2021-08-10 11:30:30

2021-11-30 07:02:10

2021-12-01 07:02:16

2021-11-02 10:53:56

2016-07-22 10:50:56

2021-08-31 11:53:38

2021-12-13 07:28:34

2021-12-20 07:51:16

2015-11-10 16:55:00

性能IO子系统Linux

2021-09-03 09:12:09

2014-09-22 13:31:46

2020-12-29 09:11:33

2021-02-07 08:02:33

Linux内核开源

同话题下的热门内容

如何选择适合的公共 DNSLinux终端居然也可以做文件浏览器?Linux 怎么防止 ssh 被暴力破解Linux下如何配置普通用户的sudo命令权限?我是如何使用 Linux fmt 命令来格式化文本如何在基于 Ubuntu 的 Linux 发行版上安装最新的 Vim 9.0Linux内存管理(Golang实现)Linux Kernel 5.19 正式发布,支持龙芯 CPU架构

编辑推荐

Linux系统下安装MySQL的步骤详解CentOS与Ubuntu有什么不同?Linux下如何使用minicom USB串口为什么你可能想要略过Ubuntu 17.04?Linux中7个判断文件系统类型的方法
我收藏的内容
点赞
收藏

51CTO技术栈公众号