异常与中断1--相关概念
Posted 今天天气眞好
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异常与中断1--相关概念相关的知识,希望对你有一定的参考价值。
1.概念引入以及处理流程
下面先看一个实例:
母亲在看书,小孩在睡觉:
对于轮询方式:
while(1)
{
看书;
打开房门,听到哭声
{
处理
}
打开房门,没有哭声
{
return
}
}
对于中断方式:
while(1)
{
看书;
听见哭声,去处理
}
中断程序
{
处理小孩
}
再来看母亲的处理过程:
(1)先在看书
(2)发生了各种声音
如:远处的猫叫
、门铃声
、小孩哭声
(3)母亲处理
第一步:放入书签,合上书(保存现场
)
第二步:转去处理(调用对应的中断处理函数
)
处理的时候,对于不同的情况不同处理
对于猫叫
:(听而不闻),忽略
对于门铃声
:开门取快递
对于小孩哭声
:照顾小孩
第三步:回来继续看书(恢复现场
)
我们可以将母亲的大脑比作一个CPU,如下:
注意:所谓中断体系实际上就是异常体系,即中断是一中异常
引申拓展为ARM对异常(中断)的处理过程:
1.初始化
(1)设置中断源,让他可以产生中断。如某个按键可以产生中断的话,我们可以设置他的gpio引脚为中断引脚
(2)设置中断控制器(屏蔽,优先级),屏蔽的话就是在要使用的时候打开,优先级是同时有多个中断,我们先去处理那一个
(3)设置CPU总开关(使能中断),举个例子:母亲也正在睡觉,他听不到任何声音,即对所有的中断都没有反应。
2.执行正常程序
3.有中断产生
。如按键按下---->中断控制器----->发信号给CPU
注意:CPU每次执行完一条指令,都会去判断有无中断产生,有无异常产生
当发现有中断产生时,就会去进行相应的处理:
对于不同的异常,会跳去不同的地址
执行程序,在这些地址上,只是一条跳转指令,挑去执行某个函数
此处不同的地址即是异常向量,通常地址都排在一起。
4.这些函数进行中断处理
:
(1)保存现场(设置相应寄存器)
(2)进行处理:先分辨中断源,再调用相应的中断处理函数
(3)恢复现场
查看这些向量表,打来任意一个uboot的汇编代码,因为uboot是裸板程序的集大成者,如下:
第一个reset:是发生复位异常,比如按下复位键,回跳到这执行
第二个:指令无法辨别,或者指令不存在
第三个:软中断
…
注意:当发生中断时,CPU强制跳到24(即0x18)这个地方执行(硬件)
我们可以在0x18的地方放一条指令:ldr pc , _irq
(一条伪指令)
于是CPU就会跳去执行_irq的代码,即:
保护现场、调用中断处理函数、恢复现场
总结:中断程序如何被调用?
CPU强制跳到0x18位置,再通过跳转指令执行其他函数,函数内部就处理中断
处理过程:
(1)保存现场
(2)调用函数:分便中断源、调用对应函数
(3)恢复现场
2.CPU的模式、状态与寄存器
1.CPU的7中模式(mode)
1.用户模式
(usr):不可直接进入其他模式。显示是给上层应用程序使用的,限制应用程序权限,防止破坏整个系统
2.系统模式
(sys)
3.异常模式
(1)未定义指令模式
(und):CPU执行碰到不认识的指令会进入该模式
(2)管理模式
(svc)
(3)中止模式
(abt):也分为指令预取中止和数据访问中止
指令预取中止:CPU执行程序时会去读指令,CPU是以流水线的方式来进行操作的,在执行当前指令的时候,已经在解析下一条指令,在读取第三条指令,此处在读取第三条指令的时候就是预取,有可能会出错
数据访问中止:读写某个地址的过程中可能会出错
(4)中断模式(IRQ)
(5)快中断模式(FIQ):快速处理,可以将某个中断配置为快中断(在Linux下一般不会用到)
特权模式:可以在除了用户模式以外的6种模式之间随意切换
通过编程操作CPSR寄存器直接会进入其他模式
2.CPU的两种状态
ARM state
和 Thumb stste
ARM state:ARM指令集,每个指令4byte
Thumb stste:Thumb指令集,每个指令2byte
注意:Thumb指令集可以减少程序的存储空间,但是在ARM下的nor flash 和nand flash都很大,没有必要节省这么一点空间
例如:
mov r0 , r1指令:
对于ARM 是4byte的机器码
对于Thumb是2byte的机器码
3.CPU的寄存器
CPSR/SPSR:
CPSR:当前程序状态寄存器
SPSR:保存被中断模式下的CPSR(备份寄存器)
可以看到M4-M0为当前CPU处于哪一种模式
T:状态位,表明是ARM还是Thumb状态
F:FIQ禁止,为1时表示禁止,禁止FIQ中断
I:IRQ禁止,为1时表示禁止,禁止IRQ中断
27~8位表示保留位
N,Z,C,V为状态位
如:
cmp r0 , r1:影响Z位,if r0 == r1,则Z = 1
beq xxx:影响Z位,if Z == 1,则跳转
下面看各个模式下能够访问到的寄存器:
注意图中灰色格子表示在这些模式下访问这些寄存器,访问到的是这个模式下的专属寄存器
如:对于Usr和FIQ
mov r0 , r8:r0都一样,但是r8在两种模式下是不同的,访问的不是同一个物理上的寄存器,在FIQ中,r8_fiq是FIQ模式下的专属寄存器
可以看到上图中的R13和R14都是不同的,因此在每种模式下可以设置他们不同的R13(栈)和R14(链接寄存器,保存发生异常时的指令地址)
回顾一下中断处理的过程:
1.保存:保存被中断模式下的寄存器
例如在用户模式下,先进行保存,再去处理异常,保存的时候也不用全部保存,因为模式下的寄存器也会不同,如在FIQ模式下的R8-R14都是专属寄存器,就可以只用保存R0-R7即可,加快处理的速度
2.处理
3.恢复
下面来看异常处理的流程以及从异常返回的流程
异常处理的流程:
(1)把下一条指令的地址保存在LR寄存器中
即:
异常模式下的LR寄存器LR_(哪一种异常模式) = 被中断的下一条指令的地址(PC+4 / PC+8),取决于不同的情况
(2)SPSR_异常 = CPSR
(3)修改CPSR的M4~M0,进入中断模式
(4)跳到向量表
从异常返回:
(1)PC = LR_异常 - offset
(2)CPSR = SPSR_异常(之前保存的)
(3)清中断
以上是关于异常与中断1--相关概念的主要内容,如果未能解决你的问题,请参考以下文章