Exynos4412 中断驱动开发相关问题总结
1、Linux 中如何標識一個外部中斷?
? ? ?在linux kernel中,我們使用下面兩個ID來標識一個來自外設的中斷:
a -- IRQ number
? ? ? CPU需要為每一個外設中斷編號,我們稱之IRQ Number。這個IRQ number是一個虛擬的interrupt ID,和硬件無關,僅僅是被CPU用來標識一個外設中斷。
b -- HW interrupt ID
? ? ? ?對于interrupt controller而言,它收集了多個外設的interrupt request line并向上傳遞,因此,interrupt controller需要對外設中斷進行編碼。Interrupt controller用HW interrupt ID來標識外設的中斷(即硬件中斷號是對于中斷控制器來講的)。在interrupt controller級聯的情況下,僅僅用HW interrupt ID已經不能唯一標識一個外設中斷,還需要知道該HW interrupt ID所屬的interrupt controller(HW interrupt ID在不同的Interrupt controller上是會重復編碼的)。
? ? ? 系統中所有的interrupt controller會形成樹狀結構,對于每個interrupt controller都可以連接若干個外設的中斷請求(我們稱之interrupt?source),interrupt controller會對連接其上的interrupt source(根據其在Interrupt controller中物理特性)進行編號(也就是HW interrupt ID了)。但這個編號僅僅限制在本interrupt controller范圍內。
? ? ? 要注意,這里的中斷控制器并不是GIC,而是每一個中斷的 interrupt - parent,下面講解設備樹時會提到。
2、中斷節點在設備樹中的描述
? ? ? 在Device Tree Source文件中,對于那些產生中斷的外設,我們需要定義interrupt-parent和interrupts屬性:
(1)interrupt-parent
? ? ? ? ? 表明該外設的interrupt request line物理的連接到了哪一個中斷控制器上,中斷控制器會對中斷源進行描述;
(2)interrupts
? ? ? ? 這個屬性描述了具體該外設產生的interrupt的細節信息(也就是傳說中的interrupt specifier)。例如:HW interrupt?ID(由該外設的device node中的interrupt-parent指向的interrupt controller解析)、interrupt觸發類型等。
? ? ?對于Interrupt controller,我們需要定義interrupt-controller和#interrupt-cells的屬性:
(1)interrupt-controller
? ? ? ? 表明該device node就是一個中斷控制器
(2)#interrupt-cells
? ? ? ?該中斷控制器用多少個cell(一個cell就是一個32-bit的單元)描述一個外設的interrupt request line。具體每個cell表示什么樣的含義由interrupt controller自己定義。
(3)interrupts和interrupt-parent
? ? ? 對于那些不是root?的interrupt controller,其本身也是作為一個產生中斷的外設連接到其他的interrupt?controller上,因此也需要定義interrupts和interrupt-parent的屬性。
舉個例子,這是上面編寫按鍵驅動時的中斷描述:
[cpp]?view plaincopy
3、Linux 內核對中斷的初始化過程
? ? ?ARM linux內核啟動時,首先運行的是linux/arch/arm/kernel/head.S,進行一些初始化工作,然后調用main.c->start_kernel()函數,進而調用early_irq_init()函數進行初始化、init_IRQ()函數進行中斷初始化、建立異常向量表
【init_IRQ ---> irqchip_init ---> of_irq_init】
[cpp]?view plaincopy
extern struct of_device_id __irqchip_begin[];
[cpp]?view plaincopy
? ? ?這個數據結構主要被用來進行Device node和driver模塊進行匹配用的。從該數據結構的定義可以看出,在匹配過程中,device name、device type和DT compatible string都是考慮的因素。更細節的內容請參考__of_device_is_compatible函數。
? ? __irqchip_begin就是內核irq chip table的首地址,這個table也就保存了kernel支持的所有的中斷控制器的ID信息(用于和device node的匹配)。
void __init of_irq_init(const struct of_device_id *matches)
? ? ? ?of_irq_init函數執行之前,系統已經完成了device tree的初始化,因此系統中的所有的設備節點都已經形成了一個樹狀結構,每個節點代表一個設備的device node。of_irq_init是在所有的device node中尋找中斷控制器節點,形成樹狀結構(系統可以有多個interrupt controller,之所以形成中斷控制器的樹狀結構,是為了讓系統中所有的中斷控制器驅動按照一定的順序進行初始化)。之后,從root interrupt controller節點開始,對于每一個interrupt controller的 device node,掃描irq chip table,進行匹配,一旦匹配到,就調用該interrupt controller的初始化函數,并把該中斷控制器的device node以及parent中斷控制器的device node作為參數傳遞給irq chip driver。
4、中斷觸發后的處理流程
a -- 具體CPU architecture相關的模塊會進行現場保護,然后調用machine driver對應的中斷處理handler;
b -- machine driver對應的中斷處理handler中會根據硬件的信息獲取HW interrupt ID,并且通過irq domain模塊翻譯成IRQ number
c -- ?調用該IRQ number 對應的high level irq event handler,在這個high level的handler中,會通過和interupt controller交互,進行中斷處理的flow control(處理中斷的嵌套、搶占等),當然最終會遍歷該中斷描述符的IRQ action list,調用外設的specific handler來處理該中斷
d -- 具體CPU architecture相關的模塊會進行現場恢復。
總結
以上是生活随笔為你收集整理的Exynos4412 中断驱动开发相关问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows 8.1 新增控件之 Co
- 下一篇: 智能家居APP原型设计(附下载链接)—基