ARM 7 使用者模式下禁止/使能中斷的一種方法–使用非強制中斷 for Keil MDK

來源:互聯網
上載者:User

最近寫一個程式,需要在使用者模式下關中斷,但ARM 7的體繫結構決定了中斷必須在特權模式下才可以更改,所以想到使用ARM的非強制中斷來實現關中斷和開中斷.

 

使用非強制中斷,首先要有硬體指令的支援.ARM有條指令是SWI.

SWI 指令的格式為:

SWI {條件} 24 位的立即數

SWI 指令用於產生軟體中斷,以便使用者程式能叫用作業系統的系統常式。作業系統在 SWI 的例外處理常式中提供相應的系統服務,指令中 24 位的立即數指定使用者程式調用系統常式的類型,相關參數通過通用寄存器傳遞,當指令中 24 位的立即數被忽略時,使用者程式調用系統常式的類型由通用寄存器 R0 的內容決定,同時,參數通過其他通用寄存器傳遞。 

指令樣本:

SWI  0x02       ;該指令叫用作業系統編號位02的系統常式。

 

在keil MDK中,關鍵字__svc可以產生硬體SWI指令,使得處理器能響應軟體中斷.關鍵字__svc,keil MDK協助檔案中這樣描述:

__svc 關鍵字聲明超級使用者調用 (SVC) 函數,該函數最多使用四個類似於整數的參數,並通過 value_in_regs 結構最多返回四個結果。
__svc 是一個函數限定符。它影響函數的類型。

文法
__svc(int svc_num) return-type function-name([argument-list]);
其中:
    svc_num 是在 SVC 指令中使用的立即值。
    它是一個運算式,其計算結果為以下範圍內的整數:
         • 在 ARM 指令中為 0 到 224–1 (24 位值)
         • 在 16 位 Thumb 指令中為 0-255 (8 位值)。

要在keil MDK中使用軟體中斷,要做好兩件事:第一件,更改開機檔案,編寫軟體中斷的彙編入口.在這個彙編入口中主要根據軟體中斷命令號進行相應的函數跳轉.第二件,編寫相應命令號的C語言服務函數.下面舉例怎麼樣用軟體中斷實現開中斷和關中斷.

 

第一步:更改啟動代碼

keil MDK內建的啟動代碼有類似下面的語句:

Vectors         LDR     PC, Reset_Addr        
                     LDR     PC, Undef_Addr
                     LDR     PC, SWI_Addr
                     LDR     PC, PAbt_Addr
                     LDR     PC, DAbt_Addr

藍色語句是程式複位後要執行的第一條指令,即複位異常入口;而紅色語句就是執行一個軟體中斷指令後,要跳轉到的軟體中斷異常入口.通過語句"SWI_Addr        DCD     SWI_Handler"進行中轉,軟體中斷會跳轉到標號為SWI_Handler的語句處,該處即處理軟體中斷的命令號.原始碼如下:

       EXPORT    SWI_Handler
      extern  EnableIrqFunc          ;使能中斷函數名,用C語言實現
      extern  DisableIrqFunc         ;禁止中斷函數名,用C語言實現
SWI_Handler
    STMFD  SP!, {R0,R12,LR}       ;入棧
    LDR      R0, [LR,#-4]               ;取指令
    BIC       R0,R0,#0xFF000000  ;取軟體中斷命令號
    CMP      R0,#0                        ;和0比較,因為我的使能中斷用了軟體中斷命令0,禁止中斷使用了軟體中斷命令1
    BLEQ     EnableIrqFunc                ;為零調用使能中斷函數
    BLNE    DisableIrqFunc                ;不為零調用禁止中斷函數
    LDMFD  SP!,{R0,R12,PC}^    ;出棧

 

第二部:編寫相應命令號的C語言服務函數.

聲明軟體中斷:

__svc(0x00) void EnableIrq(void);  //使能中斷
__svc(0x01) void DisableIrq(void);  //禁止中斷

 

編寫服務函數:

void DisableIrqFunc(void)<br />{<br />int temp;<br /> __asm<br />{<br /> MRS temp,SPSR<br />ORRtemp,temp,#0x80<br />MSR SPSR_c,temp<br />}<br />}<br />void EnableIrqFunc(void)<br />{<br /> int temp;<br />__asm<br />{<br /> MRS temp,SPSR<br />BICtemp,temp,#0x80<br />MSR SPSR_c,temp<br />}<br />}

 

到此,使能和禁止中斷的非強制中斷就結束了,下面看一下執行過程.

 

在程式中,如果想關中斷,只需使用:DisableIrq();

MDK編譯器在執行這句函數時,自動用非強制中斷指令代替,即: SWI 0x01

ARM執行這條軟體中斷指令後,發生軟體中斷異常,程式跳轉到軟體中斷異常服務函數處,即彙編代碼標號為SWI_Handler處,在這裡判斷軟體中斷命令號是0x01,然後執行 BLNE    DisableIrqFunc   語句,調用禁止中斷函數,實現關中斷.

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.