<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM微處理器的編程模型之:異常中斷處理

          ARM微處理器的編程模型之:異常中斷處理

          作者: 時間:2013-09-13 來源:網(wǎng)絡(luò) 收藏

          本文引用地址:http://www.ex-cimer.com/article/257085.htm

          有些情況下,系統(tǒng)0x0地址不一定是ROM。如果0x0地址為RAM,那么就系統(tǒng)將中斷向量表從ROM復(fù)制RAM,下面的例子顯示了這樣一個過程。

          MOV R8, #0

          ADR R9, Vector_Init_Block

          LDMIA R9!,{r0-r7} ;復(fù)制中斷向量表 (8 words)

          STMIA R8!,{r0-r7}

          LDMIA R9!,{r0-r7} ;復(fù)制由偽操作 DCD定義的地址

          STMIA R8!,{r0-r7}

          注意

          可以使用Scatter文件定義加載向量表的地址,這樣上述代碼的拷貝工作由C庫函數(shù)完成。

          2.使用C語言安裝異常處理程序

          程序中有時需要在main()函數(shù)中使用C語言安裝中斷向量表。這就要求指令經(jīng)編譯后的解碼能安裝在內(nèi)存的正確位置。

          (1)向量表中使用跳轉(zhuǎn)指令的情況

          如果在向量表中使用跳轉(zhuǎn)指令,使用下面的步驟完成向量表的安裝。

          ① 讀取異常處理程序的地址。

          ② 從異常處理程序地址中減去向量表中的偏移。

          ③ 為適應(yīng)指令流水線,將上一步得到的地址減8。

          ④ 將得到的結(jié)果右移2位,得到以字為單位的地址偏移量。

          ⑤ 將結(jié)果的高8位清零,得到跳轉(zhuǎn)指令的24位偏移量。

          ⑥ 將上一步得到的結(jié)果和0xea000000(無條件跳轉(zhuǎn)指令編碼)做邏輯與操作,從而得到要寫到向量表中的跳轉(zhuǎn)指令的正確編碼。

          下面的例子顯示了這樣一個標準過程。

          unsigned Install_Handler (unsigned routine, unsigned *vector)

          { unsigned vec, oldvec;

          vec = ((routine - (unsigned)vector - 0x8)>>2);

          if ((vec 0xFF000000))

          {

          /* diagnose the fault */

          prinf (Installation of Handler failed);

          exit (1);

          }

          vec = 0xEA000000 | vec;

          oldvec = *vector;

          *vector = vec;

          return (oldvec);

          }

          (2)在向量表中使用加載PC指令

          在向量表中使用加載PC指令,按照下面的步驟完成。

          ① 讀取異常處理程序地址。

          ② 從異常處理程序地址中減去向量表中的偏移。

          ③ 為適應(yīng)指令流水線,將上一步得到的地址減8。

          ④ 保留結(jié)果的后12位。

          ⑤ 將結(jié)果與0xe59ff000(LDR PC, [PC,#offset])做邏輯或操作,從而得到要寫到向量表中的跳轉(zhuǎn)指令的正確編碼。

          ⑥ 將異常處理程序的地址放到相應(yīng)的存儲單元。

          下面的例子顯示了一個標準的C語言過程。

          unsigned Install_Handler (unsigned location, unsigned *vector)

          { unsigned vec, oldvec;

          vec = ((unsigned)location - (unsigned)vector - 0x8) | 0xe59ff000;

          oldvec = *vector;

          *vector = vec;

          return (oldvec);

          }

          3.4.7 FIQ和IRQ中斷處理函數(shù)的設(shè)計

          1.中斷分支

          內(nèi)核只有兩個外部中斷輸入信號nFIQ和nIRQ。但對于一個系統(tǒng)來說,中斷源可能多達幾十個。為此,在系統(tǒng)集成的時候,一般都會有一個異??刂破鱽硖幚懋惓P盘?,如圖3.8所示。

          圖3.8 中斷系統(tǒng)

          這時候用戶程序可能存在多個IRQ/FIQ的中斷處理函數(shù)。為了使從向量表開始的跳轉(zhuǎn)始終能找到正確的處理函數(shù)入口,需要設(shè)置一套處理機制和方法。

          多數(shù)情況下是由軟件來處理異常分支的,因為軟件可以通過讀取中斷控制器來獲得中斷源的信息,如圖3.9所示。

          有些芯片可能支持特殊的硬件分支功能,這需要查看具體的芯片說明。

          因為軟件的靈活性,可以設(shè)計出比圖3.9更好的流程控制方法,如圖3.10所示。

          Int_vector_table是用戶自己開辟的一塊存儲器空間,里面按次序存放異常處理函數(shù)的地址。IRQ_Handler()從中斷控制器獲取中斷源信息,然后再從Int_vector_table中的對應(yīng)地址單元得到異常處理函數(shù)的入口地址,完成一次異常響應(yīng)的跳轉(zhuǎn)。這種方法的好處是用戶程序在運行過程中,能夠很方便地動態(tài)改變異常服務(wù)內(nèi)容。

          圖3.9 軟件控制中斷分支

          圖3.10 靈活的軟件分支設(shè)計

          進入異常處理程序后,用戶可以完全按照自己的意愿來進行程序設(shè)計,包括調(diào)用Thumb狀態(tài)的函數(shù)等。但對于絕大多數(shù)的系統(tǒng)來說,有兩個步驟必須處理,一是現(xiàn)場保護,二是要把中斷控制器中對應(yīng)的中斷狀態(tài)標識清除,表明該中斷請求已經(jīng)得到響應(yīng),否則,中斷函數(shù)退出以后,又會被再一次觸發(fā),從而進入周而復(fù)始的死循環(huán)。



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();