swi 是 arm 的軟體中斷指令,大概是 software interrupt 的意思 執行完swi指令後,cpu會做幾件事情:
將當前 cpsr 儲存到 spsr_svc 中
將cpu模式改為特權模式svc_mode, 即更改 cpsr 的低五位, cspr[4:0]=0b10011
切換到arm狀態, cspr[5]=0
禁止irq, cspr[7]=1
將 pc 置為 0x00000008, 即跳到中斷向量的地方開始執行
其於cpu的這種行為,我們需要考慮幾件事情:
如何實現呢?
首先考慮當前的環境和需求。
在我的這塊開發板上,sram的位址空間為 0x30000000 ~ 0x34000000 所以最開始要將測試程式放到 0x30000000 開始的地方。當程式從 0x30000000 位址跑 起來之後,我們再去設定中斷向量表,即在在**中去設定 0x00000000 ~ 0x0000001c 這塊位址空間的指令。
於是想到可以如下來實現:
- .global _start
- _start:
- mov r8, #0
- adr r9, vector_init_block
- ldmia
- stmia
- vector_init_block:
- b reset_addr
- b undefined_addr
- b swi_addr
- b prefetch_addr
- b abort_addr
- b notused_addr
- b irq_addr
- b fiq_addr
程式從 _start 開始執行,第一件事情即將 vector_init_block 開始的8條指令複製到 0x00000000 開始的地方,每條指令佔4位元組,共 8*4=32位元組。
假想現在程式從 0x30000000 開始執行,之後呼叫 swi 發生了軟體中斷,pc開始跳到 0x00000008 開始執行,這個位置的指令是 b swi_addr , 然後再跳到swi_addr去繼續 執行。
這裡有乙個問題,跳轉指令 b 只能在 32m 空間範圍內跳轉。 而 swi_addr 肯定是在 0x30000000 之後的,所以這裡會跳轉失敗。
要想在32位(4g)位址空間實現跳轉,可以使用 ldr 指令。 於是可以如下實現
- .global _start
- _start:
- mov r8, #0
- adr r9, vector_init_block
- ldmia
- stmia
- ldmia
- stmia
- vector_init_block:
- ldr pc, reset_addr
- ldr pc, undefined_addr
- ldr pc, swi_addr
- ldr pc, prefetch_addr
- ldr pc, abort_addr
- ldr pc, notused_addr
- ldr pc, irq_addr
- ldr pc, fiq_addr
- reset_addr: .word reset_handler
- undefined_addr: .word undefined_handler
- swi_addr: .word swi_handler
- prefetch_addr: .word prefetch_handler
- abort_addr: .word abort_handler
- notused_addr: .word 0
- irq_addr: .word irq_handler
- fiq_addr: .word fiq_handler
ldr 指令是將某個位址裡的值讀到暫存器中,而緊接著我們將幾個中斷處理函式 的位址放到記憶體中供 ldr 讀取。
reset_addr .word reset_handler 就是很典型的指標用法, 將處理函式 reset_handler 的位址放到記憶體中存起來。
與上面不同的時,這裡 _start 中不僅複製了指令,而且複製了後面的『指標』
swi處理通常分為兩級:
彙編實現,儲存現場,計算swi中的24位立即數
可以用c實現,具體實現swi各個功能
細分如下:
儲存環境,將要用到的暫存器和返回位址儲存到棧中,供退出時恢復
計算中斷號,swi指令中包括乙個24位的立即數,用於指定特定功能
進入swi處理程式。這部分可以用c實現
中斷返回,恢復暫存器
- swi_handler:
- stmfd
- ldr r0, [lr, #-4]
- bic r0, r0, #0xff000000
- bl c_swi_handler
- ldmfd ^
看到 swi 是怎麼返回的了麼! ldmfd sp!, ^ ^ 表示恢復 spsr_svc -> cpsr
- void c_swi_handler(unsigned int nr)
- - static inline void swi(void)
-
swi 帶的引數 0x1 即為中斷號
講了這麼多,swi倒底可以用來做什麼呢? 通過上面的測試,對swi執行流程有了乙個大概的了解。之後第一映像就是swi可以用來實 現系統呼叫。 如同在x86下linux中使用的
int 0x80
SWI 軟中斷詳解
swi 軟中斷詳解 軟中斷 程式設計異常通常叫做軟中斷 軟中斷是通訊程序之間用來模擬硬中斷的一種訊號通訊方式。中斷源發中斷請求或軟中斷訊號後,cpu或接收程序在適當的時機自動進行中斷處理或完成軟中斷訊號對應的功能 軟中斷是軟體實現的中斷,也就是程式執行時其他程式對它的中斷 而硬中斷是硬體實現的中斷,...
基於ARM7軟中斷程式的設計
1 儲存器部分原理 筆者在設計一專案時採用lpc2458。此cpu為 核心,帶512k位元組的片內flash,98k位元組的片內ram,支援片外local bus 可從片外nor flash啟動cpu。由於 量較大,程式放在片外的nor flash中。且存在片外nor flash在執行程式時,需對片...
ARM中斷筆記
一 arm體系cpu有以下7種工作模式 1 使用者模式 usr 正常的程式執行模式。不能直接切換到其他模式 2 系統模式 sys 執行作業系統的特權任務。與使用者模式類似,但具有直接切換到其他模式等特權 3 快速中斷模式 fiq 支援高速資料傳輸以及通道處理。fiq異常響應時進入此模式 4 中斷模式...