码迷,mamicode.com
首页 > 其他好文 > 详细

文章标题

时间:2015-07-29 21:31:07      阅读:108      评论:0      收藏:0      [点我收藏+]

标签: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的源代码分析。

版权声明:本文为博主原创文章,未经博主允许不得转载。

文章标题

标签:arm中断源码分析

原文地址:http://blog.csdn.net/weiwei_xiaoyu/article/details/47132327

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!