×
单片机 > 单片机程序设计 > 详情

第014课 Jz2400_ARM异常与中断体系详解

发布时间:2024-05-01 发布时间:
|

第001节_概念引入与处理流程


取个场景解释中断。


假设有个大房间里面有小房间,婴儿正在睡觉,他的妈妈在外面看书。


问:这个母亲怎么才能知道这个小孩醒?


过一会打开一次房门,看婴儿是否睡醒,让后接着看书

一直等到婴儿发出声音以后再过去查看,期间都在读书

第一种 叫做查询方式:

*优点:简单

*缺点: 累

写程序如何:


while(1)

{

1 read book(读书)

2 open door(开门)

if(睡)

return(read book)

else

照顾小孩


}


第二种叫中断方式:


优点:不累

缺点:复杂

写程序:



while(1)

{

read book

中断服务程序()//如何被调用?

{

处理照顾小孩

}

}


我们看看母亲被小孩哭声打断如何照顾小孩?


母亲的处理过程:


1 平时看书


2 发生了各种声音,如何处理这些声音

:: 有远处的猫叫(听而不闻,忽略)

:: 门铃声有快递(开门收快递)

:: 小孩哭声(打开房门,照顾小孩)

3 母亲的处理

:: 只会处理门铃声和小孩哭声

:: a 现在书中放入书签,合上书(保存现场)

:: b 去处理 (调用对应的中断服务程序)

:: c 继续看书(恢复现场)


不同情况,不同处理:


a 对于门铃:开门取快件


b 对于哭声:照顾小孩


我们将母亲的处理过程抽象化——母亲的头脑相当于CPU


耳朵听到声音会发送信号给脑袋,声音来源有很多种,有远处的猫叫,门铃声,小孩哭声。这些声音传入耳朵,再由耳朵传给大脑,除了这些可以中断母亲的看书,还有其他情况,比如身体不舒服,有只蜘蛛掉下来,对于特殊情况无法回避,必须立即处理


对比我们的arm系统

有CPU,有中断控制器。


中断控制器可以发信号给CPU告诉它发生了那些紧急情况


中断源有按键、定时器、有其它的(比如网络数据)


这些信号都可以发送信号给中断控制器,再由中断控制器发送信号给CPU表明有这些中断产生了,这些成为中断(属于一种异常)


还有什么可以中断CPU运行?


指令不对,数据访问有问题


reset信号,这些都可以中断CPU 这些成为异常中断


重点在于保存现场以及恢复现场


处理过程


a 保存现场(各种寄存器)


b 处理异常(中断属于一种异常)


c 恢复现场


arm对异常(中断)处理过程


1 初始化:

:: a 设置中断源,让它可以产生中断

:: b 设置中断控制器(可以屏蔽某个中断,优先级)

:: c 设置CPU总开关,(使能中断)


2 执行其他程序:正常程序


3 产生中断:按下按键—>中断控制器—>CPU


4 cpu每执行完一条指令都会检查有无中断/异常产生


5 发现有中断/异常产生,开始处理。对于不同的异常,跳去不同的地址执行程序。这地址上,只是一条跳转指令,跳去执行某个函数(地址),这个就是异常向量。如下就是异常向量表,对于不同的异常都有一条跳转指令。


.globl _start

_start: b reset

ldr pc, _undefined_instruction

ldr pc, _software_interrupt

ldr pc, _prefetch_abort

ldr pc, _data_abort

ldr pc, _not_used

ldr pc, _irq //发生中断时,CPU跳到这个地址执行该指令 **假设地址为0x18**

ldr pc, _fiq

//我们先在0x18这里放 ldr pc ,__irq,于是cpu最终会跳去执行__irq代码

//保护现场,调用处理函数,恢复现场


(3-5都是硬件强制做的)


6 这些函数做什么事情?

:: 软件做的:

:: a 保存现场(各种寄存器)

:: b 处理异常(中断):

:::: 分辨中断源

:::: 再调用不同的处理函数

:: c 恢复现场


对比母亲的处理过程来比较arm中断的处理过程。


中断处理程序怎么被调用?


CPU—>0x18 –跳转到其他函数->

:: 做保护现场

:: 调用函数

:::: 分辨中断源

:::: 调用对应函数

:: 恢复现场


cpu到0x18是由硬件决定的,跳去执行更加复杂函数(由软件决定)


第002节CPU模式(Mode)状态(State)与寄存器

这节课我们来讲CPU的工作模式(Mode) 状态(State)寄存器


7种Mode:


usr/sys

undefined(und)

Supervisor(svc)

Abort(abt)

IRQ(irq)

FIQ(fiq)


2种State:


ARM state

Thumb state


寄存器:

通用寄存器

备份寄存器(banked register)

当前程序状态寄存器(Current Program Status Register);CPSR

CPSR的备份寄存器:SPSR(Save Program Status Register)


我们仍然以这个母亲为例讲解这个CPU模式

这个母亲无压力看书 –>(正常模式)

要考试,看书—>(兴奋模式)

生病—->(异常模式)


可以参考书籍 《ARM体系结构与编程》作者:杜春雷


对于ARM CPU有7种模式:


1 usr :类比 正常模式


2 sys :类比的话兴奋模式


3 5种异常模式:(2440用户手册72页)

:: 3.1 und :未定义模式

:: 3.2 svc :管理模式

:: 3.3 abt :终止模式

:::: a 指令预取终止(读写某条错误的指令导致终止运行)

:::: b 数据访问终止 (读写某个地址,这个过程出错)

:::: 都会进入终止模式

:: 3.4 IRQ: 中断模式

:: 3.5 FIQ: 快中断模式


我们可以称以下6种为特权模式

und :未定义模式

svc :管理模式

abt :终止模式

IRQ :中断模式

FIQ :快中断模式

sys :系统模式


usr用户模式(不可直接进入其他模式) 可以编程操作CPSR直接进入其他模式

这个图是有关各个模式下能访问寄存器的,再讲这个图之前我们先引入 2种state


CPU有两种state:


1 ARM state:使用ARM指令集,每个指令4byte

2 Thumb state:使用的是Thumb指令集,每个指令2byte

比如同样是:


mov R0, R1 编译后


对于ARM指令集要占据4个字节:机器码


对于Thumb指令集占据2个字节:机器码


引入Thumb减少存储空间


ARM指令集与Thumb指令集的区别:


Thumb 指令可以看作是 ARM 指令压缩形式的子集,是针对代码密度的问题而提出的,它具有 16 位的代码密度但是它不如ARM指令的效率高 .


Thumb 不是一个完整的体系结构,不能指望处理只执行Thumb 指令而不支持 ARM 指令集.


因此,Thumb 指令只需要支持通用功能,必要时可以借助于完善的 ARM 指令集,比如,所有异常自动进入 ARM 状态.在编写 Thumb 指令时,先要使用伪指令 CODE16 声明,而且在 ARM 指令中要使用 BX指令跳转到 Thumb 指令,以切换处理器状态.编写 ARM 指令时,则可使用伪指令 CODE32声明.


下节课会演示使用Thumb指令集编译,看是否生成的bin文件会变小很多

在每种模式下都有R0 ~ R15


在这张图注意到有些寄存器画有灰色的三角形,表示访问该模式下访问的专属寄存器

比如

mov R0, R8

mov R0, R8

在System 模式下访问的是R0 ~ R8,在所有模式下访问R0都是同一个寄存器

mov R0,R8_fiq

但是在FIQ模式下,访问R8是访问的FIQ模式专属的R8寄存器,不是同一个物理上的寄存器


在这五种异常模式中每个模式都有自己专属的R13 R14寄存器,R13用作SP(栈) R14用作LR(返回地址)

LR是用来保存发生异常时的指令地址


为什么快中断(FIQ)有那么多专属寄存器,这些寄存器称为备份寄存器


回顾一下中断的处理过程

* 1 保存现场(保存被中断模式的寄存器)


就比如说我们的程序正在系统模式/用户模式下运行,当你发生中断时,需要把R0 ~ R14这些寄存器全部保存下来,让后处理异常,最后恢复这些寄存器


但如果是快中断,那么我就不需要保存 系统/用户模式下的R8 ~ R12这几个寄存器,在FIQ模式下有自己专属的R8 ~ R12寄存器,省略保存寄存器的时间,加快处理速度


但是在Linux中并不会使用FIQ模式


2 处理


3 恢复现场


CRSR当前程序状态寄存器,这是一个特别重要的寄存器


SPSR保存的程序状态寄存器,他们格式如下:

首先 M4 ~ M0 表示当前CPU处于哪一种模式(Mode);


我们可以读取这5位来判断CPU处于哪一种模式,也可以修改这一种模式位,让其修改这种模式;


假如你当前处于用户模式下,是没有权限修改这些位的;


M4 ~ M0对应什么值,会有说明:

查看其他位

Bit5 State bits表示CPU工作与Thumb State还是ARM State用的指令集是什么

Bit6 FIQ disable当bit6等于1时,FIQ是不工作的

Bit7 IRQ disable当bit5等于1时,禁止所有的IRQ中断,这个位是IRQ的总开关

Bit8 ~ Bit27是保留位

Bite28 ~ Bit31是状态位,


什么是状态位,比如说执行一条指令

cmp R0, R1

如果R0 等于 R1 那么zero位等于1,这条指令影响 Z 位,如果R0 == R1,则Z = 1


beq跳转到xxx这条指令会判断Bit30是否为1,是1的话则跳转,不是1的话则不会跳转

使用 Z 位,如果 Z 位等于1 则跳转,这些指令是借助状态位实现的


SPSR保存的程序状态寄存器:

表示发生异常时这个寄存器会用来保存被中断的模式下他的CPSR


就比如我我的程序在系统模式下运行 CPSR是某个值,当发生中断时会进入irq模式,这个CPSR_irq就保存系统模式下的CPSR


我们来看看发生异常时CPU是如何协同工作的:


进入异常的处理流程(硬件)

我们来翻译一下:


发生异常时,我们的CPU会做什么事情


1把下一条指令的地址保存在LR寄存器里(某种异常模式的LR等于被中断的下一条指令的地址)

它有可能是PC + 4有可能是PC + 8,到底是那种取决于不同的情况


2 把CPSR保存在SPSR里面(某一种异常模

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ..[12]
Jz2400ARM异常中断体系

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机的抗干扰措施有哪些