任何一個(gè)嵌入式系統(tǒng)級(jí)的設(shè)計(jì)都離不開中斷,對(duì)于擁有雙cotex-A9的Zynq來說也一樣。Zynq的中斷設(shè)計(jì)由ARM與GIC pl390中斷控制器組成,用于接收IOP(I/O peripherals)與PL的信號(hào)。如下圖所示,CPU中的中斷分為PPIs(private peripheral interrupts),SGIs(software generated interrupts)與SPIs(shared peripheral interrupts)其中,通過寫GIC(generic interrupt controller)的寄存器來產(chǎn)生SGIs。從Xilinx給出的ug585手冊(cè)中可以清晰的看出GIC與PPIs,SCIs,SPIs的關(guān)系。GIC可以管理從PS與PL部分產(chǎn)生的中斷,并且對(duì)其使能,優(yōu)先級(jí)等作出設(shè)置,與普通ARM相同,所有的中斷都會(huì)賦予一個(gè)中斷ID,用作CPU的相應(yīng)。
對(duì)于SPIs來說,其中斷源也可以從任意子系統(tǒng)PS中的IOP或者PL部分的信號(hào)產(chǎn)生。下圖為中斷控制器的框圖,更能夠體現(xiàn)出PPIs,SPIs,SGIs的關(guān)系,中斷響應(yīng)后會(huì)從與之對(duì)應(yīng)的CPU接口進(jìn)行處理。
下面就分別來說說這三種中斷,對(duì)于SGIs來說,每一個(gè)CPU核可以通過SGIs來響應(yīng)自己的,其他的或者兩個(gè)CPU核的中斷,通過寫ICDSGIR控制器來控制SGIs,ICDICFR0是控制SGIs優(yōu)先級(jí)及觸發(fā)條件的寄存器,這是一個(gè)只讀寄存器,由此我們可以看出SGIs的觸發(fā)條件是上升沿,不可以進(jìn)行更改。
對(duì)于PPIs來說,每一個(gè)CPU都連接到5個(gè)PPI,同樣的,ICDICFR1為PPIs的優(yōu)先級(jí)及觸發(fā)條件控制寄存器,是只讀的,因而PPIs的觸發(fā)條件也不可更改。需要注意到的是,PL部分的快速響應(yīng)中斷FIQ(fast interrupt)信號(hào)與普通中斷IRQ(interrupt)需要被送往中斷控制器中,所以即便ICDICFR1規(guī)定IRQ與FIQ的響應(yīng)等級(jí)為low level,但是他們的在PS與PL接口的響應(yīng)等級(jí)仍是high。
最后是SPIs,有多達(dá)60種中斷類型可以由任一CPU或者PL部分產(chǎn)生,為了響應(yīng)這么多的中斷,我們必須對(duì)GIC進(jìn)行編寫,但是Zynq啟動(dòng)的過程中并沒有對(duì)GIC進(jìn)行編寫,因此我們需要在SDK中對(duì)其進(jìn)行編輯。同樣的,這些中斷的觸發(fā)條件也已經(jīng)被規(guī)定了,不能夠進(jìn)行更改。SPI的中斷太多了,不一一列舉,大家可以去ug585中查看這些中斷。但是讓筆者比較疑惑的是,既然中斷的觸發(fā)類型不能夠被更改,為什么SDK的庫中會(huì)有更改中斷觸發(fā)形式的函數(shù)呢。GIC是Zynq中斷的大腦,這些中斷遠(yuǎn)不能達(dá)到GIC pl39所能控制的極限。
我們以一個(gè)簡(jiǎn)單地中斷響應(yīng)程序來作為例子,了解如何使用Zynq的中斷,同樣的使用XPS+SDK來進(jìn)行設(shè)計(jì)。
首先我們使用BSB新建工程;
同樣的選擇ZC702,刪除所有的外設(shè);
添加兩個(gè)個(gè)GPIO外設(shè)的IP核,一個(gè)外設(shè)作為LED顯示,另一個(gè)外設(shè)作為中端IO,這里記得在中端IO的設(shè)置中勾選interruput使能,不需要對(duì)GPIO做其他設(shè)置;
下一步要將GPIO外設(shè)加入中斷中,可以看到IRQ_F2P沒有任何連接;
我們將中斷IO加入IRQ,單擊L to H : no connection,添加中斷源;
XPS部分就設(shè)計(jì)完畢了,生成比特流之后導(dǎo)入SDK中,進(jìn)行軟件設(shè)計(jì)。SDK為我們提供了使用中斷的庫文件 xscugic.h(system control unit generic interrupt controller),沒有查到scu的縮寫,姑且認(rèn)為是系統(tǒng)控制單元的縮寫,比較好理解。
中斷設(shè)置很簡(jiǎn)單,跟其他的單片機(jī)程序一樣,主要有以下幾部分
首先進(jìn)行GPIO初始化,這個(gè)就不需要多說了。
其次進(jìn)行中斷的設(shè)置,如中斷控制,全局中斷允許等等,主要用了以下函數(shù)
XScuGic_LookupConfig 中斷設(shè)置查找
XScuGic_CfgInitialize GIC初始化
XScuGic_SetPriorityTriggerType 設(shè)置中斷優(yōu)先級(jí)及中斷觸發(fā)方式,筆者在這里
有些疑問,手冊(cè)上面說中斷觸發(fā)方式不可以更改這里為何有這個(gè)函數(shù)呢,還需要研究一下
XScuGic_Connect 設(shè)置中斷服務(wù)程序入口地址
XScuGic_Enable GIC允許
XGpio_InterruptGlobalEnable GPIO全局中斷允許
XGpio_InterruptEnable 相應(yīng)GPIO中斷允許
Xil_ExceptionInit 異常處理函數(shù)
Xil_ExceptionRegisterHandler
Xil_ExceptionEnable
最后編寫中斷服務(wù)程序,在中斷服務(wù)程序中需要先禁止中斷使能,完成服務(wù)程序后再打開。
總結(jié)來看,由于SDK提供的庫文件使得Zynq中斷使用很方便簡(jiǎn)單,并且中斷源很多,加上PS部分與PL部分的配合,使用非常靈活。
評(píng)論