linux系统常见的中断(中断子系统专栏之二)
在上一篇文章中,我们简要分析了中断子系统框架,本章我们将通过实现一个虚拟的中断控制器驱动,说明如何进行中断控制器驱动开发。本章的内容大概分为如下几部分:
一、实现虚拟中断控制器的可行性说明
二、中断控制器驱动的开发流程
三、虚拟中断控制器驱动设计说明
一、实现虚拟中断控制器的可行性说明在进行虚拟中断控制器的设计之前,我们先说明下LINUX系统中硬件中断触发后的处理过程。如下图所示,当硬件中断触发后,各架构的CPU板级代码经过处理后,大都会调用do_IRQ/generic_handle_irq接口,从而调用具体irq_desc的irq flow handler接口,进行中断处理函数的调用等工作。基于此,我们可以提供操作接口调用generic_handle_irq,从而模拟硬件中断触发,实现中断处理流程的触发操作,这是我们实现虚拟中断控制器的理论基础。
二、中断控制器驱动的开发流程
在提供了模拟硬件中断触发的机制后,我们再确认下中断控制器驱动的开发流程,主要分为如下几个部分:
- 为该中断控制器的所有hw irq line,均创建对应的irq_desc(因为我是在ubuntu16.04上开发的虚拟中段控制器驱动,并没有提供设备树支持,因此在驱动开发时完成了所有irq_desc的申请,如使用设备树开发的话,则无须申请所有的irq_desc。当有外设用到其中的一个hw irq line时,则在该设备的设备节点中引用对应的hw irq index及该hw irq index对应controller的设备节点名即可,然后在外设的驱动中调用irq_of_parse_and_map接口即可(而在该接口中若检测到该hw irq line尚未创建irq_desc,则进行irq_desc的创建,同时在该hw irq所属的irq domain中,完成hw irq index与logic irq index的映射)。设备树这种方式确实很好,仅在hw irq被使用时方进行irq_desc的创建及注册操作);
- 为该irq controller 提供操作接口,即完成struct irq_chip类型变量的定义及赋值,主要包括中断的使能控制、中断触发方式的设置等等;
- 为该中断控制器创建irq domain,以便存储该irq controller的hw irq line与logic irq index的映射关系,并完成该irq_desc与irq_chip、irq flow handler的map操作操作等。
有了以上的基础后,我们即可以进行虚拟中断控制器驱动的开发,以便了解中断控制器驱动的开发流程。
虚拟中断控制器型号介绍与说明本次我们开发的虚拟中断控制器包含两个型号virt0808、virt0813,这两个中断控制器均提供16个hw irq line。然后这两个中断控制器级联在一起(virt0813连接至virt0808的第16个中断号,virt0808作为root controller),连接方式如下图所示。
这两个中断控制器均提供如下几个寄存器:
- 中断状态寄存器(status reg);
- 中断使能寄存器(mask reg);
- 中断电平触发控制寄存器(level reg);
- 中断边沿触发控制寄存器(edeg reg)
以上即为虚拟中断控制器的主要内容,下面为这两个中断控制器进行驱动开发。
虚拟中断控制器驱动开发设计针对虚拟中断控制器驱动,主要包括如下几步部分内容:
- 提供virt0808虚拟中断控制器驱动,并在sysfs目录下创建属性文件irq_trigger,供应用程序模拟触发硬件中断;
- 提供外设驱动,申请中断,作为对虚拟中断的验证。
针对virt0808,定义数据结构virt_irq_provider,主要的成员包括:
- 存储应用程序设置的模拟触发中断的hw irq line index(irq_trigger_value);
- 定义struct irq_work类型的变量work,主要用于触发irq中断使用;
- 该irq控制器的logic irq base id,及hw irq line的个数;
- 该irq controller的寄存器;
- 该irq controller对应的irq_chip、irq_domain;
- 该irq controller driver所对应的platform device。
针对模拟硬件中断触发,我们主要借助irq work实现。主要的调用流程如下图所示
- 当应用程序通过向irq_trigger写入需要模拟触发的hw irq line后,则会调用virt0808 driver定义的函数virt0808_irq_store,在该函数中调用irq_work_queue,将该irq work加入irq work queue中,并触发irq work interrupt;
- 而在irq work interrupt的处理函数中调用irq_work_run,处理virt0808 driver定义的处理函数,即virt0808_hwirq_trigger;
- 在virt0808_hwirq_trigger接口中则调用generic_handle_irq接口中,则调用该irq controller对应hw irq line的irq_desc进行中断的处理操作
而针对virt0813而言,其数据结构定义如下,该数据结构的定义与virt_irq_provider的定义类似。
Virt0808 driver
- Virt0808对应irq chip的定义,主要是完成virt0808的操作接口,定义如下
- 定义irq domain操作接口
在进行irq domain的map接口中完成irq desc与irq chip、irq flow handler的绑定操作
- Irq domain、irq desc的创建操作
在probe接口中通过调用如下接口完成irq domain、irq desc的创建操作
以上就是virt0808的驱动程序,完成以上功能后,就完成针对virt0808 irq controller的驱动操作。
Virt0813 driver该设备驱动与virt0808 driver的驱动类似,唯一区别的是,因为virt0813是挂载在virt0808上的,因此当virt0813上中断发生时,cpu首先得到的是virt0808对应引脚中断,然后在virt0808的chain hw irq line的中断处理函数中,通过读取virt0813的中断状态寄存器,确认virt0813上是哪一个hw irq line发生中断,再调用generic_handle_irq接口去处理该中断。处理过程如下图所示:
virt0813_sub_irq_handler的定义如下:
测试驱动
在测试驱动中主要申请两个irq,一个irq是virt0808 irq controller的hw irq line;一个irq是virt0813 irq controller 的hw irq line,该驱动仅仅是测试用,比较简单,代码如下:
测试验证
在该virt irq的目录下执行make &&make install,驱动镜像即在image目录下。
驱动加载:
insmod virt0808_dev.ko
insmod virt0808_irq.ko
insmod virt0813_irq.ko
insmod irq_consumer_dev.ko
insmod irq_consumer_driver.ko
Virt0808 irq controller中断触发验证因我们在测试驱动中,申请了virt0808的第7个中断,因此我们触发该中断,看下该中断对应的中断处理程序有没有调用:
cd /sys/devices/platform/virt0808_irq_dev.0/
echo 6 >>irq_trigger
dmesg
如上图所示,中断处理函数已经执行。下面我们进行virt0813中断的测试,我们申请的是virt0813的第一个中断,执行
命令如下:
cd /sys/devices/platform/virt0813_irq_dev.0
echo 1 >>irq_status
cd /sys/devices/platform/virt0808_irq_dev.0/
echo 15 >>irq_trigger
dmesg
如上图所示,中断处理函数也已经执行成功,测试成功。
以上就是本篇文章的主要内容,我们主要实现了virt irq controller driver,熟悉irq controller driver的开发流程,我们实现的驱动中,两个irq controller通过级联的方式连接,也比较有代表性。我们学习了irq子系统下irq controller driver的开发后,对我们平常的开发有没有帮助呢?当我们需要为一个gpio controller开发驱动,且该gpio controller支持中断时,则可以为该gpio controller创建irq controller driver即可完成该功能(此种功能需求下,可参考virt0813的驱动程序实现该需求)。至此我们完成了irq子系统的学习,针对irq子系统我也就是会开发相应驱动,若要彻底理解中断子系统,还有很长的路要走…后续如果有可能,会再深入学习(本次虚拟驱动的源码链接稍后会发出来,或者在gitee上搜索用户jerry_chg,也可以找到本次的驱动代码)。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com