知识杂货铺

不卖切糕

View on GitHub
7 September 2018 02:42

Linux驱动分析 - 中断

by 宋强

中断控制器驱动层次

Linux中的中断控制器总共分为三层,分别是最上层的驱动接口层,不同种类中断的流程层和硬件相关接口层。

最上层地驱动器接口层

最上层的驱动器接口层主要是用于其他驱动程序例如GPIO、Audio和Video等使用的,是一个最高层的硬件无关实现,具体接口有:

int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, 
        const char *name, void *dev);
void *free_irq(unsigned int irq, void *dev_id);

当释放中断之后系统会检查是否还有设备使用这个中断,没有的话就会disable这个中断,

(on a shared irq, the caller must ensure the interrupt is disabled on the card it drives before calling this function. 这句不明白。kernel/irq/manage.c:1718)。

这个函数会在所有中断处理函数都返回之后才会返回,所以一定不要在中断处理函数中调用。

void disbale_irq(unsigned int irq);

等待所有失能中断的中断处理函数完成之后失能中断,使能和失能操作会嵌套使能和失能。

可以在中断上下文中使用,但是要非常小心(需要遵循什么条件?)

void enable_irq(unsigend int irq);

会抵消一次disable_irq产生的影响,只有在满足desc->irq_data.chip->bus_lock还有desc->chip->bus_sync_unlock都为NULL的时候才能在中断函数中调用(暂时不明白)

disable_irq_nosync() (SMP only);

synchronize_irq() (SMP only);

省略。

int irq_set_irq_type(unsigned int irq, unsigned int type);

用于设置触发模式,可选的type定义在include/linux/irq.h中 IRQ_TYPE_* 变量。

int irq_set_irq_wake(unsigned int irq, unsigned int on);

用于设置此路中断是否能够唤醒睡眠中的系统,第二个参数为enable或disable。

int irq_set_handler_data(unisgned int irq, void *data);

存储自定义数据用的。

int irq_set_chip(unsigned int irq, struct irq_chip *chip);

关联irq号和chip descriptor用。

int irq_set_chip_data(unsigned int irq, void *data);

存储芯片相关自定义数据。

芯片内部的中断使能失能接口

处理器可以通过寄存器设置屏蔽所有的中断,而这样的操作在Linux中是通过local_irq_disable()和local_irq_enable()两个函数完成的。

不同种类中断的流程层

对中断的总结和分类导致了流程层的产生,相同种类的中断处理流程相同,总共有这几种:

系统有默认的可用的处理函数,还不清楚是否需要自己重写。

底层中断控制器封装接口

这个也是我们写中断控制器驱动的话需要实现的接口,所有的接口函数都定义在一个irq_chip结构体中。

一般情况下至少实现irq_ack,然后可能需要实现irq_mask,irq_unmask,irq_set_type还有irq_set_wake等。

具体有关这些函数的说明可以在include/linux/irq.h:400找到

中断控制器的模型和全局中断号的映射

程序中通过设置irq_chip的parents属性为父中断的中断号的方式来配置中断级联,所以DT中既指定了interrupt-controller又指定了interrupts的这里interrupts里面的中断号就是整个中断控制器级联到父中断控制器上使用的夫中断控制器的中断号。

ARM中的GIC与TI的INTC

armv7以及armv9都是使用的ARM公司设计的GIC作为最上级的中断控制器,但是am33xx系列等TI芯片使用的是TI自己的INTC中断控制器,不过这两个的驱动一般都不用我们关心,和芯片内核紧密相关的驱动都会由上游厂家维护。

tags: Linux - 驱动 - 中断