Chinaunix首页 | 论坛 | 博客
  • 博客访问: 355087
  • 博文数量: 90
  • 博客积分: 2017
  • 博客等级: 大尉
  • 技术积分: 615
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-19 08:10
文章分类

全部博文(90)

文章存档

2012年(4)

2011年(74)

2010年(11)

2009年(1)

分类: 嵌入式

2011-05-22 15:03:15

ARM异常中断处理、lr寄存器、工作模式栈设计、中断服务程序ISR


中断和异常处理

中断是异常的一种。每种异常都有各自的异常处理(exception handler),handler存放在异常向量表(vector table)中,由于向量表比较小,handler里通常通过一句跳转语句跳转到实际的异常服务程序中去。

异常会引起处理器工作模式的变化,异常和工作模式的关系为:


当发生异常时,处理器会自动将:
1.当前模式的cpsr存放至异常模式的spsr
2.pc存放至异常模式的lr
3.改变cpsr的工作模式域
4.将pc设置成exception handler的地址

向量表里面存放着handler,handler里面通常是一句跳转语句:


之所以是跳转语句,是因为这几种异常handler的间隔只有4个字节的地址差,即存放一条32位指令,异常服务程序一条指令处理不完吧,所以放一条跳转语句在那里,通过跳转语句跳转到实际的异常服务程序。注意B和LDR使用的区别。
然而由于FIQ是向量表里面的最后异常,如果向量表后面没有其他内容的话,FIR的handler可以不用跳转,将FIQ服务程序直接放在地址0x0000001C的开始。

----------------------------
七种异常
reset:初始化内存、缓存、中断源、每种工作模式下的栈指针。
data abort:访问了无效内存地址,譬如某些内存地址上并没有挂载实际的物理器件。另外,可能访问了没有权限的内存。
IRQ:外设将IRQ引脚设为低电平时触发。
FIQ:外设将FIQ引脚设为低电平时触发,FIQ优先级比IRQ高,有更多的独立模式寄存器。
prefetch abort:取指令时造成内存错误时触发。
SWI:通过执行SWI指令触发。
undefined instruction:遇到了非法指令。


----------------------------
异常返回
lr寄存器保存着异常返回地址。


几种常用的处理lr的方式



----------------------------
中断
中断处理步骤:步骤2里面的都是处理器自动完成的,与其他异常有点不太一样的是它还会将中断掩码设为1,即屏蔽中断。



手动使能中断的方法



中断栈设计
中断时需要保护现场,即将当前工作模式下的数据压入栈。另外,在reset异常中,需要设置栈指针。为了避免栈溢出,可以每次都调用栈检查函数(见汇编篇),还可以采用内存保护机制。典型的栈分布为:


B分布比A分布好的原因是,即使栈溢出了,不会损坏向量表。



譬如要设计以上的一个栈分布时,代码如下,不同工作模式下的栈指针应在reset异常下完成:


一开始设置SVC模式的栈,然后IRQ的,然后user的。通过MSR改变cpsr。
USR_Stack,Usr32md等都是宏定义,通过EQU来定义:


顺便说下DCD指令,DCD就是分配一个地址并初始化为指定的表达式,如:
DCD     0x8000;就是分配一个32位的地址,其内容是0x8000
如果用上标号label,那么这个label相当于一个变量,如:
label   DCD   0X8000;这样引用label就是使用了0x8000这个数值。

----------------------------
简单的非递归的interrupt handler



中断服务程序ISR完成步骤的3和4,在步骤3中通过读取芯片内的中断状态寄存器,可以知道哪个中断源发生了中断,并调用相应的处理程序,所以ISR也像一个表一样的东西。可以用C编写。
阅读(2681) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~