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
需要注意的事情:
■ 這個機器只有一個中斷控制器: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
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
總結
以上是生活随笔為你收集整理的Exynos4412 中断驱动开发(三)—— 设备树中中断节点的创建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 安装adobe字体,Adob
- 下一篇: 使用ColorUI组件