前面呢,我们讲了中断中的数据结构以及中断的硬件框架,以及大概的提了一下设备树中是怎么去描述中断的,今天呢,我们就来详细讲一讲:
在硬件上,“中断控制器”只有GIC这一个,但是我们在软件上也可以把上图中的“GPIO”称为“中断控制器”。很多芯片有多个GPIO模块,比如GPIO1、GPIO2等等。所以软件上的“中断控制器”就有很多个:GIC、GPIO1、GPIO2等等。
GPIO1连接到GIC,GPIO2连接到GIC,所以GPIO1的父亲是GIC,GPIO2的父亲是GIC。
假设GPIO1有32个中断源,但是它把其中的16个汇聚起来向GIC发出一个中断,把另外16个汇聚起来向GIC发出另一个中断。这就意味着GPIO1会用到GIC的两个中断,会涉及GIC里的2个hwirq。
这些层级关系、中断号(hwirq),都会在设备树中有所体现。
我们先来
我们可以发现GIC产生的中断一共有三种,这里只是稍微提一下,我们还是把重点放在设备树上面,当然,我们后面还是会单独开一章去讲,这里我们可以知道,一共有三种,也就是
SPIs也就是共享中断,也就是我们最常去使用的,这个是每个CPU都可以可以看到的,也就是可以处理的
PPIS也就是私有的外设中断,因为每个CPU都是有着自己的定时器的,这个产生的中断也就是PPI了
SGI的话就是不同的CPU之间进行通信产生的中断来着
接着我们来看看中断框架中各个部分应该要包含什么:
就是其实驱动的话,我们是只需要去知道最左边就行,但是我们还是来讲一下左边:
首先对于GIC中断控制器:
我们需要具备一个compatible属性嘛,这样子才能去跟驱动程序进行匹配,然后还得指明这是一个interrupt_controller,还得有一个#interrupt_cells属性嘛,用来描述需要使用多少个元素去描述一个中断嘛,当然,这是对于他的子节点的
再来看GPIO中断控制器:
一样的,那三个属性是必须要的,然后还得声明上一级使用的哪个中断控制器里面的哪一个中断,这里就涉及到属性interrupt_parent,以及去使用哪一个中断嘛,也就是interrupts = <>这里面的元素就是由他的父亲级决定的
最后呢,就是我们需要去写的了:
指定中断:
其实都是差不多的
设备树里中断节点的示例:
从设备树反推IMX6ULL的中断体系,如下,比之前的框图多了一个“GPC INTC”:
GPC INTC的英文是:General Power Controller, Interrupt Controller。它提供中断屏蔽、中断状态查询功能,实际上这些功能在GIC里也实现了,个人觉得有点多余。除此之外,它还提供唤醒功能,这才是保留它的原因。
那么到这里,我们就差不多讲完了,下一篇,我们来讲讲GIC的中断处理流程,完结,撒花(doge.)