arm中system模式的作用
交了錢被人逼著學才會努力深究,真是賤
以前就知道arm有7種基本工作模式
FIQ 、IRQ由中斷進入
UNDEF、ABORT 由程序異常進入
SVC由上電和軟中斷進入
user由SVC處理程序主動進入
但是還有一個system,使用和user相同的寄存器,但是又沒有SPSR,同時還能執(zhí)行特權(quán)指令
這么一個另類,OS把它當user用不安全,當異常和中斷,又沒有自動進入方式
怎么看怎么別扭,當然這也是領悟之后才意識到的,system是用來解決arm中中斷可重入問題的
搜了一下,網(wǎng)上的關于arm可重入中斷的解釋只有1篇,而且沒有考慮完全http://blog.chinaunix.net/u1/58640/showart_513501.html
默認的中斷處理函數(shù)都會自己先主動把lr壓棧先,此文沒有考慮這一點,把破壞想的嚴重了
這樣的理論知識實踐中幾乎沒有用到,唯有追求專業(yè)的人士才會深究,這樣就能滿足特殊要求,做到一般人做不到的事情
首先,armcc關鍵字__irq不能用來編寫可重入中斷
當中斷可重入時,在中斷處理函數(shù)中使用 BL 調(diào)用子函數(shù),這時候問題就來了,分兩種情況
如果子函數(shù)不是__irq 方式申明的,沒有自己壓棧lr的習慣,那么此時再來一個irq中斷,lr_irq就被新值沖掉
,從此陷入一個死循環(huán)。
如果子函數(shù)是會主動壓棧lr的好孩子,那么僅僅在執(zhí)行壓棧lr的這條指令時,發(fā)生irq中斷才會導致上述問題,但是觸發(fā)問題的條件就變得很苛刻了
所以,這時候就需要system模式來拯救世界了
編寫可重入中斷必須借助以下匯編代碼
IRQHandler
;LR_IRQ ,SPSR_IRQ,r12壓棧,避免下一個IRQ中斷將其沖掉
sub lr,lr,#4
stmfd sp!,{lr}
mrs r14,spsr
STMFD sp!,{r12,r14}
;讀、清中斷控制器中斷源
;省略相關代碼
mov r12,#IntBase
LDR r12,[r12,#IntSource]
;切換到system模式,同時使能IRQ
mrs r14,cpsr
bic r14,r14,#0x9f
orr r14,r14,#0x1f
msr CPSR_c,r14
;保存r0-r3,LR_user到user棧中,然后調(diào)用c子程序,中斷源r0最為一個參數(shù)傳進c處理函數(shù)
BL C_irq_handler ;看名字,就知道這個c程序是__irq形式申明的
;是一個會自己壓棧LR的好孩子
LDMFD sp!,{r0-r3,lr}
;切換到IRQ模式同時禁止IRQ
mrs r12,cpsr
bic r12,r12,#0x1f
orr r12,r12,#0x92
msr CPSR_c,r12
;恢復LR_irq,SPSR_irq和工作寄存器r12,然后退出IRQ
LDMFD sp!,{r12,r14}
msr SPSR_csxf,r14
LDMFD sp!,{PC}^
評論