提到中断就必须了解到GIC,下面先了解一下GIC

一、GIC概念

 GIC(Generic Interrupt Controller)是ARM公司提供的一个通用的中断控制器。GIC通过AMBA(Advanced Microcontroller Bus Architecture)这样的片上总线连接到一个或者多个ARM processor上。

下面是Exynos4412-fs4412 开发板(内核版本为 Linux 3.14)的中断源连线:

二、设备树中中断如何工作

与遵循树的自然结构而进行的地址转换不同,机器上的任何设备都可以发起和终止中断信号。另外地址的编址也不同于中断信号,前者是设备树的自然表示,而后者者表现为独立于设备树结构的节点之间的链接。描述中断连接需要四个属性:

■  interrupt-controller - 一个空的属性定义该节点作为一个接收中断信号的设备。

■  #interrupt-cells - 这是一个中断控制器节点的属性。它声明了该中断控制器的中断指示符中 cell 的个数(类似于 #address-cells 和 #size-cells)。

■  interrupt-parent - 这是一个设备节点的属性,包含一个指向该设备连接的中断控制器的 phandle。那些没有 interrupt-parent 的节点则从它们的父节点中继承该属性。

■  interrupts - 一个设备节点属性,包含一个中断指示符的列表,对应于该设备上的每个中断输出信号

中断指示符是一个或多个 cell 的数据(由 #interrupt-cells 指定),这些数据指定了该设备连接至哪些输入中断。在以下的例子中,大部分设备都只有一个输出中断,但也有可能在一个设备上有多个输出中断。一个中断指示符的意义完全取决于与中断控制器设备的 binding。每个中断控制器可以决定使用几个 cell 来唯一的定义一个输入中断。

下面的代码为我们 Coyote's Revenge 模型机添加了中断连接:

[cpp] view plaincopy
  1. / {
  2. compatible = "acme,coyotes-revenge";
  3. #address-cells = <1>;
  4. #size-cells = <1>;
  5. interrupt-parent = <&intc>;
  6. cpus {
  7. #address-cells = <1>;
  8. #size-cells = <0>;
  9. cpu@0 {
  10. compatible = "arm,cortex-a9";
  11. reg = <0>;
  12. };
  13. cpu@1 {
  14. compatible = "arm,cortex-a9";
  15. reg = <1>;
  16. };
  17. };
  18. serial@101f0000 {
  19. compatible = "arm,pl011";
  20. reg = <0x101f0000 0x1000 >;
  21. interrupts = < 1 0 >;
  22. };
  23. serial@101f2000 {
  24. compatible = "arm,pl011";
  25. reg = <0x101f2000 0x1000 >;
  26. interrupts = < 2 0 >;
  27. };
  28. gpio@101f3000 {
  29. compatible = "arm,pl061";
  30. reg = <0x101f3000 0x1000
  31. 0x101f4000 0x0010>;
  32. interrupts = < 3 0 >;
  33. };
  34. intc: interrupt-controller@10140000 {
  35. compatible = "arm,pl190";
  36. reg = <0x10140000 0x1000 >;
  37. interrupt-controller;
  38. #interrupt-cells = <2>;
  39. };
  40. spi@10115000 {
  41. compatible = "arm,pl022";
  42. reg = <0x10115000 0x1000 >;
  43. interrupts = < 4 0 >;
  44. };
  45. external-bus {
  46. #address-cells = <2>
  47. #size-cells = <1>;
  48. ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet
  49. 1 0  0x10160000   0x10000     // Chipselect 2, i2c controller
  50. 2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash
  51. ethernet@0,0 {
  52. compatible = "smc,smc91c111";
  53. reg = <0 0 0x1000>;
  54. interrupts = < 5 2 >;
  55. };
  56. i2c@1,0 {
  57. compatible = "acme,a1234-i2c-bus";
  58. #address-cells = <1>;
  59. #size-cells = <0>;
  60. reg = <1 0 0x1000>;
  61. interrupts = < 6 2 >;
  62. rtc@58 {
  63. compatible = "maxim,ds1338";
  64. reg = <58>;
  65. interrupts = < 7 3 >;
  66. };
  67. };
  68. flash@2,0 {
  69. compatible = "samsung,k8f1315ebm", "cfi-flash";
  70. reg = <2 0 0x4000000>;
  71. };
  72. };
  73. };

需要注意的事情:

■ 这个机器只有一个中断控制器:interrupt-controller@10140000。

■ 中断控制器节点上添加了‘inc:’标签,该标签用于给根节点的 interrupt-parent 属性分配一个 phandle。这个 interrupt-parent 将成为本系统的默认值,因为所有的子节点都将继承它,除非显示覆写这个属性。

■ 每个设备使用 interrupts 属性来不同的中断输入线。

■ #interrupt-cells 是 2,所以每个中断指示符都有 2 个 cell。本例使用一种通用的模式,也就是用第一个 cell 来编码中断线号;然后用第二个 cell 编码标志位,比如高电平/低电平有效,或者边缘/水平触发。对于任何给定的中断控制器,请参考该控制器的 binding 文档以了解指示符如何编码。

三、GIC DTS描述

1、中断系统概述

对于中断系统,主要有三个角色:

(1)processor:主要用于处理中断;

(2)Interrupt Generating Device:通过硬件的interrupt line表明自身需要处理器的进一步处理(例如有数据到来、异常状态等)

(3)interrupt controller:负责收集各个外设的异步事件,用有序、可控的方式通知一个或者多个processor。

2、DTS如何描述Interrupt Generating Device

     对于Interrupt Generating Device,我们需要定义下面两个属性:

(1) Interrupt属性:该属性主要描述了中断的HW interrupt ID以及类型。

(2)interrupt-parent 属性:该属性主要描述了该设备的interrupt request line连接到哪一个interrupt controller。

我们以一个简单的串口为例子,

uart3: serial@48020000 {
       compatible = "ti,omap4-uart";
       reg = <0x48020000 0x100="">;
       interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
       ti,hwmods = "uart3";
       clock-frequency = <48000000>;
};

对于uart3,interrupts属性用3个cell(对于device tree,cell是指由32bit组成的一个信息单位)表示。GIC_SPI 描述了interrupt type。

对于GIC,它可以管理4种类型的中断:

1)外设中断(Peripheral interrupt)

根据目标CPU的不同,外设的中断可以分成PPI(Private Peripheral Interrupt)SPI(Shared Peripheral Interrupt)。PPI只能分配给一个确定的processor,而SPI可以由Distributor将中断分配给一组Processor中的一个进行处理。外设类型的中断一般通过一个interrupt request line的硬件信号线连接到中断控制器,可能是电平触发的(Level-sensitive),也可能是边缘触发的(Edge-triggered)。

2)软件触发的中断(SGI,Software-generated interrupt)

软件可以通过写GICD_SGIR寄存器来触发一个中断事件,这样的中断,可以用于processor之间的通信。

3)虚拟中断(Virtual interrupt)和Maintenance interrupt。

这两种中断和本文无关,不再赘述。

在DTS中,外设的interrupt type有两种,一种是SPI,另外一种是PPI。SGI用于processor之间的通信,和外设无关。     uart3的interrupt属性中的74表示该外设使用的GIC interrupt ID号。GIC最大支持1020个HW interrupt ID,具体的ID分配情况如下:1)ID0~ID31是用于分发到一个特定的process的interrupt。标识这些interrupt不能仅仅依靠ID,因为各个interrupt source都用同样的ID0~ID31来标识,因此识别这些interrupt需要interrupt ID + CPU interface number。ID0~ID15用于SGI,ID16~ID31用于PPI。PPI类型的中断会送到指定的process上,和其他的process无关。SGI是通过写GICD_SGIR寄存器而触发的中断。Distributor通过processor source ID、中断ID和target processor ID来唯一识别一个SGI。2)ID32~ID1019用于SPI。uart3的interrupt属性中的IRQ_TYPE_LEVEL_HIGH用来描述触发类型。

3、DTS如何描述GIC

linux-3.14\arch\arm\boot\dts\exynos4412.dtsi文件中

[java] view plaincopy
  1. #include "exynos4x12.dtsi"
  2. /{
  3. compatible = "samsung,exynos4412";
  4. gic: interrupt-controller@10490000 {
  5. cpu-offset = <0x4000>;
  6. };
  7. interrupt-controller@10440000 {
  8. samsung,combiner-nr = <20>;
  9. interrupts =    <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,
  10. <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,
  11. <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,
  12. <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,
  13. <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;
  14. };
  15. };

a -- compatible属性

      compatible属性用来描述GIC的programming model。该属性的值是string list,定义了一系列的modle(每个string是一个model)。这些字符串列表被操作系统用来选择用哪一个driver来驱动该设备。

假设定义该属性:compatible = “a厂商,p产品”, “标准bbb类型设备”。那么linux kernel可能首先使用“a厂商,p产品”来匹配适合的driver,如果没有匹配到,那么使用字符串“标准bbb类型设备”来继续寻找适合的driver。

compatible属性有两个应用场景:

1)对于root node,compatible属性是用来匹配machine type的(参考Device Tree相关文档)

2)对于普通的HW block的节点,例如interrupt-controller,compatible属性是用来匹配适合的driver的。

b -- interrupt-controller 

interrupt-controller这个没有定义value的属性用来表明本设备节点就是一个interrupt controller。理解#interrupt-cells这个属性需要理解interrupt specifier和interrupt domain这两个概念。interrupt specifier其实就是外设interrupt的属性值,对于uart3而言,其interrupt specifier就是<GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,也就是说,interrupt specifier定义了一个外设产生中断的规格(HW interrupt ID + interrupt type)。

具体如何解析interrupt specifier?这个需要限定在一定的上下文中,不同的interrupt controller会有不同的解释。因此,对于一个包含多个interrupt controller的系统,每个interrupt controller及其相连的外设组成一个interrupt domain,各个外设的interrupt specifier只能在属于它的那个interrupt domain中得到解析。#interrupt-cells定义了在该interrupt domain中,用多少个cell来描述一个外设的interrupt specifier。

c -- reg

reg属性定义了GIC的memory map的地址.

三、GIC的HW block diagram描述

1、Distributor

Distributor的主要的作用是检测各个interrupt source的状态,控制各个interrupt source的行为,分发各个interrupt source产生的中断事件到各个processor。

Distributor对中断的控制包括:

1)中断enable或者disable的控制。Distributor对中断的控制分成两个级别。一个是全局中断的控制。一旦disable了全局的中断,那么任何的interrupt source产生的interrupt event都不会被传递到CPU interface。另外一个级别是对针对各个interrupt source进行控制,disable某一个interrupt source会导致该interrupt event不会分发到CPU interface,但不影响其他interrupt source产生interrupt event的分发。

2)控制中断事件分发到process。一个interrupt事件可以分发给一个process,也可以分发给若干个process。

3)优先级控制。

4)interrupt属性设定。例如是level-sensitive还是edge-triggered,是属于group 0还是group 1。

Distributor可以管理若干个interrupt source,这些interrupt source用ID来标识,我们称之interrupt ID

2、CPU interface

CPU interface这个block主要用于和process进行接口。该block的主要功能包括:

1)enable或者disable

对于ARM,CPU interface block和process之间的中断信号线是nIRQ和nFIQ这两个signal。如果disable了中断,那么即便是Distributor分发了一个中断事件到CPU interface,但是也不会assert指定的nIRQ或者nFIQ通知processor。

2)ackowledging中断

processor会向CPU interface block应答中断,中断一旦被应答,Distributor就会把该中断的状态从pending状态修改成active。如果没有后续pending的中断,那么CPU interface就会deassert nIRQ或者nFIQ的signal。如果在这个过程中又产生了新的中断,那么Distributor就会把该中断的状态从pending状态修改成pending and active。这时候,CPU interface仍然会保持nIRQ或者nFIQ信号的asserted状态,也就是向processor signal下一个中断。

3)中断处理完毕的通知

当interrupt handler处理完了一个中断的时候,会向写CPU interface的寄存器从而通知GIC CPU已经处理完该中断。做这个动作一方面是通知Distributor将中断状态修改为deactive,另外一方面,如果一个中断没有完成处理,那么后续比该中断优先级低的中断不会assert到processor。一旦标记中断处理完成,被block掉的那些比当前优先级低的中断就会递交给processor。

4)设定priority mask

通过priority mask,可以mask掉一些优先级比较低的中断,这些中断不会通知到CPU。

5)设定preemption的策略

6)在多个中断事件同时到来的时候,选择一个优先级最高的通知processor


四、本次按键中断节点填写

1、查看原理图

2、可以看到中断 EINT9  EINT10  挂在GPX1下 1 2

3、查看中断号

4、确定其父节点

5、确定中断节点

[java] view plaincopy
  1. fs4412-key{
  2. compatible = "fs4412,key";
  3. interrupt-parent = <&gpx1>;
  4. interrupts = <1 2>,<2 2>;
  5. };

Exynos4412 中断驱动开发(三)—— 设备树中中断节点的创建相关推荐

  1. Exynos4412 中断驱动开发(一)—— 中断基础及中断的注册过程

    一.中断基础概念 所谓中断,指CPU在执行程序的过程中,出现了某些突发事件即待处理,CPU必须暂停当前的程序.转去处理突发事件,处理完毕后CPU又返回原程序被中断的位置并继续执行. 1.中断分类 a ...

  2. Exynos4412 中断驱动开发(二)—— 中断处理流程分析

    前面已经学习了中断的注册过程,下面由一张流程图来看一下当中断发生时的处理流程: 中断发生之后处理流程 a -- 具体的CPU architecture相关模块进行现场保护,然后调用machine dr ...

  3. Exynos4412 中断驱动开发相关问题总结

    1.Linux 中如何标识一个外部中断? 在linux kernel中,我们使用下面两个ID来标识一个来自外设的中断: a -- IRQ number CPU需要为每一个外设中断编号,我们称之IRQ ...

  4. 边缘计算开源框架EdgeXFoundry的部署应用开发(三)设备服务开发

    边缘计算开源框架EdgeXFoundry的部署应用开发(三)设备服务开发 使用SDK开发真实设备接入服务 着手编写一个温湿度设备接入 准备相关文件及目录 脚本可选,用于单文件编译测试 编写温湿度设备接 ...

  5. uboot命令实践:fdt系列命令实践和在编程设备树中添加节点

    前言 uboot启动后,会将设备树传递给内核,本文将学习uboot中的设备树相关的命令的使用,最后将想通过实现一个命令,向设备树添加和者修改自定义的节点. 一 fdt命令族 fdt命令族概览 => ...

  6. linux 设备树 usb控制器,linux 设备树中 dwc3 节点的phys参数含义

    找了好久今天找到了,记录一下: &dwc3_0 { ... phys = ; ... } Required properties (port (child) nodes): lane0: - ...

  7. linux内核模块编程(六)----字符设备驱动中断开发

    先给自己打个广告,本人的微信公众号正式上线了,搜索:张笑生的地盘,主要关注嵌入式软件开发,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题 一 why 字符设备驱动在我们 ...

  8. linux 设备树及节点引用

    1.ARM Linux社区为什么要引入设备树 Linux之父Linus Torvalds闲来无事,在翻看ARM Linux代码的时候,有一天终于忍不住了.他在2011年3月17日的ARM Linux邮 ...

  9. Linux下设备树中常用的of操作函数举例

    文章目录 前言 一.在设备树中添加自定义节点 二.用到的of函数简介 1.用到的结构体 2.各of函数介绍 1>.of_find_node_by_path 2>.of_find_prope ...

最新文章

  1. R语言plotly可视化:plotly可视化分裂的分组小提琴图、每个小提琴图内部分为两组数据、每个分组占小提琴图的一半(Split violin plot in R with plotly)
  2. S2-045漏洞利用工具解决方案
  3. ITK:预定义操作以对应两个图像中的像素
  4. python递归调用详解_Python递归调用自己的函数
  5. 那个一年发4篇cell的研究生后来怎样了?
  6. HTML基础(2)——边框
  7. Ajax同步交互与异步交互
  8. 为2440搭建NFS开发环境【ZT】
  9. linux 内核编号含义_linux内核(kernel)版本号的意义
  10. 实例化新的Android片段的最佳做法
  11. php调用拼多多的接口
  12. CSS样式表初始化杂谈
  13. 使用thrift做c++,java和python的相互调用 - jinghong - ITeye技术网站
  14. Atitit 非结构化数据管理法 目录 1. 什么是非结构化数据? 1 2. 对非结构化数据也即对全文数据的搜索主要有两种方法: 2 2.1. 顺序扫描法(Serial Scanning): 2 2
  15. 银行软开开发篇[转]
  16. 同一个服务器装oracle,windows下同一台服务器上装有两个ORACLE数据库实例,通过命令启停数据库...
  17. 新手常见(五国)(-v图)错误解决(原版,破解kernel,补丁kext下载)
  18. javase printwriter 打印流
  19. JavaWeb进阶之路:MyBatis-配置解析
  20. 判断两个整数是否互质

热门文章

  1. Mybatis各种模糊查询及#和$区别
  2. smarty二维foreach示例[顺代一维数组],再次加强版
  3. linux编译源码问题 环境变量的设置
  4. oracle raise_application_error,RAISE_ APPLICATION_ ERROR--之异常处理
  5. 如何使用Webpack在HTML,CSS和JavaScript之间共享变量
  6. 为Tueri.io构建React图像优化组件
  7. 先知模型 facebook_Facebook先知
  8. 小程序获取微信用户绑定的手机号
  9. codevs1014 装箱问题
  10. spring ioc原理