国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > ARM異常處理

ARM異常處理 時(shí)間:2018-09-29      來源:未知

只要正常的程序流被暫時(shí)中止,處理器就進(jìn)入異常模式。例如響應(yīng)一個(gè)來自外設(shè)的中斷。在處理異常之前,ARM內(nèi)核保存當(dāng)前的處理器狀態(tài),這樣當(dāng)處理程序結(jié)束是可以恢復(fù)執(zhí)行原來的程序。

注意:如果同時(shí)發(fā)生兩個(gè)或更多異常,那么將按照固定的順序來處理異常 。

ARM支持的異常種類:

一、異常的進(jìn)入與退出

當(dāng)一種異常發(fā)生時(shí),硬件就會(huì)自動(dòng)執(zhí)行如下動(dòng)作:

(1)將CPSR保存到相應(yīng)異常模式下的SPSR中

(2)把PC寄存器保存到相應(yīng)異常模式下的LR中

(3)將CPSR設(shè)置成相應(yīng)的異常模式

(4)設(shè)置PC寄存器的值為相應(yīng)處理程序的入口地址

可以總結(jié)如下圖:

呵呵,在這里我們需要重點(diǎn)研究的是,異常產(chǎn)生后,后PC會(huì)指到哪里去呢?這個(gè)事情實(shí)際不需要我們操心,ARM核在設(shè)計(jì)的時(shí)候就已經(jīng)確定好了,也就是經(jīng)常我們所說的異常向量表。異常向量表:

在ARM7,ARM9/10等處理器,異常向量表可以存放在以 0x00000000或0xffff00000其始的地址。默認(rèn)是以零地址開始存放的?赡苡行┩瑢W(xué)還是有些暈,我們來舉個(gè)例子說明一下。

例如:ARM處理器正在執(zhí)行指令,此時(shí)外部硬件產(chǎn)生了一個(gè)中斷。此時(shí)將產(chǎn)生IRQ異常,然后ARM核就會(huì)自動(dòng)完成我們上面說的4步。完成前3步后,ARM核會(huì)強(qiáng)制將pc的值修改為0x18。修改完成后,處理器就開始從0x18這個(gè)地址取指令執(zhí)行。

從上圖可以知道,不同的異常產(chǎn)生時(shí),ARM核修改的PC值不一樣。例如:如果是swi指令引起的異常,ARM核后就會(huì)修改pc的值為0x08。

是不是異常向量表,一定要放在0x00000000或0xffff00000其始的地址呢?答案:不是,現(xiàn)在cortex-A系列的處理器可以將異常向量表放在任何位置,拿ARM核收到異常后,它怎么知道應(yīng)該將pc的值修改為多少呢?這就需要我們通過協(xié)處理指令告訴它了。

例如:在cortex-A8上,我們可以操作如下協(xié)處理指令,來告訴ARM核異常向量表的位置。

cortex-A8官方手冊(cè):3.2.68節(jié)有詳細(xì)說明

如將告訴ARM核,異常向量表存放在0x20008000

ldr r0,=0x20008000

mcr p15,0,r0,c12,c0,0 

好了,到這里大家已經(jīng)知道了異常是什么,當(dāng)異常產(chǎn)生的時(shí)候,ARM核都會(huì)自動(dòng)做那些事情。當(dāng)然,當(dāng)異常產(chǎn)生的時(shí)候,我們應(yīng)該對(duì)異常做出處理,處理完之后,要返回異常產(chǎn)生之前的場(chǎng)景繼續(xù)運(yùn)行。就像,有些時(shí)候,我們?cè)谧鍪虑榈臅r(shí)候,生病了,我們就需要到醫(yī)生那里去治療一下,等治療完成之后,就必須把生病前的事情接著后面干。

有些人,肯定忍不住了,我知道了異常,也知道異常產(chǎn)生后,pc會(huì)指向異常向量表,那異常向量表中,到底放什么東西呀,我該怎么處理我的異常呢?

首先,回答第一個(gè)問題,異常向量表中存放的就是去醫(yī)生的火箭。坐上火箭就可以到醫(yī)生哪了,這叫一個(gè)字"快"。醫(yī)生,火箭.....

呵呵,別折磨大家了,我們公布答案吧!看下面

從上面我們可以知道,異常向量表里面存放的都是跳轉(zhuǎn)指令。有些時(shí)直接通過b指令實(shí)現(xiàn)的,有些時(shí)通過修改pc值實(shí)現(xiàn)的。這也就是剛剛我說到的"火箭"。跳轉(zhuǎn)的目的是跳到一個(gè)地方對(duì)異常進(jìn)行處理。也就是我說到的到醫(yī)生那里去"治療"。

我們以irq異常為例子,來說明我們需要干的事情

irq : 

SUB    LR,LR,#4 ;計(jì)算返回地址

STMFD  SP!,{R0-R3,LR} ;保存使用到的寄存器

干里你想干的事情

.....

LDMFD  SP!,{R0-R3,PC}^ ;中斷返回

注意:當(dāng)異常結(jié)束時(shí),異常處理程序必須:

1.將LR中的值減去偏移量后存入PC,偏移量根據(jù)異常的類型而有所不同;

2.將SPSR的值復(fù)制回CPSR;

3.清零中斷禁止標(biāo)志。

注:恢復(fù)CPSR的動(dòng)作會(huì)將T、F和I位自動(dòng)恢復(fù)為異常發(fā)生前的值。

哎,終于說完了異常。下面我們用一句話總結(jié)一下:異常產(chǎn)生需要保存現(xiàn)場(chǎng)(ARM核已經(jīng)自動(dòng)為我們做了),異常返回的時(shí)候需要恢復(fù)現(xiàn)場(chǎng)(需要程序員自動(dòng)完成)。

下面我們來詳細(xì)說明異常產(chǎn)生的原因,以及異常返回時(shí),異常模式的lr應(yīng)該保存的值是多少。后我們會(huì)以軟中斷實(shí)驗(yàn),來給大家強(qiáng)化對(duì)異常的理解。

重要基礎(chǔ)知識(shí):R15(PC)總是指向“正在取指”的指令,而不是指向“正在執(zhí)行”的指令或正在“譯碼”的指令。一般來說,人們習(xí)慣性約定將“正在執(zhí)行的指令作為參考點(diǎn)”,稱之為當(dāng)前第一條指令,因此PC總是指向第三條指令。當(dāng)ARM狀態(tài)時(shí),每條指令為4字節(jié)長(zhǎng),所以PC始終指向該指令地址加8字節(jié)的地址,即:PC值=當(dāng)前程序執(zhí)行位置+8;

注意:不管是幾級(jí)流水線都統(tǒng)一按照三級(jí)流水線來分析,這一點(diǎn)已經(jīng)向ARM官方求證過。

(1)快速中斷異常

快速中斷請(qǐng)求(FIQ)適用于對(duì)一個(gè)突發(fā)事件的響應(yīng),這得益于在ARM狀態(tài)中,快速中斷模式有8個(gè)專用的寄存器可用來滿足寄存器保護(hù)的需要(這可以加速上下文切換的速度)。

不管異常入口是來自ARM狀態(tài)還是Thumb狀態(tài),F(xiàn)IQ處理程序都會(huì)通過下面的指令從中斷返回:

SUBS pc,R14_fiq,#4

在一個(gè)特權(quán)模式中,可以通過置位CPSR中的F位來禁止FIQ異常。

(2)中斷請(qǐng)求異常

 中斷請(qǐng)求(IRQ)異常是一個(gè)由nIRQ輸入端的低電平所產(chǎn)生的正常中斷(在具體的芯片中,nIRQ由片內(nèi)外設(shè)拉低,nIRQ是內(nèi)核的一個(gè)信號(hào),對(duì)用戶不可見)。IRQ的優(yōu)先級(jí)低于FIQ。對(duì)于FIQ序列它是被屏蔽的。任何時(shí)候在一個(gè)特權(quán)模式下,都可通過置位CPSR中的I 位來禁止IRQ。 

不管異常入口是來自ARM狀態(tài)還是Thumb狀態(tài),F(xiàn)IQ處理程序都會(huì)通過執(zhí)行下面的指令從中斷返回:

SUBS    PC,R14_fiq,#4

分析IRQ 和 FIQ異常中斷處理的返回:

指令地址  對(duì)應(yīng)于PC 

A           PC-8      執(zhí)行此指令完成后(!)查詢IRQ及FIQ,如果有中斷請(qǐng)求則產(chǎn)生中斷.  

A+4       PC-4 

A+8       PC    ;lr! 

                    (此時(shí)PC的值已經(jīng)更新,指向A+12.將當(dāng)前PC-4(即A+8) 

保存到LR.返回時(shí),要接著執(zhí)行A+4(LR-4)處的指令,所以返回指令為 

SUBS PC, LR,#4(PC=A+4=LR-4) 

白話解釋:對(duì)于普中斷和快中斷異常: 

  中斷必須在一條指令執(zhí)行完以后被檢測(cè)到,如正在執(zhí)行指令甲時(shí)發(fā)生了中斷,不等指令甲執(zhí)行完是不

會(huì)處理該中斷的,發(fā)生異常時(shí)pc已經(jīng)更新(A+12); 

  lr = pc – 4(這時(shí)處理器決定的,無法更改!)即A+8 

  返回后,應(yīng)執(zhí)行被中斷而沒有執(zhí)行的指令(上面的A+4),所以返回時(shí),pc = lr-4

(3)中止

中止發(fā)生在對(duì)存儲(chǔ)器的訪問不能完成時(shí),中止包含兩種類型:

預(yù)取中止   :   發(fā)生在指令預(yù)取過程中

數(shù)據(jù)中止   :   發(fā)生在對(duì)數(shù)據(jù)訪問時(shí)

A.預(yù)取中止

當(dāng)發(fā)生預(yù)取中止時(shí),ARM核將預(yù)取的指令標(biāo)記為無效,但在指令達(dá)到流水線的執(zhí)行階段時(shí)才進(jìn)入異常。如果指令在流水線中因?yàn)榘l(fā)生分支而沒有被執(zhí)行,中止將不會(huì)發(fā)生。

在處理中止的原因之后,不管處于哪種處理器操作狀態(tài),處理程序都會(huì)執(zhí)行下面的指令恢復(fù)PC和CPSR并重試被中止的指令:

SUBS  PC,R14_abt,#4

分析指令預(yù)取中止異常中斷處理的返回: 

指令地址 

A       PC-8     執(zhí)行本指令時(shí)發(fā)生異常,   

A+4   PC-4     處理器將A+4(PC-4)保存到LR.  ;lr! 

A+8   PC 

返回時(shí),發(fā)生指令預(yù)取中止的指令A(yù)(PC-8)處重新執(zhí)行,所以返回指令為 

SUBS PC, LR,#4(PC=A=LR-4) 

白話解釋:對(duì)于預(yù)取指令中止異常: 

  發(fā)生預(yù)取指令異常時(shí),是在執(zhí)行時(shí)發(fā)生的異常,pc未更新,即pc = A+8 

  lr = pc – 4(這時(shí)處理器決定的,無法更改!)即A+4 

  由于這類異常返回后應(yīng)重新執(zhí)行異常的那個(gè)指令(A),所以返回時(shí),pc = lr-4 

B.數(shù)據(jù)中止

指令地址 

A           PC-8    本指令訪問有問題的數(shù)據(jù),產(chǎn)生中斷時(shí),PC的值已經(jīng)更新    

A+4        PC-4   中斷發(fā)生時(shí)PC=A+12,處理器將A+8(PC-4)保存到LR. 

A+8        PC    ;lr! 

返回時(shí),要返回到A處繼續(xù)執(zhí)行,所以指令為SUBS PC,  LR,#8.(PC=A=LR-8) 

白話解釋:對(duì)于數(shù)據(jù)訪問中止異常: 

  發(fā)生數(shù)據(jù)訪問中止異常時(shí),是在執(zhí)行時(shí)訪問數(shù)據(jù)錯(cuò)誤導(dǎo)致的異常,pc已經(jīng)更新,即pc = A+12 

  lr = pc – 4(這時(shí)處理器決定的,無法更改!)即A+8 

  由于這類異常返回后應(yīng)重新執(zhí)行異常的那個(gè)指令(A),所以返回時(shí),pc = lr-8 

(4)軟件中斷指令

所有的任務(wù)都是運(yùn)行在用戶模式下的,因此任務(wù)只能讀CPSR而不能寫SPSR。任務(wù)切換到特權(quán)模式下唯一的途徑就是使用一個(gè)SWI指令調(diào)用,SWI指令強(qiáng)迫處理器從用戶模式切換到SVC管理模式,并且IRQ自動(dòng)關(guān)閉,所以軟件中斷方式常被用于系統(tǒng)調(diào)用。

(5)未定義指令異常

(1)當(dāng)ARM在對(duì)一條未定義指令進(jìn)行譯碼時(shí),發(fā)現(xiàn)這是一條自己和系統(tǒng)內(nèi)任何協(xié)處理器都無法執(zhí)行的指令時(shí),就會(huì)發(fā)生未定義指令異常;

(2)由于是在對(duì)未定義指令譯碼時(shí)發(fā)生異常,所以PC的值等于未定義指令的地址+4(即剛好為中斷返回地址),因此R14保存的值是 中斷返回地址 ,所以當(dāng)異常要返回時(shí)可執(zhí)行以下指令:

MOVS   PC,R14_und    

分析:SWI和和未定義指令異常中斷的返回: 

指令地址 

A         PC-8  當(dāng)前指令為SWI或未定義指令 此時(shí)發(fā)生異常PC的值還沒有更新. 

A+4       PC-4  中斷時(shí)處理器將PC-4保存到LR    ;lr! 

A+8       PC  

返回時(shí),從發(fā)生中斷的指令A(yù)(PC-8)的下一條指令A(yù)+4(PC-4)處開始執(zhí)行,所以直接 

把LR的值賦給PC就行了,具體指令為MOV PC,LR  (PC=A+4=LR) 

白話解釋:對(duì)于SWI和未定義指令異常: 

  發(fā)生異常時(shí)pc沒有更新,根據(jù)ARM的三級(jí)流水線原理,pc沒有更新,仍然等于(A+8); 

  lr = pc – 4(這時(shí)處理器決定的,無法更改!)即A+4 

  由于這類異常返回后應(yīng)執(zhí)行下一條指令(A+4),所以返回時(shí),pc = lr即可

后我們來總結(jié)一下:

  引起PC更新的原因一種是數(shù)據(jù)中止,還有就是中斷了. 

  中斷必須是在一條指令執(zhí)行完畢后才能被檢測(cè)到,所以它中斷的只是還未執(zhí)行的那條指令(pc - 8),

所以pc = lr – 4; 

  與中斷相同,SWI和未定義指令異常也是返回到下一條指令(pc - 4),只是他們?cè)趫?zhí)行時(shí),PC的值并沒

有更新,所以pc = lr; 

  預(yù)取指令中止異常,也沒有發(fā)生pc更新,但它還得重新執(zhí)行發(fā)生異常的那條指令,所以pc = lr – 4; 

  數(shù)據(jù)訪問中止異常,發(fā)生了pc更新,并且它也需要重新執(zhí)行發(fā)生異常的那條指令,所以pc = lr – 8;

當(dāng)多個(gè)異常同時(shí)發(fā)生時(shí),一個(gè)固定的優(yōu)先級(jí)系統(tǒng)決定它們被處理的順序:

二、SWI 實(shí)驗(yàn)

(1)swi 指令

SWI指令用于產(chǎn)生軟中斷,從而實(shí)現(xiàn)在從戶模式變換到管理模式,并且將CPSR保存到管理模式的SPSR中,然后程序跳轉(zhuǎn)到SWI異常入口。在其它模式下也可使用SWI指令,處理器同樣地切換到管理模式。

該指令主要用于用戶程序調(diào)用操作系統(tǒng)的系統(tǒng)服務(wù),操作系統(tǒng)在SWI異常處理程序中進(jìn)行相應(yīng)的系統(tǒng)服務(wù)。

注意:

ARM 內(nèi)核不提供直接傳遞軟中斷(SWI)號(hào)到處理程序的機(jī)制:

SWI 處理程序必須定位SWI 指令,并提取SWI指令中的常數(shù)域

為此, SWI 處理程序必須確定SWI 調(diào)用是在哪一種狀態(tài)(ARM/Thumb).

檢查 SPSR 的 T-bit

SWI 指令在ARM 狀態(tài)下在 LR-4 位置, Thumb 狀態(tài)下在 LR-2位置

SWI 指令按相應(yīng)的格式譯碼:

例如:

 

SWI  13

思考,當(dāng)軟中斷產(chǎn)生后,怎么獲取它的軟中斷號(hào)呢?

實(shí)驗(yàn)的核心代碼如下:

 

software_interrupt:

@設(shè)置軟中斷所在模式的棧

ldr sp,=0x34000

@保存用到的寄存器

stmfd sp!,{r0-r2,lr}

@獲取swi指令對(duì)應(yīng)的機(jī)器碼

ldr r0,[lr,#-4]

@獲取軟中斷號(hào)

bic r0,r0,#0xff000000

@調(diào)用C處理函數(shù),求累加和

bl calc_sum

@獲得函數(shù)返回值,存放在r1

mov r1,r0

@恢復(fù)現(xiàn)場(chǎng),^表示目標(biāo)寄存器是pc時(shí),傳遞數(shù)據(jù)給pc,同時(shí)更新CPSR

ldmfd sp!,{r0-r2,pc}^

上一篇:Linux字符設(shè)備驅(qū)動(dòng)模型之字符設(shè)備初始化

下一篇:Input子系統(tǒng)剖析

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部