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

提到中断就必须了解到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
在CODE上查看代码片派生到我的代码片
  1. / {  
  2.   
  3.     compatible = "acme,coyotes-revenge";  
  4.     #address-cells = <1>;  
  5.     #size-cells = <1>;  
  6.     interrupt-parent = <&intc>;  
  7.   
  8.     cpus {  
  9.         #address-cells = <1>;  
  10.         #size-cells = <0>;  
  11.         cpu@0 {  
  12.             compatible = "arm,cortex-a9";  
  13.             reg = <0>;  
  14.         };  
  15.   
  16.         cpu@1 {  
  17.             compatible = "arm,cortex-a9";  
  18.             reg = <1>;  
  19.         };  
  20.     };  
  21.   
  22.     serial@101f0000 {  
  23.         compatible = "arm,pl011";  
  24.         reg = <0x101f0000 0x1000 >;  
  25.         interrupts = < 1 0 >;  
  26.     };  
  27.   
  28.     serial@101f2000 {  
  29.         compatible = "arm,pl011";  
  30.         reg = <0x101f2000 0x1000 >;  
  31.         interrupts = < 2 0 >;  
  32.     };  
  33.   
  34.     gpio@101f3000 {  
  35.         compatible = "arm,pl061";  
  36.         reg = <0x101f3000 0x1000  
  37.                0x101f4000 0x0010>;  
  38.         interrupts = < 3 0 >;  
  39.     };  
  40.   
  41.     intc: interrupt-controller@10140000 {  
  42.         compatible = "arm,pl190";  
  43.         reg = <0x10140000 0x1000 >;  
  44.         interrupt-controller;  
  45.         #interrupt-cells = <2>;  
  46.     };  
  47.   
  48.     spi@10115000 {  
  49.         compatible = "arm,pl022";  
  50.         reg = <0x10115000 0x1000 >;  
  51.         interrupts = < 4 0 >;  
  52.     };  
  53.   
  54.     external-bus {  
  55.         #address-cells = <2>  
  56.         #size-cells = <1>;  
  57.         ranges = <0 0  0x10100000   0x10000     // Chipselect 1, Ethernet  
  58.                   1 0  0x10160000   0x10000     // Chipselect 2, i2c controller  
  59.                   2 0  0x30000000   0x1000000>; // Chipselect 3, NOR Flash  
  60.   
  61.   
  62.         ethernet@0,0 {  
  63.             compatible = "smc,smc91c111";  
  64.             reg = <0 0 0x1000>;  
  65.             interrupts = < 5 2 >;  
  66.         };  
  67.   
  68.         i2c@1,0 {  
  69.             compatible = "acme,a1234-i2c-bus";  
  70.             #address-cells = <1>;  
  71.             #size-cells = <0>;  
  72.             reg = <1 0 0x1000>;  
  73.             interrupts = < 6 2 >;  
  74.   
  75.             rtc@58 {  
  76.                 compatible = "maxim,ds1338";  
  77.                 reg = <58>;  
  78.                 interrupts = < 7 3 >;  
  79.             };  
  80.         };  
  81.   
  82.         flash@2,0 {  
  83.             compatible = "samsung,k8f1315ebm""cfi-flash";  
  84.             reg = <2 0 0x4000000>;  
  85.         };  
  86.     };  
  87. };  


需要注意的事情:

■ 这个机器只有一个中断控制器: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
在CODE上查看代码片派生到我的代码片
  1. #include "exynos4x12.dtsi"  
  2. /{        
  3.     compatible = "samsung,exynos4412";       
  4.     gic: interrupt-controller@10490000 {        
  5.         cpu-offset = <0x4000>;   
  6.     };       
  7.   
  8.     interrupt-controller@10440000 {              
  9.         samsung,combiner-nr = <20>;              
  10.         interrupts =    <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>,                         
  11.                 <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>,                         
  12.                 <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>,                        
  13.                 <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>,                          
  14.                 <0 107 0>, <0 108 0>, <0 48 0>, <0 42 0>;       
  15.     };  
  16. };  

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
在CODE上查看代码片派生到我的代码片
  1. fs4412-key{        
  2.     compatible = "fs4412,key";       
  3.     interrupt-parent = <&gpx1>;  
  4.     interrupts = <1 2>,<2 2>;  
  5. };  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

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

前面已经学习了中断的注册过程&#xff0c;下面由一张流程图来看一下当中断发生时的处理流程&#xff1a; 中断发生之后处理流程 a -- 具体的CPU architecture相关模块进行现场保护&#xff0c;然后调用machine driver执行对应的中断处理handler; b -- machine driver对应中断处…

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

一、中断基础概念 所谓中断&#xff0c;指CPU在执行程序的过程中&#xff0c;出现了某些突发事件即待处理&#xff0c;CPU必须暂停当前的程序。转去处理突发事件&#xff0c;处理完毕后CPU又返回原程序被中断的位置并继续执行。 1、中断分类 a -- 内部中断和外部中断 根据中断的…

rubymine 调试 redmine

1、安装debase和ruby-debug-ide包。&#xff08;注意版本&#xff0c;rubymine 8.0.2下&#xff0c;bitnami下的版本需安装debase -v 0.2.1版本&#xff0c;网上有文章说用debase -v 0.2.2beta6。容易在rubymine启动调试时出现找不到ruby-debug-ide等错误提示&#xff09; 启动…

Linux 设备驱动中的 I/O模型(二)—— 异步通知和异步I/O

阻塞和非阻塞访问、poll() 函数提供了较多地解决设备访问的机制&#xff0c;但是如果有了异步通知整套机制就更加完善了。 异步通知的意思是&#xff1a;一旦设备就绪&#xff0c;则主动通知应用程序&#xff0c;这样应用程序根本就不需要查询设备状态&#xff0c;这一点非常类…

判断链表是否有环

链表有环的情况一般是链表的尾指向前面的节点而不是null&#xff0c;如head->node1->node2->node3->node4->tail->node2&#xff0c;该链表存在环。判断环是否存在可以借助两个指针&#xff0c;一个指针每次迭代只移动一步&#xff0c;第二个指针每次迭代移动…

Linux 设备驱动中的 I/O模型(一)—— 阻塞和非阻塞I/O

在前面学习网络编程时&#xff0c;曾经学过I/O模型 Linux 系统应用编程——网络编程&#xff08;I/O模型&#xff09;&#xff0c;下面学习一下I/O模型在设备驱动中的应用。 回顾一下在Unix/Linux下共有五种I/O模型&#xff0c;分别是&#xff1a; a -- 阻塞I/O b -- 非阻塞I/O…

Python 爬虫进阶六之多进程的用法

python 中的多线程其实并不是真正的多线程&#xff0c;并不能做到充分利用多核 CPU 资源。 如果想要充分利用&#xff0c;在 python 中大部分情况需要使用多进程&#xff0c;那么这个包就叫做 multiprocessing。 借助它&#xff0c;可以轻松完成从单进程到并发执行的转换。mult…

Linux 设备驱动的并发控制

Linux 设备驱动中必须要解决的一个问题是多个进程对共享的资源的并发访问&#xff0c;并发的访问会导致竞态&#xff0c;即使是经验丰富的驱动工程师也常常设计出包含并发问题bug 的驱动程序。 一、基础概念 1、Linux 并发相关基础概念 a -- 并发&#xff08;concurrency&#…

第三章:多坐标系

第一节&#xff1a;为什么要有多坐标系 当我们使用一个坐标系来描绘整个场景的时候&#xff0c;场景中的任意点都可以用该坐标系描述&#xff0c;此时如果有一只羊一遍摇动着耳朵&#xff0c;一边走&#xff0c;这个时候如果进行坐标的转换会发现异常的麻烦&#xff0c;此时如果…

Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用

关与设备树的概念&#xff0c;我们在Exynos4412 内核移植&#xff08;六&#xff09;—— 设备树解析 里面已经学习过&#xff0c;下面看一下设备树在设备驱动开发中起到的作用 Device Tree是一种描述硬件的数据结构&#xff0c;设备树源(Device Tree Source)文件&#xff08;以…

Android 网络通信框架Volley简介(Google IO 2013)

1. 什么是Volley 在这之前&#xff0c;我们在程序中需要和网络通信的时候&#xff0c;大体使用的东西莫过于AsyncTaskLoader&#xff0c;HttpURLConnection&#xff0c;AsyncTask&#xff0c;HTTPClient&#xff08;Apache&#xff09;等&#xff0c;今年的Google I/O 2013上&…

Linux 设备驱动开发 —— platform设备驱动应用实例解析

前面我们已经学习了platform设备的理论知识Linux 设备驱动开发 —— platform 设备驱动 &#xff0c;下面将通过一个实例来深入我们的学习。 一、platform 驱动的工作过程 platform模型驱动编程&#xff0c;需要实现platform_device(设备)与platform_driver&#xff08;驱动&am…

Python爬虫入门四urllib库的高级用法

1.设置headers 有些网站不会同意程序直接用上面的方式进行访问&#xff0c;如果识别有问题&#xff0c;那么站点根本不会响应&#xff0c;所以为了完全模拟浏览器的工作&#xff0c;我们需要设置一些 Headers 的属性。 首先&#xff0c;打开我们的浏览器&#xff0c;调试浏览器…

进程上下文、中断上下文及原子上下文

谈论进程上下文 、中断上下文 、 原子上下文之前&#xff0c;有必要讨论下两个概念&#xff1a; a -- 上下文 上下文是从英文context翻译过来&#xff0c;指的是一种环境。相对于进程而言&#xff0c;就是进程执行时的环境&#xff1b; 具体来说就是各个变量和数据&#xff0c;…

Linux 文件系统与设备文件系统 (二)—— sysfs 文件系统与Linux设备模型

提到 sysfs 文件系统 &#xff0c;必须先需要了解的是Linux设备模型&#xff0c;什么是Linux设备模型呢&#xff1f; 一、Linux 设备模型 1、设备模型概述 从2.6版本开始&#xff0c;Linux开发团队便为内核建立起一个统一的设备模型。在以前的内核中没有独立的数据结构用来让内…

Python爬虫入门七正则表达式

已经搞定了怎样获取页面的内容&#xff0c;不过还差一步&#xff0c;这么多杂乱的代码夹杂文字我们怎样把它提取出来整理呢&#xff1f;下面就开始介绍一个十分强大的工具&#xff0c;正则表达式 1.了解正则表达式 正则表达式是用来匹配字符串非常强大的工具&#xff0c;在其…

Linux 文件系统与设备文件系统 (一)—— udev 设备文件系统

一、什么是Linux设备文件系统 首先我们不看定义&#xff0c;定义总是太抽象很难理解&#xff0c;我们先看现象。当我们往开发板上移植了一个新的文件系统之后&#xff08;假如各种设备驱动也移植好了&#xff09;&#xff0c;启动开发板&#xff0c;我们用串口工具进入开发板&a…

情人节,教大家使用css画出一朵玫瑰花。

情人节到了&#xff0c;给大家来一朵高端的玫瑰花。 在网上看到的一个canvas实现的玫瑰花&#xff0c;效果很好&#xff0c;但是代码被压缩过&#xff0c;也没有注释&#xff0c;看的云里雾里的。 今天我教大脚用CSS来实现一朵玫瑰花。 先看效果 首先我们画出一个花瓣 1、画出一…

Linux 字符设备驱动开发基础(六)—— VFS 虚拟文件系统解析

一、VFS 虚拟文件系统基础概念 Linux 允许众多不同的文件系统共存&#xff0c;并支持跨文件系统的文件操作&#xff0c;这是因为有虚拟文件系统的存在。虚拟文件系统&#xff0c;即VFS&#xff08;Virtual File System&#xff09;是 Linux 内核中的一个软件抽象层。它通过一些…

vim使用—实现程序的自动补齐(C语言)

使用过Source Insight的人一定对它的自动补全功能印象深刻&#xff0c;在很多的集成开发环境中&#xff0c;也都支持自动补全。vim做为一个出色的编辑器&#xff0c;这样的功能当然少不了。至于如何实现程序自动补全&#xff0c;网上教程很多。这里&#xff0c;我将自己配置过程…