文章目录
1.两种流程处理
- 1.查询方式
- 特点:简单、但占用较多资源
- 2.中断方式
- 特点:负责、但占用资源少
- 常见的中断有(中断也是异常的一种):
- 按键(外部中断)、定时器中断、网络数据
- 常见的异常有
- 指令异常、数据访问出错、Reset
2.中断处理过程
2.1 硬件初始化
- 设置中断源
- 设置中断控制器(屏蔽、优先级)
- 设置CPU总开关(使能中断)
2.2 执行程序
2.3 产生中断
- eg:
- CPU每执行完一条指令,都会检查有误异常(中断)产生
- 发现异常(中断)产生,开始处理
- 对于不同的异常,会跳去不同的地址(异常向量)执行程序
- 这些地址上,只是一条跳转指令(跳去执行其他函数)
2.4 执行中断
- 1.保存现场(各类寄存器)
- 2.中断处理
- 3.恢复现场
3.ARM的7种模式(Mode)
- 正常模式
-
User (usr): The normal ARM program execution state
- 用户模式(不可以直接进入其他模式)
-
System (sys): A privileged user mode for the operating system
- 系统模式
-
User (usr): The normal ARM program execution state
-
异常模式
-
FIQ (fiq): Designed to support a data transfer or channel process
- 快中断模式
-
IRQ (irq): Used for general-purpose interrupt handling
- 中断模式
-
Supervisor (svc): Protected mode for the operating system
- 管理模式
-
Abort mode (abt): Entered after a data or instruction prefetch abort
- 中止模式
-
Undefined (und): Entered when an undefined instruction is executed
- 未定义指令模式
-
FIQ (fiq): Designed to support a data transfer or channel process
-
除了用户模式以外的6中模式 成为特权模式(Privileged Mode),可以编程操作
CPSR
(当前程序状态寄存器)直接进入其他模式 -
不同模式是为了更好的应对所对应的异常(差别在于:寄存器的资源)
banker register 为备份寄存器,可以成为专属寄存器,R13(SP栈指针)、R14(LR返回地址)
SPSR(保存程序状态寄存器):用来保存“被中断模式的CPSR”,相当于CPSR的备份寄存器,eg:当正处于User Mode
,发生中断,进入IRQ Mode
,SPSR_irq就保存了User Mode那一时刻的CPSR
3.1 异常向量表
4.ARM的2种状态(State)
-
ARM State:
- 使用ARM指令集,占据4个字节
-
Thumb State:
- 使用Thumb指令集,占据2个字节
-
M0~M4:模式位 Mode bit (7种模式)
-
T:状态位 State bits(ARM or Thumb)
5.异常的处理流程
5.1 进入异常
- 进入异常时的动作(硬件部分实现)
- 1.异常模式下的LR存放 [被中断模式的下一条指令的地址](PC+4/PC+8)
- 2.异常模式下的SPSR = CPSR
- 3.修改CPSR的[M4~M0],进入异常模式
- 4.跳到向量表
5.2 退出异常
- 退出异常时的动作(硬件部分实现)
- 1.PC = 异常模式下的LR - Offest(offest根据下表来确定)\
- 2.CPSR = 异常模式下的SPSR(恢复CPSR)
- 3.清除中断标志位
6.程序以thumb指令集运行
6.1 gcc以thumb编译
-
thumb指令集编译、使得代码以thunb状态运行,在makefile中的gcc编译加上
-mthunb
arm-linux-gcc -mthumb -c -o $@ $<
6.2 如何从arm切换至thumb
- [x]在start.S中需要使用ARM指令集的用
.code 32
指定,用thumb指令集的用.code 16
指定
- 使用
BX
指令(其是ARM指令系统中的带状态切换跳转指令),BX
命令后面的那个值如果最低位为1的话,则切换到thumb指令
.code 32
/*..............*/
/* 从ARM State 切换到Thumb State*/
adr r0,thumb_func
add r0,r0,#1 /*bit0 = 1时,bx就会切换CPU状态至thumb state*/
bx r0
.code 16
thumb_func:
/*..............*/
6.3 注意
- 对于thumb指令,不能向PC直接赋值
- eg:
ldr pc, =main
(这样不行),需要先把值赋值寄存器,再把寄存器赋值给PC
- eg:
gcc disable built-in memcpy
- 当使用thumb编译时,gcc会调用memcy,我们可以把变量改成static(存放在data段),这样就不会让gcc去调用了