中断是最常用的函数。无论是单片机还是Linux系统,都需要中断,对其深入了解是非常有必要的。为什么需要中断?答:处理器的速度比外设快很多,内核必须处理其他任务。只有外设准备好了,CPU才会转而去处理外设。一般的通信方式有:轮询(polling)和中断(interrupt)。除了网络传输适合轮询外,中断一般用于其他情况。中断分类中断是指在CPU正常运行过程中,由于内部和外部事件或程序预先安排的事件,CPU暂时停止正在运行的程序,转而转向为内部或外部预先安排的事件服务的程序,并且服务完成。然后返回继续执行暂时中断的程序。常说的中断其实就是第一种,异步中断。陷阱是系统调用,从用户态落到内核态,比如调用open、write等系统调用,也算是中断。这两个都是正常的,所以会返回到下一条指令。故障是当内存页丢失等时,会返回到当前指令继续执行,看内核会不会修复。如果无法修复,就会挂掉。终止意味着系统直接挂掉。中断子系统的硬件架构在一个完整的设备中,与中断相关的硬件可以分为三类,它们是:设备、中断控制器和CPU本身。设备:设备是中断源。当设备需要请求某项服务时,会发起硬件中断信号。通常,信号会被连接到中断控制器进行进一步处理。在现代移动设备中,发起中断的设备可以位于SoC(片上系统)芯片之外,也可以位于芯片内部,因为目前大多数SoC都集成了大量的硬件IP,如I2C、SPI、DisplayController等,是内部中断源。中断控制器:中断控制器负责收集所有中断源发起的中断。几乎所有现有的中断控制器都是可编程的。通过对中断控制器进行编程,我们可以控制各个中断源的优先级,中断电类型也可以开启和关闭某个中断源。在smp系统中,它甚至可以控制某个中断源送到哪个CPU去处理。对于基于ARM的SoC,最常用的中断控制器是VIC(向量中断控制器)。进入多核时代后,GIC(GeneralInterruptController)的应用逐渐增多。STM32单片机的中断控制器称为NVIC,ARM架构的中断控制器一般为GIC,不同的架构有不同的中断控制器。CPU:最终响应中断的部分。它通过可编程中断控制器的编程操作来控制和管理系统中的各个中断。当中断控制器最终确定一个中断可以被处理时,它会通知一个或几个cpu去处理这个中断,虽然中断控制器可以同时通知几个cpu去处理某个中断,但实际上只有一个cpu会最终响应中断请求,但是具体哪个cpu响应可能是随机的,中断控制器在硬件上保证了这个特性,但是对于中断系统也取决于操作系统的软件实现。为什么需要中断控制器?CPU要做的主要是计算。一个CPU有很多中断可以使用,其中也有优先级。由于中断太多,我们需要在中断进入CPU处理之前进入中断控制器,让中断控制器控制中断的优先级、触发方式、使能和禁止等,减轻CPU的负担,让CPU专注于计算。中断控制器的级联根据中断的个数,可以级联中断控制器来满足要求。例如,在GIC中断控制器之前连接EINT中断控制器或其他中断控制器,以分层控制不同的中断。中断控制器的级联有两种:机器级级联,级联的初始化代码当然位于板子的初始化代码中(arch/xxx/mach-xxx),因为只要使用这个板子的设备或SOC,必须使用此子控制器。在设备级级联,因为设备不一定是系统的标准设备,所以中断控制器的级联操作应该在设备的驱动程序中实现。机器设备的级联,由于内核事先知道了子控制器的硬件连接信息,可以方便的为子控制器保留相应的irq_desc结构和irq号,处理起来比较简单。设备级的级联不同,驱动程序必须动态确定组合设备中每个子设备的irq号和irq_desc结构。我只讨论机器级别的级联,同样的原理可以用于设备级别的关联。中断子系统架构整个中断子系统的架构分为4层,最底层(第四层)是硬件,包括CPU和中断控制器。第三层是CPU的驱动和中断控制器的驱动,由原芯片厂负责。第二层是Linux内核提供的通用中断处理模块。这一层的意义在于希望用户在第一层编写的驱动在移植时更方便,保持接口不变,避免用户直接使用原来的芯片。API,而是Linux的API。第一层是驱动工程师每天写的驱动。
