arm 中斷配置以及處理的原始碼分析
CPU的中斷機制是多工的基礎。現代計算機能夠有如此的工作效率很大程度依賴於高速多級的中斷處理。如果CPU沒有中斷處理就只能順序執行程式碼,想不能時時相應外部處理,無法進行多工的工作。
arm的中斷時分為兩級中斷,nomal interrupt和fast interrupt。快速中斷fiq可以打斷進入到niq,不過一般嵌入式系統速度不是很高,任務也不會出現特別時時的需要 一般不會開啟fiq,畢竟開啟之後對於記憶體互斥處理,中間資料儲存將有更高的要求。
一般的soc會在arm外部部署一箇中斷控制器的ip來進行中斷管理。這裡面會維護一個終端的優先順序和記錄中斷狀態。
一下是一份帶有中斷處理的彙編初始程式碼。
.globl _main
.globl start
.equ USERMODE, 0x10
.equ FIQMODE, 0x11
.equ IRQMODE, 0x12
.equ SVCMODE, 0x13
.equ ABORTMODE, 0x17
.equ UNDEFMODE, 0x1b
.equ MODEMASK, 0x1f
.equ NOINT, 0xc0
start:
b reset
interrupt_vector:
LDR PC, _undefined_instruction
LDR PC, _software_interrupt
LDR PC, _prefetch_abort
LDR PC, _data_abort
LDR PC, _not_used
LDR PC, _normal_interrupt
LDR PC, _fast_interrupt
@———————————————-
@ Vector
@———————————————-
_undefined_instruction: .long undefined_instruction
_software_interrupt: .long software_interrupt
_prefetch_abort: .long prefetch_abort
_data_abort: .long data_abort
_not_used: .long not_used
_normal_interrupt: .long normal_interrupt
_fast_interrupt: .long fast_interrupt
undefined_instruction:
B undefined_instruction
software_interrupt:
B software_interrupt
prefetch_abort:
B prefetch_abort
data_abort:
B data_abort
not_used:
B not_used
normal_interrupt:
mrs r8,spsr
@ B normal_interrupt
stmfd sp!, {r0-r12,lr}
ldr r0, =0x00000001
ldr r1, =0x00000002
ldr r2, =0x00000003
ldr r3, =0x00000004
bl rt_hw_trap_irq
ldmfd sp!, {r0-r12,lr}
mrs r8,spsr
@msr cpsr, r8
subs pc, lr, #4
fast_interrupt:
B fast_interrupt
.globl rt_hw_interrupt_disable
rt_hw_interrupt_disable:
mrs r0, cpsr
cpsid if
bx lr
/*
* void rt_hw_interrupt_enable(rt_base_t level);
*/
.globl rt_hw_interrupt_enable
rt_hw_interrupt_enable:
cpsie aif
bx lr
.globl test_save_spsr
test_save_spsr:
mrs r9,spsr
bx lr
reset:
———————————————-
Set CPU mode, flush caches, etc.
———————————————-
#set the cpu to svc32 mode
#turn off IRQ/FIQ bit of CPU
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr_c,r0
#vector 0x0
#enable icaches
#little endian
#disable dcaches, mmu
ldr r0, =0x00400078
mcr p15, 0, r0, c1, c0, 0
ldr r0, =0x00000000
mcr p15, 0, r0, c8, c7, 0 @Flush TLB
mcr p15, 0, r0, c7, c7, 0 @ Flush Caches
mcr p15, 0, r0, c7, c10, 4 @ Flush Write Buffer
mrs r0, cpsr
bic r0, r0, #MODEMASK
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 /* IRQ mode */
ldr sp, =0xa2000000
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0x53
msr cpsr_c,r0
ldr sp, =0x10003800
@———————————————-
@ jump to main
@———————————————-
b main
這裡面從頭開始分析:
開始是start的入口點
這個地址一般定義為0地址
後面的
LDR PC, _undefined_instruction
LDR PC, _software_interrupt
LDR PC, _prefetch_abort
LDR PC, _data_abort
LDR PC, _not_used
LDR PC, _normal_interrupt
LDR PC, _fast_interrupt
為 0x4 0x8 0xa 0x10.. 的地址
如果arm接收到了中斷會根據中斷的型別分別跳轉到這些地址。這裡常遇到的就是data_abort中斷,這個中斷一般是訪問了非法未定義的地址無法獲取到資料,prefetch_abort中斷時無法獲取到正確的指令的中斷,一般是程式碼區損壞出現了非法指令或者是訪問指令區域錯誤到了非法地址了。
最後兩個就是我們正常的快速中斷和正常中斷了。可以看到normal_interrupt 中斷normal_interrupt:
mrs r8,spsr
@ B normal_interrupt
stmfd sp!, {r0-r12,lr}
ldr r0, =0x00000001
ldr r1, =0x00000002
ldr r2, =0x00000003
ldr r3, =0x00000004
bl rt_hw_trap_irq
ldmfd sp!, {r0-r12,lr}
mrs r8,spsr
@msr cpsr, r8
subs pc, lr, #4
他是跳轉過來之後先馬上儲存自己的執行狀態暫存器,因為後面的cpu執行狀態是在中斷模式,跟使用者模式用的協處理器有幾個是公用的,後面肯定會覆蓋的 ,如果不儲存後面就要恢復不了了 ,儲存完狀態就會跳到中斷處理函式rt_hw_trap_irp 中,執行完這個中斷你就可以回到使用者模式把壓到終端狀態棧的協處理器回覆回來。
這裡需要注意的是cpu有幾個棧,中斷的棧 mrs r0, cpsr
bic r0, r0, #MODEMASK
orr r1,r0,#IRQMODE|NOINT
msr cpsr_cxsf,r1 /* IRQ mode */
ldr sp, =0xa2000000
這裡和使用者模式的棧不是一個地址 ,
最後有個需要注意的是:cpu預設上電是不開啟中斷響應的。需要我們用協處理器去開啟他
rt_hw_interrupt_enable:
cpsie aif
bx lr
產生中斷前一定要呼叫他執行。
下一篇將貼出mmu的原始碼分析。
相關文章
- 分析直播間原始碼的特點以及對音影片的處理方式原始碼
- Fabric 1.0原始碼分析(27) Orderer #configupdate(處理通道配置更新)原始碼
- SpringMVC原始碼分析:POST請求中的檔案處理SpringMVC原始碼
- Spring Ioc原始碼分析系列--Ioc容器註冊BeanPostProcessor後置處理器以及事件訊息處理Spring原始碼Bean事件
- 中斷和中斷處理程式
- Laravel Excpetions(錯誤處理) 原始碼分析Laravel原始碼
- MyBatis原始碼分析之核心處理層MyBatis原始碼
- ViewGroup事件分發和處理原始碼分析View事件原始碼
- #21 Go errors 處理及 zap 原始碼分析GoError原始碼
- 原始碼分析:Android訊息處理機制原始碼Android
- kube-scheduler原始碼分析(2)-核心處理邏輯分析原始碼
- external-attacher原始碼分析(2)-核心處理邏輯分析原始碼
- ThinkPHP6 原始碼分析之請求處理PHP原始碼
- spring事務管理原始碼分析(二)事務處理流程分析Spring原始碼
- Android與ARM處理器Android
- Kafka原始碼分析(四) - Server端-請求處理框架Kafka原始碼Server框架
- tomcat原始碼分析(第四篇 tomcat請求處理原理解析--Container原始碼分析)Tomcat原始碼AI
- 前端業務程式碼配置化處理條件判斷邏輯前端
- 【原始碼分析】- 在SpringBoot中你會使用REST風格處理請求嗎?原始碼Spring BootREST
- 影片直播系統原始碼,非同步處理實現程式碼分析原始碼非同步
- 成品app直播原始碼搭建,常用資料處理手段程式碼分析APP原始碼
- thinkphp原始碼分析(四)—錯誤及異常處理篇PHP原始碼
- Scrapy原始碼閱讀分析_4_請求處理流程原始碼
- 直播帶貨原始碼,非同步處理中會處理兩次請求原始碼非同步
- flutter原始碼系列 PageView原始碼分析以及監聽事件Flutter原始碼View事件
- springcloud/springboot整合NACOS 做註冊和配置中心以及nacos原始碼分析GCCloudSpring Boot原始碼
- jetty、servlet以及spring的銜接原始碼分析JettyServletSpring原始碼
- Spring Ioc原始碼分析系列--自動注入迴圈依賴的處理Spring原始碼
- Hystrix微服務容錯處理及回撥方法原始碼分析微服務原始碼
- 【影像處理筆記】SIFT演算法原理與原始碼分析筆記演算法原始碼
- 021ARM處理器工作模式模式
- 中斷處理和GIC-V2
- Spring原始碼解讀之BeanFactoryPostProcessor的處理Spring原始碼Bean
- Tomcat 7 中 NIO 處理分析Tomcat
- snabbdom原始碼解析(七) 事件處理原始碼事件
- 【原始碼】Redis命令處理過程原始碼Redis
- 原始碼解析Java Attach處理流程原始碼Java
- springmvc原始碼 ---DispatcherServlet 處理請求SpringMVC原始碼Servlet
- Trap (陷入/中斷) 原始碼解析原始碼