第7章ARM異常中斷處理及編程課件_第1頁(yè)
第7章ARM異常中斷處理及編程課件_第2頁(yè)
第7章ARM異常中斷處理及編程課件_第3頁(yè)
第7章ARM異常中斷處理及編程課件_第4頁(yè)
第7章ARM異常中斷處理及編程課件_第5頁(yè)
已閱讀5頁(yè),還剩189頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第7章ARM異常中斷處理及編程

7.1ARM異常中斷處理概述7.2ARM體系異常中斷種類(lèi)7.3ARM應(yīng)用系統(tǒng)中異常中斷處理程序的安裝7.4ARM的SWI異常中斷處理程序設(shè)計(jì)7.5FIG和IRQ異常中斷程序設(shè)計(jì)7.6基于ARM9芯片S3C2410異常中斷程序設(shè)計(jì)第7章ARM異常中斷處理及編程7.1ARM異常中斷處1第7章ARM異常中斷處理及編程

本章的主要內(nèi)容:●ARM異常中斷處理概述●異常中斷的進(jìn)入與退出●應(yīng)用程序中異常中斷處理程序的安裝●SWI異常中斷處理程序●FIQ和IRQ異常中斷處理程序●復(fù)位異常中斷處理程序●未定義異常中斷●指令預(yù)取中止異常中斷處理程序●數(shù)據(jù)訪問(wèn)中止異常中斷處理程序第7章ARM異常中斷處理及編程本章的主要內(nèi)容:2第7章ARM異常中斷處理及編程

7.1ARM異常中斷處理概述ARM異常中斷處理需要實(shí)現(xiàn)中斷的響應(yīng)、解析跳轉(zhuǎn)和返回等操作,以便支持上層應(yīng)用程序的開(kāi)發(fā)。當(dāng)異常中斷發(fā)生時(shí),系統(tǒng)執(zhí)行完當(dāng)前指令后,將跳轉(zhuǎn)到相應(yīng)的異常中斷處理程序處執(zhí)行。當(dāng)異常中斷處理程序執(zhí)行完成后,程序返回到發(fā)生中斷的指令的下一條指令處執(zhí)行。進(jìn)入異常中斷處理程序時(shí),要保存被中斷的程序的執(zhí)行現(xiàn)場(chǎng)。從異常中斷處理程序退出時(shí),要恢復(fù)被中斷的程序的執(zhí)行現(xiàn)場(chǎng)。ARM體系中常在存儲(chǔ)地址的低端固化了一個(gè)32字節(jié)的硬件中斷向量表,用來(lái)指定各異常中斷及其處理程序的對(duì)應(yīng)關(guān)系。第7章ARM異常中斷處理及編程7.1ARM異常中斷處3第7章ARM異常中斷處理及編程

當(dāng)一個(gè)異常出現(xiàn)后,ARM微處理器執(zhí)行以下操作:

(1)保存處理器當(dāng)前狀態(tài)、中斷屏蔽位以及各條件標(biāo)志位;(2)設(shè)置當(dāng)前程序狀態(tài)寄存器CPSR中相應(yīng)的位;(3)將寄存器lr_mode設(shè)置成返回地址;(4)將程序計(jì)數(shù)器(PC)值設(shè)置成該異常中斷的中斷向量地址,從而跳轉(zhuǎn)到相應(yīng)的異常中斷處理程序處執(zhí)行。接收到中斷請(qǐng)求后,ARM處理器內(nèi)核會(huì)自動(dòng)執(zhí)行以上四步,程序計(jì)數(shù)器PC總是跳轉(zhuǎn)到相應(yīng)的固定地址。

從異常中斷處理程序中返回:(1)恢復(fù)被屏蔽的程序的處理器狀態(tài);(2)返回到發(fā)生異常中斷的指令的下一條指令處繼續(xù)執(zhí)行。當(dāng)異常中斷發(fā)生時(shí),程序計(jì)數(shù)器PC所指的位置對(duì)于各種不同的異常中斷是不同的,同樣,返回地址對(duì)于各種不同的異常中斷也是不同的。第7章ARM異常中斷處理及編程當(dāng)一個(gè)異常出現(xiàn)后,ARM微4第7章ARM異常中斷處理及編程

7.2ARM體系異常中斷種類(lèi)

ARM處理器中主要有7個(gè)異常(2個(gè)中斷異常)●復(fù)位(RESET)●未定義的指令

●軟件中斷

●指令與取終止(PrefechAbort)

●數(shù)據(jù)訪問(wèn)終止(DATAABORT)

●外部中斷請(qǐng)求(IRQ)

●快速中斷請(qǐng)求(FIQ)

第7章ARM異常中斷處理及編程7.2ARM體系異常中5第7章ARM異常中斷處理及編程

7.2.1異常中斷向量表及異常中斷優(yōu)先級(jí)

在ARM體系中,異常中斷向量表的大小為32字節(jié),每異常中斷占4個(gè)字節(jié)。每個(gè)異常中斷對(duì)應(yīng)的中斷向量表中的4個(gè)字節(jié)的空間中存放了一條跳轉(zhuǎn)指令或者一條向PC寄存器中賦值的數(shù)據(jù)訪問(wèn)指令。第7章ARM異常中斷處理及編程7.2.1異常中斷向量表及6第7章ARM異常中斷處理及編程

第7章ARM異常中斷處理及編程7第7章ARM異常中斷處理及編程

1.復(fù)位異常在以ARM為核的系統(tǒng)中,引起復(fù)位的原因有:

●上電復(fù)位●復(fù)位引腳上的復(fù)位脈沖●對(duì)系統(tǒng)電源檢測(cè)發(fā)現(xiàn)過(guò)壓或欠壓?!駮r(shí)鐘異常復(fù)位。

ARM處理器復(fù)位后,將進(jìn)行以下操作:

●強(qiáng)制進(jìn)入管理模式;●強(qiáng)制進(jìn)入ARM狀態(tài);●跳轉(zhuǎn)到絕對(duì)地址PC=0x00000000處執(zhí)行;●禁止IRQ中斷和FIQ中斷。第7章ARM異常中斷處理及編程

1.復(fù)位異常8第7章ARM異常中斷處理及編程

復(fù)位后,程序狀態(tài)寄存器如下:......IFTM4M3M2M1M0

11010011上電復(fù)位后,進(jìn)入管理模式,執(zhí)行操作系統(tǒng)程序,一般用做對(duì)系統(tǒng)初始化,例如開(kāi)中斷等;然后切換到用戶模式,開(kāi)始執(zhí)行正常的用戶程序。第7章ARM異常中斷處理及編程復(fù)位后,程序狀態(tài)寄存器如下9第7章ARM異常中斷處理及編程

切換到用戶模式可使用下列程序:

MRSR0,CPSR

;讀狀態(tài)寄存器

BICR0,R0,#03

;把末兩位清0MSRCPRS_c,R0

;把修改后的值加載給;狀態(tài)寄存器,切換結(jié)束

......

;用戶程序第7章ARM異常中斷處理及編程

切換到用戶模式可使用下列10第7章ARM異常中斷處理及編程

2.未定義指令異常

ARM的未定義指令異常有以下兩種情況:(1)遇到一條沒(méi)有定義指令;(2)執(zhí)行一條對(duì)協(xié)處理器的操作指令沒(méi)有應(yīng)答。

未定義異常中斷時(shí),狀態(tài)寄存器中的F位不變。使用下列指令退出異常中斷,返回原程序?!癜严乱粭l指令的地址拷貝給LR;●把程序狀態(tài)寄存器CPSR拷貝給SPSR_und;●強(qiáng)制進(jìn)入未定義模式;●強(qiáng)制進(jìn)入到ARM模式;●跳轉(zhuǎn)到絕對(duì)地址PC=0x00000004處執(zhí)行;●禁止IRQ中斷。第7章ARM異常中斷處理及編程

2.未定義指令異常11第7章ARM異常中斷處理及編程

進(jìn)入中斷后,程序狀態(tài)寄存器如下:......IFTM4M3M2M1M0

1x011011

未定義異常中斷返回時(shí),使用下列指令返回到原中斷處:MOVSPC,R14. 第7章ARM異常中斷處理及編程

進(jìn)入中斷后,程序狀態(tài)寄12第7章ARM異常中斷處理及編程

3.軟件中斷異常

是由指令SWI引起的。程序在執(zhí)行這一指令后,進(jìn)入異常中斷。處理器響應(yīng)中斷,硬件執(zhí)行如下的操作:●把下一條指令的地址拷貝給LR;●把程序狀態(tài)寄存器CPSR拷貝給SPSR_svc;●強(qiáng)制進(jìn)入管理模式;●強(qiáng)制進(jìn)入到ARM狀態(tài);●跳轉(zhuǎn)到絕對(duì)地址PC=0x00000008處執(zhí)行;●禁止IRQ中斷。第7章ARM異常中斷處理及編程

3.軟件中斷異常13第7章ARM異常中斷處理及編程

進(jìn)入中斷后的程序狀態(tài)寄存器如下:......IFTM4M3M2M1M0

1x010011軟件中斷處理程序完成后,使用下列指令返回到原中斷處:MOVSPC,R14第7章ARM異常中斷處理及編程

進(jìn)入中斷后的程序狀態(tài)寄存14第7章ARM異常中斷處理及編程

4.預(yù)取指中止異常程序存儲(chǔ)器引起的中止異常叫做預(yù)取指中止異常;數(shù)據(jù)存儲(chǔ)器引起的中止異常叫做數(shù)據(jù)中止異常。

有兩種可能如下:

●當(dāng)執(zhí)行這條指令前程序發(fā)生跳轉(zhuǎn),則這條無(wú)效指令不引起異常中斷;●當(dāng)執(zhí)行到這條指令時(shí),處理器會(huì)發(fā)生預(yù)取指中止異常,引起中斷。第7章ARM異常中斷處理及編程

4.預(yù)取指中止異常15第7章ARM異常中斷處理及編程

當(dāng)進(jìn)入預(yù)取指異常中斷時(shí),處理器硬件響應(yīng)中斷,執(zhí)行以下的操作:●把中斷時(shí)PC的地址拷貝給LR;●把程序狀態(tài)寄存器CPSR拷貝給SPSR_abt;●強(qiáng)制進(jìn)入中止異常模式;●強(qiáng)制進(jìn)入到ARM狀態(tài);●跳轉(zhuǎn)到絕對(duì)地址PC=0x0000000C處執(zhí)行;●禁止IRQ中斷。第7章ARM異常中斷處理及編程當(dāng)進(jìn)入預(yù)取指異常中斷時(shí),處16第7章ARM異常中斷處理及編程

進(jìn)入中斷后,程序狀態(tài)寄存器如下:......IFTM4M3M2M1M0

1x010111預(yù)取指中止異常中斷返回時(shí),應(yīng)該執(zhí)行下列指令:SUBSPC,R14,#4.第7章ARM異常中斷處理及編程進(jìn)入中斷后,程序狀態(tài)寄存器17第7章ARM異常中斷處理及編程

5.?dāng)?shù)據(jù)中止異常ARM處理器訪問(wèn)數(shù)據(jù)存儲(chǔ)器時(shí),在讀取數(shù)據(jù)的同時(shí)數(shù)據(jù)存儲(chǔ)器發(fā)出了中止信號(hào),引起數(shù)據(jù)中止異常。數(shù)據(jù)中止異常中斷服務(wù)程序返回時(shí),用下列指令:

SUBSPC,R14,#8

上述指令是返回到中斷時(shí)所執(zhí)行的指令,目的是再一次從數(shù)據(jù)存儲(chǔ)器中讀取數(shù)據(jù)。如果不再一次讀取數(shù)據(jù),則執(zhí)行下一條指令,此時(shí)使用下列指令返回:

SUBSPC,R14,#4第7章ARM異常中斷處理及編程5.?dāng)?shù)據(jù)中止異常18第7章ARM異常中斷處理及編程

當(dāng)進(jìn)入數(shù)據(jù)中止異常中斷時(shí),處理器硬件響應(yīng)中斷,執(zhí)行以下的操作:●把中斷時(shí)的PC的地址拷貝給LR;●把程序狀態(tài)寄存器CPSR拷貝給SPSR_abt;●強(qiáng)制進(jìn)入中止異常模式;●強(qiáng)制進(jìn)入到ARM狀態(tài);●跳轉(zhuǎn)到絕對(duì)地址PC=0x00000010處執(zhí)行;●禁止IRQ中斷。第7章ARM異常中斷處理及編程當(dāng)進(jìn)入數(shù)據(jù)中止異常中斷19第7章ARM異常中斷處理及編程

進(jìn)入中斷后,程序狀態(tài)寄存器如下:......IFTM4M3M2M1M0

1x010111第7章ARM異常中斷處理及編程

進(jìn)入中斷后,程序狀態(tài)寄20第7章ARM異常中斷處理及編程

6.中斷請(qǐng)求(IRQ)異常當(dāng)I=1時(shí)。則屏蔽IRQ中斷,當(dāng)I=0時(shí),則允許中斷。處理器復(fù)位后置I為1,關(guān)閉中斷。ARM系統(tǒng)中外設(shè)通過(guò)該異常中斷請(qǐng)求處理服務(wù)。

例如:定時(shí)器中斷、串行口通訊中斷、外部信號(hào)中斷和A/D處理中斷等。IRQ中斷是可屏蔽的。在狀態(tài)寄存器中的I位就是IRQ的屏蔽位。第7章ARM異常中斷處理及編程6.中斷請(qǐng)求(IRQ)異常21第7章ARM異常中斷處理及編程

當(dāng)發(fā)生IRQ中斷時(shí),處理器硬件響應(yīng)中斷,執(zhí)行下列操作:

●把中斷時(shí)的PC的地址值拷貝給LR;●把程序狀態(tài)寄存器CPSR拷貝給SPSR_irq;●強(qiáng)制進(jìn)入IRQ異常模式;●強(qiáng)制進(jìn)入到ARM狀態(tài);●跳轉(zhuǎn)到絕對(duì)地址PC=0x00000018處執(zhí)行;●禁止IRQ中斷。第7章ARM異常中斷處理及編程當(dāng)發(fā)生IRQ中斷時(shí),22第7章ARM異常中斷處理及編程

進(jìn)入中斷后,程序狀態(tài)寄存器如下:......IFTM4M3M2M1M0

1x010010

完成中斷處理后,程序執(zhí)行下列返回原中斷處:SUBSPC.R14,#4.第7章ARM異常中斷處理及編程進(jìn)入中斷后,程序狀態(tài)寄存器23第7章ARM異常中斷處理及編程

7.2.2支持中斷跳轉(zhuǎn)的解析程序(1)解析程序的概念和作用中斷解析程序是為了使得上層應(yīng)用程序與硬件中斷跳轉(zhuǎn)聯(lián)系起來(lái)所編寫(xiě)一段中間的服務(wù)程序。中斷跳轉(zhuǎn)流程圖如圖7.1所示。第7章ARM異常中斷處理及編程7.2.2支持中斷跳轉(zhuǎn)的24第7章ARM異常中斷處理及編程

(2)解析過(guò)程以一次IRQ跳轉(zhuǎn)為例說(shuō)明解析過(guò)程,假定中斷向量表定義在0x00400000開(kāi)始的外部RAM空間,中斷解析示例流程如圖7.2所示。圖中實(shí)線表示的流程都用ARM匯編語(yǔ)言編寫(xiě),一般作為boot代碼的一部分放在系統(tǒng)的底層模塊中。填寫(xiě)向量表的操作可以在上層應(yīng)用程序中方便地實(shí)現(xiàn),比如在C語(yǔ)言中:*(int*(0x00400018))=(int)ISR_IRQ;這樣就將IRQ中斷的服務(wù)程序入口地址(0x00300260)填寫(xiě)到中斷向量表中的固定地址0x00400018開(kāi)始的4字節(jié)空間了。這樣就可避免在應(yīng)用程序中計(jì)算中斷的跳轉(zhuǎn)地址,并可很方便的選擇不同的函數(shù)作為指定中斷的服務(wù)程序。當(dāng)然,在程序開(kāi)發(fā)時(shí)要合理開(kāi)辟好向量表,避免對(duì)向量表地址空間不必要的寫(xiě)操作。第7章ARM異常中斷處理及編程(2)解析過(guò)程25第7章ARM異常中斷處理及編程

第7章ARM異常中斷處理及編程26第7章ARM異常中斷處理及編程

(3)解析程序的擴(kuò)展

在ARM處理器中會(huì)包含很多中斷源,通常會(huì)在ARM內(nèi)核外面擴(kuò)展一個(gè)中斷控制器來(lái)管理各種原因產(chǎn)生的中斷。如,三星公司的S3C4510B處理器中的IRQ/FIQ類(lèi)型的中斷源可以有21個(gè)S3C44B0X有26個(gè)。解析程序的擴(kuò)展處理流程可用圖7.3表示。7.3中斷解析的擴(kuò)展處理流程第7章ARM異常中斷處理及編程(3)解析程序的擴(kuò)展7.327第7章ARM異常中斷處理及編程

7.3中斷解析的擴(kuò)展處理流程第7章ARM異常中斷處理及編程7.3中斷解析的擴(kuò)展處理28第7章ARM異常中斷處理及編程

(4)向量中斷的處理在設(shè)計(jì)外部擴(kuò)展的中斷控制器時(shí)提供了一種叫做“向量中斷”的中斷跳轉(zhuǎn)機(jī)制。與前面敘述的擴(kuò)展解析跳轉(zhuǎn)流程有所不同,它不需要軟件來(lái)識(shí)別具體的中斷源,也就是不需要添加圖7.3中的IRQ/FIQ服務(wù)程序,而完全由硬件自動(dòng)跳轉(zhuǎn)到對(duì)應(yīng)的中斷地址。其它跳轉(zhuǎn)流程的原理都是一樣的。這相當(dāng)于擴(kuò)展了ARM內(nèi)核的硬件中斷向量表,減小了中斷響應(yīng)延時(shí)。以S3C2410X處理器的外部中斷0為例,需要在其對(duì)應(yīng)的硬件固定跳轉(zhuǎn)地址0x00000020處添加指令:ldrpc,=HandlerEINT,使得程序跳轉(zhuǎn)到其服務(wù)程序HandlerEINT0處執(zhí)行。向量中斷的處理如圖7.4所示。第7章ARM異常中斷處理及編程(4)向量中斷的處理29第7章ARM異常中斷處理及編程

圖7.4向量中斷的處理第7章ARM異常中斷處理及編程圖7.4向量中斷的處理30第7章ARM異常中斷處理及編程

7.3中斷解析的擴(kuò)展處理流程7.3ARM應(yīng)用系統(tǒng)中異常中斷處理程序的安裝在ARM應(yīng)用程序中安裝異常中斷處理程序通常有下列兩種方法?!袷褂锰D(zhuǎn)指令:可以在異常中斷對(duì)應(yīng)異常向量表中特定位置放置一條跳轉(zhuǎn)指令,直接跳轉(zhuǎn)到該異常中斷的處理程序。但只能在32M空間范圍內(nèi)跳轉(zhuǎn)?!袷褂脭?shù)據(jù)讀取指令LDR:使用數(shù)據(jù)讀取指令LDR向程序計(jì)數(shù)器PC中直接賦值。這種方法分為兩步:先將異常中斷處理程序的絕對(duì)地址存放在距離向量表4KB范圍內(nèi)的一個(gè)存儲(chǔ)單元中;再使用數(shù)據(jù)讀取指令LDR將該單元的內(nèi)容讀取到程序計(jì)數(shù)器PC中。第7章ARM異常中斷處理及編程7.3中斷解析的擴(kuò)展處理31第7章ARM異常中斷處理及編程

7.3中斷解析的擴(kuò)展處理流程7.3.1在系統(tǒng)復(fù)位時(shí)安裝異常中斷處理程序

1.地址0x00處為ROM的情況

當(dāng)?shù)刂?x0處為ROM時(shí):在異常中斷向量表中,可以使用數(shù)據(jù)讀取指令LDR直接向程序計(jì)數(shù)器PC中賦值,也可以直接使用跳轉(zhuǎn)指令跳轉(zhuǎn)到異常中斷處理程序。第7章ARM異常中斷處理及編程7.3中斷解析的擴(kuò)展處理32第7章ARM異常中斷處理及編程

使用數(shù)據(jù)讀取指令LDR的示例如下所示:Vector_Init_BlockLDRPC,Reset_AddrLDRPC,Undefined_AddrLDRPC,SW_AddrLDRPC,Prefeth_AddrLDRPC,Abort_AddrNOPLDRPC,IRQ_AddrLDRPC,F(xiàn)IQ_AddrReset_Addr

DCDStart_Boot第7章ARM異常中斷處理及編程使用數(shù)據(jù)讀取指令LDR的示33第7章ARM異常中斷處理及編程

Undefined_AddrDCDUndefined_HandleSW_Addr

DCDSWI_HandlePrefeth_Addr

DCDPrefeth_HandleAbort_AddrDCDAbort_HandleDCD0IRQ_Addr

DCDIRQ_HandleFIQ_Addr

DCDFIQ_Handle第7章ARM異常中斷處理及編程Undefined_Add34第7章ARM異常中斷處理及編程

使用跳轉(zhuǎn)指令的示例如下所示:Vector_Init_BlockBLReset_HandleBLUndefined_HandleBLSWI_HandleBLPrefeth_HandleBLAbort_HandleNOPBLIRQ_HandleBLFIQ_Handle第7章ARM異常中斷處理及編程使用跳轉(zhuǎn)指令的示例如下所示35第7章ARM異常中斷處理及編程

2.地址0x00處為RAM的情況

當(dāng)?shù)刂?x0處為RAM時(shí),中斷向量表必須使用數(shù)據(jù)讀取指令直接指向PC中賦值的形式。而且,必須使用下面的代碼把中斷向量表從ROM中復(fù)制到RAM的地址0x00開(kāi)始處的存儲(chǔ)空間中。中斷向量表從ROM中復(fù)制到RAM的代碼段如下:MOVr8,#0ADRr9,Vector_Init_Block;復(fù)制中斷向量表(8字)LDMIAr9!,{r0-r7}STMIAr8!,{r0-r7};復(fù)制保存各中斷處理函數(shù)地址的表(8words)LDMIAr9!,{r0-r7}STMIAr8!,{r0-r7}第7章ARM異常中斷處理及編程2.地址0x00處為RA36第7章ARM異常中斷處理及編程

7.3.2在C程序中安裝異常中斷處理程序安裝異常中斷處理程序的方法。1.中斷向量表中使用跳轉(zhuǎn)指令的情況當(dāng)中斷向量表中使用跳轉(zhuǎn)指令時(shí),在C程序中安裝異常中斷處理程序的操作如下:(1)讀取中斷處理程序的地址。(2)從上一步得到的地址中減去該異常中斷對(duì)應(yīng)的中斷向量的地址。(3)從上一步得到的地址中減去8,以允許指令預(yù)取。(4)將上一步得到的地址右移 2位,得到以字(32位)為單位的偏移量。(5)確保上一步得到的地址值高8位為0,因?yàn)樘D(zhuǎn)指令只允許24位的偏移量。(6)將上一步得到的地址與數(shù)據(jù)0xea000000作邏輯或,從而得到將要寫(xiě)到中斷向量表中的跳轉(zhuǎn)指令的編碼。第7章ARM異常中斷處理及編程7.3.2在C程序中安裝37第7章ARM異常中斷處理及編程

例7.1使用跳轉(zhuǎn)指令的中斷向量表unsignedInstall_Handler(unsignedroutine,unsigned*vector)/*在中斷向量表中vector處,添上合適的跳轉(zhuǎn)指令*//*該跳轉(zhuǎn)指令跳轉(zhuǎn)到中斷處理程序routine處。*//*程序返回原來(lái)的中斷向量*/{unsignedvec,oldvec;vec=((routine–(unsigned)vector–0x8)>>2);if(vec&oxff000000){printf(“InstallationofHandlerfailed“);exit(1);}vec=oxea000000|vec;oldvec=*vector;*vector=vec;return(oldvec);}第7章ARM異常中斷處理及編程例7.1使用跳轉(zhuǎn)指令的中38第7章ARM異常中斷處理及編程

2.中斷向量表中使用數(shù)據(jù)讀取指令的情況當(dāng)中斷向量表中使用數(shù)據(jù)讀取指令時(shí),在C程序中安裝異常中斷處理程序的操作過(guò)程如下:(1)讀取中斷處理程序的地址。(2)從上一步得到的地址中減去該異常中斷對(duì)應(yīng)的中斷向量的地址。(3)從上一步得到地址中減去8,以允許指令預(yù)取。(4)將上一步得到地址與數(shù)據(jù)0xe59ff000作邏輯或,從而得到將要寫(xiě)到中斷向量表中的數(shù)據(jù)讀取指令的編碼。(5)將中斷處理程序的地址放到相應(yīng)的存儲(chǔ)單元。第7章ARM異常中斷處理及編程2.中斷向量表中使用39第7章ARM異常中斷處理及編程

例7.2使用數(shù)據(jù)讀取指令的中斷向量表unsignedInstall_Handler(unsignedlocation,unsigned*vector)/*在中斷向量表中vector處,添上合適的指令LDRpc,[pc,#offset]*//*該指令跳轉(zhuǎn)的目標(biāo)地址存放在存儲(chǔ)單元‘location’中*//*函數(shù)返回原來(lái)的中斷向量*/{unsignedvec,oldvec;vec=((unsigned)location–(unsigned)vector–0x8)|0xe59ff000;oldvec=*vector;*vector=vec;return(oldvec);}第7章ARM異常中斷處理及編程例7.2使用數(shù)據(jù)讀取指令40第7章ARM異常中斷處理及編程

用下面的語(yǔ)句調(diào)用例7.2的函數(shù),實(shí)現(xiàn)用C語(yǔ)言程序完成中斷處理程序的安裝。unsigned*irqvec=(unsigned*)0x18;Install_Handler((unsigned)IRQHandler,irqvec);第7章ARM異常中斷處理及編程用下面的語(yǔ)句調(diào)41第7章ARM異常中斷處理及編程

7.4ARM的SWI異常中斷處理程序設(shè)計(jì)

通過(guò)SWI異常中斷指令,用戶模式下應(yīng)用程序可以調(diào)用系統(tǒng)模式下的代碼。在實(shí)時(shí)操作系統(tǒng)中,通常使用SWI異常中斷為用戶應(yīng)用程序提供系統(tǒng)功能調(diào)用。7.4.1SWI異常中斷處理程序的實(shí)現(xiàn)在SWI指令中包括一個(gè)24位的立即數(shù)(中斷調(diào)用號(hào)),該立即數(shù)指示了用戶要請(qǐng)求的特定的調(diào)用功能,所以在SWI的異常中斷中要讀取這個(gè)中斷調(diào)用號(hào),然后根據(jù)中斷號(hào),來(lái)調(diào)用相應(yīng)的處理程序。這個(gè)過(guò)程可以分兩步:第1步是SWI中斷處理程序?yàn)閰R編,用于確定SWI指令中的24位的立即數(shù);第2步是SWI異常中斷處理的功能服務(wù)程序,是具體實(shí)現(xiàn)SWI的各個(gè)功能,它即可用匯編語(yǔ)言,也可用C語(yǔ)言編程。第7章ARM異常中斷處理及編程7.4ARM的SWI異42第7章ARM異常中斷處理及編程

1.第1步用匯編語(yǔ)言編寫(xiě)的SWI異常中斷處理程序

由于是在底層操作,所以這個(gè)異常中斷處理程序得用匯編語(yǔ)言編寫(xiě),例7.3所示的SWI異常中斷處理程序中的blswi_service_func指令是調(diào)用第2步的SWI異常中斷處理的功能服務(wù)程序,此函數(shù)是用于實(shí)現(xiàn)SWI的各個(gè)功能。第7章ARM異常中斷處理及編程1.第1步用匯編語(yǔ)言編寫(xiě)43第7章ARM異常中斷處理及編程

例7.3匯編語(yǔ)言編寫(xiě)的第1步SWI異常中斷處理程序areatop_swicodereadonlyexportswi_headlerswi_headlerstmfdsp!,{r0-r12,lr}

;保存r0至r12,lr的寄存器值ldrr0,[lr,#-4]

;從存儲(chǔ)器中取得SWI指令的所在地址bicr0,r0,#FF000000

;讀取24位中斷調(diào)用號(hào)movr1,sp;=============================blswi_service_func

;調(diào)用功能服務(wù)函數(shù),見(jiàn)下面

;中斷調(diào)用號(hào)通過(guò)r0寄存器傳入

;參數(shù)通過(guò)r1寄存器傳入;==============================ldmfdsp!,{r0-r12,pc}^

;恢復(fù)調(diào)用前r0至r12,退出end第7章ARM異常中斷處理及編程例7.3匯編語(yǔ)言編寫(xiě)的44第7章ARM異常中斷處理及編程

2.SWI異常中斷處理的中斷服務(wù)程序

為了具體實(shí)現(xiàn)SWI的各個(gè)功能,需編寫(xiě)SWI異常中斷處理的功能服務(wù)程序,它即可用匯編語(yǔ)言,也可用C語(yǔ)言編程。例7.4是用匯編語(yǔ)言編寫(xiě)的SWI異常中斷處理的中斷服務(wù)程序,例7.5是用C語(yǔ)言編寫(xiě)的SWI異常中斷處理的中斷服務(wù)程序。第7章ARM異常中斷處理及編程2.SWI異常中斷處理的45第7章ARM異常中斷處理及編程

例7.4匯編語(yǔ)言編寫(xiě)的SWI異常中斷處理程序areatoplevelswicodereadonlyexportswi_headlerswi_headlerstmfdsp!,{r0-r12,lr};保存r0至r12,lr的寄存器值ldrr0,[lr,#-4]

;從存儲(chǔ)器中取得SWI指令的所在地址bicr0,r0,#FF000000

;讀取24位中斷調(diào)用號(hào)movr1,sp;判斷立即數(shù)是否有效cmpR0,#MaxOfSWI;判R0中數(shù)是否有效超過(guò)允許的最大值ldrlspc,[pc,r0,lsl#2]bOutOfSWIRange;超出范圍JumpListofSWI;SWI的跳轉(zhuǎn)表dcdSWIPro_0;SWI對(duì)應(yīng)立即數(shù)0的中斷處理程序入口地址dcdSWIPro_1;SWI對(duì)應(yīng)立即數(shù)1的中斷處理程序入口地址第7章ARM異常中斷處理及編程例7.4匯編語(yǔ)言編寫(xiě)的S46第7章ARM異常中斷處理及編程

;其他所有的軟中斷入口SWIPro_0;進(jìn)入SWI對(duì)應(yīng)立即數(shù)0的中斷處理程序;對(duì)應(yīng)立即數(shù)0的中斷處理程序bEndOfSWISWIPro1;進(jìn)入SWI對(duì)應(yīng)立即數(shù)1的中斷處理程序;對(duì)應(yīng)立即數(shù)1的中斷處理程序bEndOfSWI;其他的SWI處理程序EndOfSWI;結(jié)束SWI中斷處理程序ldmfdsp!,{r0-r12,pc}^

;恢復(fù)調(diào)用前的r0至r12,退出中斷程序end第7章ARM異常中斷處理及編程47第7章ARM異常中斷處理及編程

例7.5用C語(yǔ)言編寫(xiě)的第2步SWI異常中斷處理的中斷服務(wù)程序

用C語(yǔ)言編寫(xiě)的第2步SWI異常中斷處理的中斷服務(wù)程序的函數(shù)原形如下:voidswi_service_func(unsignedintnumber,unsignedint*reg)

其中:參數(shù)number是SWI的中斷調(diào)用號(hào),是利用從中斷處理函數(shù)獲得的中斷調(diào)用號(hào);參數(shù)reg是SWI異常中斷第1步(例7.3)中斷處理程序傳遞來(lái)的數(shù)據(jù)棧指針。在第1步的SWI異常中斷處理程序調(diào)用第2步中斷處理程序的操作如下所示:

設(shè)置C程序?qū)⑹褂玫牡诙€(gè)參數(shù),根據(jù)ATPCS第個(gè)參數(shù)保存在寄存器R1中第7章ARM異常中斷處理及編程例7.5用C語(yǔ)言編寫(xiě)的第48第7章ARM異常中斷處理及編程

movr1,spblswi_service_func

;調(diào)用功能服務(wù)函數(shù),見(jiàn)下面

;中斷調(diào)用號(hào)通過(guò)r0寄存器傳入

;參數(shù)通過(guò)r1寄存器傳入第2步SWI異常中斷處理的中斷服務(wù)程序代碼如下:voidswi_service_func(unsignedintnumber,unsignedint*reg){

unsignedintreg1,reg2,reg3,reg4;

//獲取SWI前傳入的參數(shù)

reg1=reg[0];

reg2=reg[1];

reg3=reg[2];

reg4=reg[3];

第7章ARM異常中斷處理及編程movr1,spbl49第7章ARM異常中斷處理及編程

switch(number){

case0:

//dosomething

break;

case1:

//dosomething

break;

casen:

//dosomething

break;

default:

//dosomething

}

}

第7章ARM異常中斷處理及編程

switch(n50第7章ARM異常中斷處理及編程

//更新結(jié)果存入r0-r3

reg[0]=updata_reg1;

reg[1]=updata_reg2;

reg[2]=updata_reg3;

reg[3]=updata_reg4;}第7章ARM異常中斷處理及編程

//更新結(jié)果存入51第7章ARM異常中斷處理及編程

7.4.2SWI異常中斷調(diào)用

1.在特權(quán)模式下調(diào)用SWI執(zhí)行SWI指令后,系統(tǒng)將會(huì)把CPSR寄存器的內(nèi)容保存到寄存器SPSR_svc中,將返回地址保存到寄存器LR_svc中。這樣如果在執(zhí)行SWI指令時(shí),系統(tǒng)已經(jīng)處于特權(quán)模式下,這時(shí)寄存器SPSR_svc和寄存器LR_svc中的內(nèi)容就會(huì)被破壞。因此如果在特權(quán)模式下調(diào)用SWI功能(即執(zhí)行SWI指令),比如在一個(gè)SWI異常中斷處理程序中執(zhí)行SWI指令,就必須將原始的寄存器SPSR_svc和寄存器LR_svc值保存在數(shù)據(jù)棧中。第7章ARM異常中斷處理及編程7.4.2SWI異常中52第7章ARM異常中斷處理及編程

例如7.6在SWI中斷程序處理程序中保存寄存器SPSR_svc和寄存器LR_svc值areatop_swicodereadonlyexportswi_headlerswi_headlerstmfdsp!,{r0-r3,12,lr}

;保存r0至r3,r12,lr的寄存器值;保存SPSR_svcmovr1,spMRSr0,spsrstmfdsp!,{r0}

;讀取SWI指令ldrr0,[lr,#-4]

;從存儲(chǔ)器中取得SWI指令的所在地址bicr0,r0,#FF000000

;讀取24位中斷調(diào)用號(hào),并存入寄存器r0中第7章ARM異常中斷處理及編程例如7.6在SWI中斷53第7章ARM異常中斷處理及編程

;========================blswi_service_func

;調(diào)用功能服務(wù)函數(shù),;見(jiàn)下面中斷調(diào)用號(hào)通過(guò)r0寄存器;傳入?yún)?shù)通過(guò)r1寄存器傳入;==========================ldmfdsp!,{r0}

;恢復(fù)調(diào)用前的r0MSRspsr_cf,r0ldmfdsp!,{r0-r3,r12,pc}^

;恢復(fù)調(diào)用前的r0至r12,離開(kāi)中斷處理程序end第7章ARM異常中斷處理及編程;============54第7章ARM異常中斷處理及編程

2.從應(yīng)用程序中調(diào)用SWI

可分兩種情況從應(yīng)用程序中調(diào)用特定的SWI功能:其一是使用匯編指令調(diào)用;其二是用C程序調(diào)用。匯編指令調(diào)用特定的SWI功能只要將所需要的參數(shù)按ATPCS的要求放置在相應(yīng)的寄存器中,然后在指令SWI中指定相應(yīng)24位立即數(shù)(即待調(diào)用的SWI功能號(hào))即可。第7章ARM異常中斷處理及編程2.從應(yīng)用程序中調(diào)用SW55第7章ARM異常中斷處理及編程

例如7.7

下面的例子是用匯編指令實(shí)現(xiàn)SWI的調(diào)用。SWI中斷處理程序所需的參數(shù)放在寄存器R0中,然后調(diào)用功能號(hào)為0x0的SWI功能調(diào)用。MOVR0,#100SWI0x0第7章ARM異常中斷處理及編程例如7.756第7章ARM異常中斷處理及編程

例如7.8

下面是ARM公司的ADS1.2中自帶的一個(gè)完整的用C語(yǔ)言程序調(diào)用特定的SWI功能的例子,例子中提供了4個(gè)SWI功能調(diào)用,功能號(hào)分別為0x0、0x1、0x2和0x3。其中SWI0x0和SWI0x1使用兩個(gè)整型的輸入?yún)?shù),并返回一個(gè)結(jié)果值;SWI0x2使用4個(gè)輸入?yún)?shù),并返回一個(gè)結(jié)果值;SWI0x3使用4個(gè)輸入?yún)?shù),并返回4個(gè)結(jié)果值。第7章ARM異常中斷處理及編程例如7.857第7章ARM異常中斷處理及編程

從C程序中調(diào)用特定的SWI功能程序代碼如下:/*頭文件—swi.h*/__swi(0)intmultiply_two(int,int);__swi(1)intadd_two(int,int);__swi(2)intadd_multiply_two(int,int,int,int);structfour_results{inta;intb;intc;intd;};__swi(3)__value_in_regsstructfour_resultsmany_operations(int,int,int,int);第7章ARM異常中斷處理及編程從C程序中調(diào)用特定的SW58第7章ARM異常中斷處理及編程

/*主程序——main()*/#include<stdio.h>#include“swi.h”unsigned*swi_vec=(unsigned*)0x08;externvoidSWI_Handler(void);/*使用Install_Handler()安裝SWI異常中斷處理程序*/unsignedInstall_Handler(unsignedroutine,unsigned*vector){unsignedvec,old_vec;vec=(routine–(unsigned)vector-8)>>2;if(vec&0xff000000){printf(“Handlergreaterthan32Mbytesfromvector“);}第7章ARM異常中斷處理及編程/*主程序——main59第7章ARM異常中斷處理及編程

vec=0xea000000|vec;old_vec=*vector;*vector=vec;return(old_vec);}intmain(void){intresult1,result2;structfour_resultsres_3;Install_Handler((unsigned)SWI_Handler,swi_vec);printf(“result1=multiply_two(2,4)=%d\n”,result1=multiply_two(2,4));printf(“result2=multiply_two(3,6)=%d\n”,第7章ARM異常中斷處理及編程vec=0xea00060第7章ARM異常中斷處理及編程

result2=multiply_two(3,6));printf(“add_two(result1,result2)=%d\n”,add_two(result1,result2));printf(“add_multiply_two(2,4,3,6)=%d\n”,add_multiply_two(2,4,3,6));res_3=many_operations(12,4,3,1);printf(“res_3.a=%d\n”,res_3.a);printf(“res_3.b=%d\n”,res_3.b);printf(“res_3.c=%d\n”,res_3.c);printf(“res_3.d=%d\n”,res_3.d);return0;}第7章ARM異常中斷處理及編程result2=multi61第7章ARM異常中斷處理及編程

;第1步SWI異常中斷處理程序SWI_HandlerAREASWI_Area,CODE,READONLYEXPORTC_SWI_HandlerT_bitEQU0x20SWI_HandlerSTMFDsp!,{r0-r3,r12,lr}MOVr1,spMRSr0,spsrSTMFDsp!,{r0}TSTr0,#T_bitLDRNEHr0,[lr,#-2]BICENr0,r0,#0xff00LDREQr0,[lr,#-4]第7章ARM異常中斷處理及編程;第1步SWI異常中斷處理62第7章ARM異常中斷處理及編程

BICEQr0,r0,#0xff000000BLC_SWI_HandlerLDMFDsp!,{r0}MSRspsr_cf,r0LDMFDsp!,{r0,r3,r12,pc}^END;第2步SWI異常中斷處理程序voidC_SWI_Handler()voidC_SWI_Handler(){switch(swi_num){

第7章ARM異常中斷處理及編程BICEQr0,63第7章ARM異常中斷處理及編程

case0;//對(duì)應(yīng)于SWI0x0regs[0]=regs[0]*regs[1];break;case1;//對(duì)應(yīng)于SWI0x1regs[0]=regs[0]+regs[1];break;case2;//對(duì)應(yīng)于SWI0x2regs[0]=(regs[0]*regs[1])+(regs[2]*regs[3]);break;case3;//對(duì)應(yīng)于SWI0x3{intw,x,y,z;第7章ARM異常中斷處理及編程case0;//對(duì)64第7章ARM異常中斷處理及編程

w=regs[0];x=regs[1];y=regs[2];z=regs[3];regs[0]=w+x+y+z;regs[1]=w-x-y-z;regs[2]=w*x*y*z;regs[3]=(w+x)*(y–z);}break

;}}第7章ARM異常中斷處理及編程w=regs[0];65第7章ARM異常中斷處理及編程

3.從應(yīng)用程序中動(dòng)態(tài)調(diào)用SWI動(dòng)態(tài)調(diào)用SWI是指在應(yīng)用程序的運(yùn)行時(shí)調(diào)用SWI的功能號(hào)。有兩種方法實(shí)現(xiàn)動(dòng)態(tài)調(diào)用SWI功能號(hào)。方法1:在運(yùn)行時(shí)得到SWI功能號(hào),然后構(gòu)造出相應(yīng)的SWI指令的編碼,把這個(gè)指令的編碼保存在某個(gè)存儲(chǔ)單元中,執(zhí)行該指令即可。方法2:用一個(gè)通用的SWI異常中斷處理程序,將運(yùn)行時(shí)需要調(diào)用的SWI功能號(hào)作為參數(shù)傳遞給該通用的SWI異常中斷處理程序。通用的SWI異常中斷處理程序根據(jù)參數(shù)值調(diào)用相應(yīng)的SWI處理程序完成需要操作。第7章ARM異常中斷處理及編程3.從應(yīng)用程序中動(dòng)態(tài)調(diào)用66第7章ARM異常中斷處理及編程

在匯編程序中常用第2種方法。在執(zhí)行SWI指令之前先將需要調(diào)用的SWI功能號(hào)放在某個(gè)寄存器(R0~R12都可以使用),在通用的SWI異常中斷程序讀取該寄存器值,決定需要執(zhí)行的操作,但有些SWI處理程序需要SWI指令中的24位立即數(shù),因而上述兩種方法常常組合使用。在操作系統(tǒng)中通常使用一個(gè)SWI功能號(hào)和一個(gè)寄存器來(lái)提供很多的SWI功能調(diào)用,這樣可以將其他的SWI功能號(hào)留給用戶使用。第7章ARM異常中斷處理及編程在匯編程序中常用第2種67第7章ARM異常中斷處理及編程

例7.9在ARM體系中semihost的實(shí)現(xiàn)的一個(gè)實(shí)例,ARM程序使用SWI0x123456來(lái)實(shí)現(xiàn)semihost功能調(diào)用;Thumb程序使用SWI0xAB來(lái)實(shí)現(xiàn)semihost功能調(diào)用。此例中將子程序WRITEC(unsignedop,char*c)映射到somehost功能調(diào)用,具體semihostSWI的子功能號(hào)通過(guò)參數(shù)op傳遞。第7章ARM異常中斷處理及編程例7.968第7章ARM異常中斷處理及編程

7.5FIG和IRQ異常中斷程序設(shè)計(jì)IRQ和FIQ是ARM處理器的兩種編程模式。IRQ是指中斷模式,F(xiàn)IR是指快速中斷模式。IRQ可以被FIQ所中斷,但I(xiàn)RQ不能中斷FIQ。為了使FIQ更快,所以這種模式有更多的影子寄存器。FIQ不能調(diào)用SWI(軟件中斷)。FIQ還必須禁用中斷。如果一個(gè)FIQ例程必須重新啟用中斷,則它太慢了,并應(yīng)該是IRQ而不是FIQ。設(shè)置IRQ/FIQ中斷,若是IRQ中斷則可以設(shè)置為向量中斷并分配中斷優(yōu)先級(jí),否則為非向量IRQ。然后可以設(shè)置中斷允許,以及向量中斷對(duì)應(yīng)地址或非向量中斷默認(rèn)地址。當(dāng)有中斷后,若是IRQ中斷,則可以讀取向量地址寄存器,然后跳轉(zhuǎn)到相應(yīng)的代碼。當(dāng)要退出中斷時(shí),對(duì)向量地址寄存器寫(xiě)0,通知VIC(中斷向量控制器)中斷結(jié)束。當(dāng)發(fā)生中斷時(shí),處理器將會(huì)切換處理器模式,同時(shí)相關(guān)的寄存器也將會(huì)映射。第7章ARM異常中斷處理及編程7.5FIG和IRQ異常69第7章ARM異常中斷處理及編程

IRQ(外部中斷請(qǐng)求):當(dāng)處理器的外部中斷請(qǐng)求引腳有效,且CPSR中的I位為0時(shí),產(chǎn)生IRQ異常。系統(tǒng)的外設(shè)可以該異常請(qǐng)求中斷服務(wù)(異常向量:0x0000,0018);FIQ(快速中斷請(qǐng)求):當(dāng)處理器的快速中斷請(qǐng)求引腳有效,且CPSR中的F位為0時(shí),產(chǎn)生FIQ異常(異常向量:0x0000,001C)。使用外部中斷應(yīng)注意把某個(gè)引腳設(shè)置為外部中斷功能后,該引腳為輸入模式,由于沒(méi)有內(nèi)部上拉電阻,所以必須外接一個(gè)上拉電阻,確保引腳不被懸空;除了引腳連接模塊的設(shè)置,還需要設(shè)置VIC模塊,才能產(chǎn)生外部中斷,否則外部中斷只能反映在EXTINT寄存器中;要使器件進(jìn)入掉電模式并通過(guò)外部中斷喚醒,軟件應(yīng)該正確設(shè)置引腳的外部中斷功能,再進(jìn)入掉電模式。第7章ARM異常中斷處理及編程IRQ(外部中斷70第7章ARM異常中斷處理及編程

7.5.1IRQ和FIQ異常中斷處理程序1.不可重入的IRQ/FIQ異常中斷處理程序在C語(yǔ)言中,不可重入的IRQ/FIQ異常中斷處理程序可以使用關(guān)鍵詞_irq來(lái)說(shuō)明。關(guān)鍵詞_irq可以實(shí)現(xiàn)下面的操作:●保存APCS規(guī)定的被破壞的寄存器。●保存其他中斷處理程序中用到的寄存器?!裢瑫r(shí)將(LR-4)賦給程序計(jì)數(shù)器PC實(shí)現(xiàn)中斷處理程序的返回,并且恢復(fù)CPSR寄存器的內(nèi)容。當(dāng)IRQ/FIQ異常中斷處理程序調(diào)用了子程序時(shí),關(guān)鍵詞_irq可以使IRQ/FIQ異常中斷處理程序返回時(shí)從其數(shù)據(jù)棧中讀取LR_irq值,并通過(guò)SUBSPC,LR,#4;實(shí)現(xiàn)返回。第7章ARM異常中斷處理及編程7.5.1I71第7章ARM異常中斷處理及編程

例7.10的程序中說(shuō)明了關(guān)鍵詞_irq的作用。在例中的兩個(gè)C語(yǔ)言程序中,第1個(gè)使用了關(guān)鍵詞_irq的聲明,第2個(gè)沒(méi)有使用關(guān)鍵詞_irq的聲明。例7.10關(guān)鍵詞_irq的作用/*第1個(gè)程序使用關(guān)鍵詞_irq聲明*/_irqvoidIRQHandler(void){volatileunsignedint*base=(unsignedint*)0x80000000;if(*base==1){C_int_handler();//調(diào)用相應(yīng)的C語(yǔ)言處理程序}*(base+1)=0;//清除中斷標(biāo)志}第7章ARM異常中斷處理及編程例7.10的程序中說(shuō)明了關(guān)72第7章ARM異常中斷處理及編程

;第1個(gè)C語(yǔ)言程序?qū)?yīng)的匯編程序IRQHandlerPROCSTMFDsp!,{r0-r4.r12,lr}MOVr4,#0x80000000LDRr0,[r4,#0]SUBsp,sp,#4CMPr0,#1BLEQC_int_handlerMOVr0,#0STRr0,[r4,#4]ADDsp,sp,#4LDMFDsp!,{r0-r4,r12,lr}SUBSpc,lr,#4ENDP第7章ARM異常中斷處理及編程;第1個(gè)C語(yǔ)言程序?qū)?yīng)的匯73第7章ARM異常中斷處理及編程

EXPORTIRQHandler/*第2個(gè)程序沒(méi)有使用關(guān)鍵詞_irq聲明*/irqvoidIRQHandler(void){volatileunsignedint*base=(unsignedint*)0x80000000;if(*base==1){C_int_handler();//調(diào)用相應(yīng)的C語(yǔ)言處理程序}*(base+1)=0;//清除中斷標(biāo)志}第7章ARM異常中斷處理及編程EXPORTIRQHan74第7章ARM異常中斷處理及編程

;第1個(gè)C語(yǔ)言程序?qū)?yīng)的匯編程序IRQHandlerPROCSTMFDsp!,{r4.lr}MOVr4,#0x80000000LDRr0,[r4,#0]CMPr0,#1BLEQC_int_handlerMOVr0,#0STRr0,[r4,#4]LDMFDsp!,{r4,pc}ENDP第7章ARM異常中斷處理及編程;第1個(gè)C語(yǔ)言程序?qū)?yīng)的匯75第7章ARM異常中斷處理及編程

2.可重入的IRQ/FIQ異常中斷處理程序在可重入的IRQ/FIQ異常中斷處理程序中調(diào)用子程序,子程序的返回地址是保存在寄存器LR_irq中,若這時(shí)又發(fā)生了IRQ/FIQ異常中斷,則這個(gè)寄存器LR_irq中的值將會(huì)被破壞,那么被調(diào)用的子程序?qū)⒉荒苷_返回。因此,對(duì)于可重入IRQ/FIQ異常中斷處理程序需要做一些特殊的操作。第7章ARM異常中斷處理及編程2.可重入的IRQ/FIQ76第7章ARM異常中斷處理及編程

第1步中斷處理程序需完成下列操作(注:這一級(jí)不能用C語(yǔ)言編程):●將返回地址保存到IRQ的數(shù)據(jù)棧中。●保存工作寄存器和SPSR_irq。●清除中斷標(biāo)志。●將處理器切換到系統(tǒng)模式,重新使能(IRQ/FIQ)?!癖4嬗脩裟J絃R寄存器和被調(diào)用者不保存的寄存器?!裾{(diào)用C語(yǔ)言IRQ/FIQ異常中斷處理程序?!癞?dāng)C語(yǔ)言的IRQ/FIQ異常中斷處理程序返回后,恢復(fù)用戶模式的寄存器,并禁止中斷(IRQ/FIQ)?!袂袚Q到IRQ模式,禁止中斷?!窕謴?fù)工組寄存器和寄存器LR_irq。●從IRQ異常中斷處理程序中返回。第7章ARM異常中斷處理及編程第1步中斷處理程77第7章ARM異常中斷處理及編程

例7.11可重入的IRQ/FIQ異常中斷處理程序AREAINTERRUPT,CODE,READONLYIMPORTC_irq_handler;引入C語(yǔ)言的IRQ中斷處理程序C_irq_handlerIRQSUBlr,lr,#4STMFDsp!,{lr};保存返回IRQ處理程序地址MRSr14,SPSRSTMFDsp!,{r12,r14};保存SPSR_irq,及其他工作寄存器第7章ARM異常中斷處理及編程例7.11可重入的IR78第7章ARM異常中斷處理及編程

;在這里添加指令,清除中斷標(biāo)志位;添加指令重新使能中斷MSRCPSR_c,#0x1F;切換到系統(tǒng)模式,并使能中斷STMFDsp!,{r0-r3,lr};保存用戶模式的LR_usr及被調(diào)用者不保存的寄存器BLC_irq_handler;跳轉(zhuǎn)到C語(yǔ)言的中斷處理程序LDMFDsp!,{r0-r3,lr};恢復(fù)用戶模式的寄存器MSRCPSR_c,#0x92;切換到IRQ模式,禁止IRQ中斷,F(xiàn)IQ中斷仍允許LDMFDsp!,{r12,r14};恢復(fù)工作寄存器和SPSR_irqLDMFDsp!,{pc}^;從IRQ處理程序返回END第7章ARM異常中斷處理及編程;在這里添加指令,清除中79第7章ARM異常中斷處理及編程

7.5.2多中斷源的IRQ異常中斷處理程序下面通過(guò)一多中斷源的IRQ異常中斷處理程序來(lái)說(shuō)明ARM中斷的使用。例中是32個(gè)中斷源,每個(gè)中斷源對(duì)應(yīng)一個(gè)單獨(dú)的優(yōu)先級(jí)值,優(yōu)先級(jí)的取值范圍為0~31。假設(shè)系統(tǒng)中的中斷控制器的基地址為IntBase,存放中斷優(yōu)先級(jí)值的寄存器的偏移地址為IntLevel。寄存器R13指向一個(gè)FD類(lèi)型的數(shù)據(jù)棧。例7.12多中斷源的IRQ異常中斷處理程序SUBlr,lr,#4STMFDsp!,{lr};保存返回IRQ處理程序地址MRSr14,SPSRSTMFDsp!,{r12,r14};保存SPSR,及R12寄存器MOVr12,#IntBase;讀取中斷控制器的地址LDRr12,[r12,#IntLevel];讀取優(yōu)先級(jí)最高的中斷源的優(yōu)先級(jí)值;使能中斷第7章ARM異常中斷處理及編程7.5.2多中斷源的I80第7章ARM異常中斷處理及編程

MSRr14.CPSRBICr14,r14,#0x80MSRCPSR_c,r14LDRPC,[PC,r12,LSL#2];跳轉(zhuǎn)到優(yōu)先級(jí)最高的中斷對(duì)應(yīng)的中斷處理程序NOP;中斷處理程序地址表DCDPriority0Handler;優(yōu)先級(jí)為0的中斷對(duì)應(yīng)中斷處理程序地址DCDPriority1Handler;優(yōu)先級(jí)為1的中斷對(duì)應(yīng)中斷處理程序地址DCDPriority2Handler;優(yōu)先級(jí)為2的中斷對(duì)應(yīng)中斷處理程序地址DCDPriority3Handler;優(yōu)先級(jí)為3的中斷對(duì)應(yīng)中斷處理程序地址……;優(yōu)先級(jí)為0的中斷對(duì)應(yīng)的中斷處理程序Priority0HandlerSTMFDsp!,{r0-r11};保存工作寄存器第7章ARM異常中斷處理及編程MSRr14.CPSR81第7章ARM異常中斷處理及編程

;這里為中斷程序的程序體LDMFDsp!,{r0-r11};恢復(fù)工作寄存器

MRSr12,CPSRORRr12,r12MSRCPSR_c,r12;禁止中斷LDMFDsp!,{r12,r14};恢復(fù)SPSR及寄存器r12MSRSPSR_csxf,r14;從優(yōu)先級(jí)為0的中斷處理程序返回LDMFDsp!,{pc}^;從IRQ處理程序返回;優(yōu)先級(jí)為1的中斷對(duì)應(yīng)的中斷處理程序Priority1Handler第7章ARM異常中斷處理及編程;這里為中斷程序的82第7章ARM異常中斷處理及編程

7.6基于ARM9芯片S3C2410異常中斷程序設(shè)計(jì)

7.6.1異常中斷響應(yīng)和返回系統(tǒng)運(yùn)行時(shí),異常可能會(huì)隨時(shí)發(fā)生。當(dāng)一個(gè)異常出現(xiàn)以后,ARM微處理器會(huì)執(zhí)行以下幾步操作:(1)

將下一條指令地址存入相應(yīng)連接寄存器LR,以便程序在處理異常返回時(shí)能從正確位置重新開(kāi)始執(zhí)行。(2)

將CPSR復(fù)制到相應(yīng)的SPSR中。(3)

根據(jù)異常類(lèi)型,強(qiáng)制設(shè)置CPSR的運(yùn)行模式位。(4)

強(qiáng)制PC從相關(guān)的異常向量地址取下一條指令執(zhí)行,從而跳轉(zhuǎn)到相應(yīng)的異常處理程序處。

第7章ARM異常中斷處理及編程7.6基于ARM9芯片83第7章ARM異常中斷處理及編程

異常處理完畢之后,ARM微處理器會(huì)執(zhí)行以下幾步操作從異常返回:(1)

將連接寄存器LR的值減去相應(yīng)的偏移量后送到PC中。(2)

將SPSR復(fù)制回CPSR中。(3)

若在進(jìn)入異常處理時(shí)設(shè)置了中斷禁止位,要在此清除。

這些工作必須由用戶在中斷處理函數(shù)中實(shí)現(xiàn)。為保證在ARM處理器發(fā)生異常時(shí)不至于處于未知狀態(tài),在應(yīng)用程序的設(shè)計(jì)中,首先要進(jìn)行異常處理。采用的方式是在異常向量表中的特定位置放置一條跳轉(zhuǎn)指令,跳轉(zhuǎn)到異常處理程序處執(zhí)行程序。第7章ARM異常中斷處理及編程異常處理完畢之后84第7章ARM異常中斷處理及編程

7.6.2異常處理程序設(shè)計(jì)7.6.2.1

異常響應(yīng)流程

由于向量表的限制,只能有一條指令B完成32MB范圍內(nèi)的跳轉(zhuǎn),并不能保證所有的異常處理函數(shù)都位于32MB范圍內(nèi)。為了擴(kuò)展跳轉(zhuǎn)范圍,需要二次跳轉(zhuǎn)才能把異常處理函數(shù)的地址傳送給PC。異常處理調(diào)用關(guān)系如圖7.5所示。三星公司網(wǎng)站提供了test2410_r11軟件包,其中2410init.s有如下代碼:HandlerXXXsub

sp,sp,#4

;減少sp,保存跳轉(zhuǎn)地址stmfd

sp!,{r0}

;將工作寄存器壓入堆棧ldr

r0,=HandleXXX;將HandleXXX地址放入r0ldr

r0,[r0]

;將中斷程序入口地址放入r0str

r0,[sp,#4];將中斷程序入口地址壓入堆棧ldmfd

sp!,{r0,pc}

;將工作寄存器和中斷程序入口地址彈出到r0和PC第7章ARM異常中斷處理及編程7.6.2異常處理程序85第7章ARM異常中斷處理及編程

圖7.5異常處理調(diào)用第7章ARM異常中斷處理及編程圖7.5異常處理調(diào)用86第7章ARM異常中斷處理及編程

并且在RAM中定義了存有中斷程序入口地址表_ISR_STARTADDRESS:AREARamData,DATA,READWRITE^

_ISR_STARTADDRESSHandleReset

#

4HandleUndef

#

4HandleSWI

#

4HandlePabort

#

4HandleDabort

#

4HandleReserved

#

4HandleIRQ

#

4HandleFIQ

#

4第7章ARM異常中斷處理及編程并且在RAM中定義了存87第7章ARM異常中斷處理及編程

通常HandlerXXX位于程序入口地址32MB范圍內(nèi),HandleXXX是以_ISR_STARTADDRESS為基地址的RAM中地址。該代碼主要實(shí)現(xiàn)跳轉(zhuǎn)功能,把異常處理程序地址HandleXXX送到PC中。例如產(chǎn)生IRQ中斷時(shí),PC會(huì)被強(qiáng)制設(shè)置為0x18,執(zhí)行指令:b

HandlerIRQ在HandlerIRQ程序段內(nèi),處理器做一些必要的處理,就會(huì)將_ISR_STARTADDRESS表中存放的IRQ入口地址送入PC,然后開(kāi)始執(zhí)行相關(guān)中斷程序。由于_ISR_STARTADDRESS表存放在RAM中,后面的C語(yǔ)言程序可以方便地更改相關(guān)中斷服務(wù)程序的內(nèi)容。第7章ARM異常中斷處理及編程通常HandlerXX88第7章ARM異常中斷處理及編程

7.6.2.2

異常分支系統(tǒng)可能存在多個(gè)IRQ/FIQ的中斷處理程序。為了從向量表入口處的跳轉(zhuǎn)最終能找到正確的中斷處理程序,需要設(shè)計(jì)一套處理機(jī)制和方法來(lái)實(shí)現(xiàn)??梢栽贏RM的異常向量表之外,增加一張關(guān)聯(lián)中斷控制器的向量表,向量表中的內(nèi)容對(duì)應(yīng)每個(gè)具體的中斷源,可以協(xié)助跳轉(zhuǎn)到不同的中斷處理程序。當(dāng)響應(yīng)外設(shè)的一個(gè)中斷請(qǐng)求時(shí),首先觸發(fā)ARM核的中斷,進(jìn)人中斷程序,再通過(guò)中斷控制器識(shí)別中斷源,使PC能夠自動(dòng)獲得中斷處理程序的地址。有的芯片支持特殊的硬件分支功能,依據(jù)中斷源自動(dòng)跳轉(zhuǎn)到向量表的相應(yīng)地址,多數(shù)情況下是用軟件來(lái)處理異常分支。第7章ARM異常中斷處理及編程7.6.2.289第7章ARM異常中斷處理及編程

在S3C2410體系中,中斷的調(diào)用可以看成是經(jīng)歷了2次“中斷向量表”的查詢。2410init.s中的以下代碼完成功能就是查詢中斷偏移寄存器INTOFFSET,得到當(dāng)前中斷的中斷號(hào),并根據(jù)中斷號(hào)再調(diào)用相關(guān)的中斷服務(wù)程序。第7章ARM異常中斷處理及編程在S3C2410體系中,90第7章ARM異常中斷處理及編程

IsrIRQ

sub

sp,sp,#4

stmfd

sp!,{r8-r9}

ldr

r9,=INTOFFSET

ldr

r9,[r9]

ldr

r8,=HandleEINT0

add

r8,r8,r9,lsl#2

ldr

r8,[r8]

str

r8,[sp,#8]

ldmfd

sp!,{r8-r9,pc}為了方便C程序使用中斷,將IsrIRQ設(shè)為IRQ的中斷服務(wù)程序。

ldr

r0,=HandleIRQ

ldr

r1,=IsrIRQ

str

r1,[r0]第7章ARM異常中斷處理及編程IsrIRQ91第7章ARM異常中斷處理及編程

7.6.2.3

中斷函數(shù)設(shè)計(jì)標(biāo)準(zhǔn)的ARM指令編譯器提供了一個(gè)用來(lái)聲明中斷處理函數(shù)的關(guān)鍵字irq,編譯后的代碼在處理異常事件前保存現(xiàn)場(chǎng)信息,處理異常事件后對(duì)現(xiàn)場(chǎng)信息進(jìn)行恢復(fù)。中斷函數(shù)設(shè)計(jì)如下:staticvoid__irqEint3Int(void){

ClearPending(BIT_EINT3);Uart_Printf("EINT3interruptisoccurred.\n");

num_int=3;//設(shè)置標(biāo)志位}定義中斷處理程序入口地址可用下面的語(yǔ)句實(shí)現(xiàn):#definepISR_EINT3

(*(unsigned*)(_ISR_STARTADDRESS+0x2c))在初始化程序,引用代碼pISR_EINT3=(U32)Eint3Int,即可定義地址_ISR_STARTADDRESS+0x2c內(nèi)容是Eint3Int的地址,外部中斷3產(chǎn)生請(qǐng)求時(shí)即可調(diào)用中斷處理函數(shù)Eint3Int。第7章ARM異常中斷處理及編程7.6.2.3

中斷函92第7章ARM異常中斷處理及編程

7.6.3外中斷初始化程序設(shè)計(jì)S3C2410X的中斷控制寄存器能接收來(lái)自56個(gè)中斷源的請(qǐng)求。內(nèi)部的外圍模塊和外部管腳產(chǎn)生的多個(gè)中斷請(qǐng)求通過(guò)中斷控制器沖裁后,向ARM920T核發(fā)出FIQ或者IRQ中斷。ARM內(nèi)核只有2個(gè)外部中斷輸入信號(hào)nIRQ和nFIQ,在具體嵌入式系統(tǒng)中,需要用中斷控制器管理多個(gè)外部中斷源,選擇其中一個(gè)中斷,通過(guò)nIRQ或nFIQ向ARM內(nèi)核發(fā)出中斷請(qǐng)求,如圖7.6所示。第7章ARM異常中斷處理及編程7.6.3外中斷初始化93第7章ARM異常中斷處理及編程

圖7.6FIQ/IRQ中斷處理過(guò)程第7章ARM異常中斷處理及編程圖7.6FIQ/IRQ94第7章ARM異常中斷處理及編程

ARM920T內(nèi)核可以識(shí)別正常中斷請(qǐng)求和快速中斷請(qǐng)求兩種類(lèi)型的外部中斷,中斷的行為模式由中斷控制器來(lái)設(shè)置。S3C2410X的中斷控制器包括6類(lèi)寄存器:中斷源狀態(tài)寄存器、中斷模式寄存器、中斷屏蔽寄存器、優(yōu)先級(jí)寄存器、中斷狀態(tài)寄存器,以及中斷偏移寄存器。在初始化程序中,需要選擇相應(yīng)管腳的功能,在此定義GPF3為EINT3模式,通過(guò)外部中斷控制寄存器EXTINT0設(shè)定EINT3是下降沿觸發(fā)方式,通過(guò)設(shè)置中斷源懸掛寄存器SRCPND、中斷懸掛寄存器INTPND和中斷屏蔽寄存器INTMSK開(kāi)啟EINT3。中斷模式寄存器和中斷優(yōu)先級(jí)寄存器采用系統(tǒng)默認(rèn)方式。

第7章ARM異常中斷處理及編程ARM920T內(nèi)核可以95第7章ARM異常中斷處理及編程

具體代碼實(shí)現(xiàn)如下:voidEint_Init(void){rGPFCON=(rGPFCON&0x3f0c)|(1<<7);rEXTINT0=(rEXTINT0&~(0x7<<12))|0x2<<12;

pISR_EINT3=(U32)Eint3Int;

rSRCPND=BIT_EINT3;rINTPND=BIT_EINT3;rINTMSK=~(BIT_EINT3);}

如果采用EINT4~EINT23之間的中斷源,還需要設(shè)置外部中斷懸掛寄存器EINTPEND和外部中斷掩碼寄存器EINTMASK的相關(guān)位。第7章ARM異常中斷處理及編程具體代碼實(shí)現(xiàn)如下:96第7章ARM異常中斷處理及編程

在C語(yǔ)言的Main()程序中調(diào)用Eint_Init()函數(shù),即可完成中斷處理的初始化操作。

若外部下降沿信號(hào)接到GPF3管腳,就可以調(diào)用Eint3Int中斷處理函數(shù)。第7章ARM異常中斷處理及編程在C語(yǔ)言的Main(97第7章ARM異常中斷處理及編程

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論