历史上的今天
今天是:2025年08月10日(星期日)
2021年08月10日 | 1.5.2异常与中断_CPU模式(Mode)_状态(State)与寄存器
2021-08-10 来源:eefocus
CPU模式(Mode)
CPU有七种mode,红框内的为异常模式,另外两种为一种为用户模式,一种为系统模式。其中除了usr用户模式,其余六种模式被称为特权模式(privileged mode),在这六种模式下可以随意切换到任意其他模式(操作CPSR寄存器直接进入其他模式),但在用户模式下不可以直接进入其他模式。

其中,系统模式不会被任何异常触发,并且它使用的是用户模式下的寄存器。然而,它是一种特权模式,不会受到用户模式的限制。系统模式是给操作系统用来操控系统资源的,但希望避免使用与异常模式相关的寄存器,这是为了避免任务状态被任何异常所影响。

下面我们简单介绍一下剩余的五中异常模式:
und(未定义指令异常模式):当CPU执行到一条它不认识的指令时就会进入该模式;
svc(管理模式)
abt(中止模式)
IRQ(中断模式):一个中断可以配置为中断模式,也可以配置为快中断模式。
FIQ(快中断模式)
其中,abt(中止模式)又可以分为
指令预取中止(CPU采用流水线操作,CPU执行当前指令时,已经在解析第二条指令,同时读取第三条指令(预取),这个预取有可能出错,如果出错就会进入这个异常模式)
数据访问中止(比如我们想要读写某个地址,这个过程可能会出错,如果出错就会进入该模式)

上图为各个模式下可以使用的寄存器,可以看到,五种异常模式下,有一些寄存器带有三角形图案的阴影,这些叫做banked register(备份寄存器),表示在该模式下,使用的是该模式下专有的寄存器而不是用户模式下的那些寄存器。
MOV R0, R8 //在用户模式下,访问到的是r8寄存器,但是在FIQ模式下,访问到的是r8_fiq寄存器,他们在物理上就不是同一个寄存器(R0都是同样的R0寄存器)
可以看出,他们都有自己的r13和r14寄存器,r13为记录栈地址的寄存器sp,这表示每个模式下,都可以设置它们自己的栈 ,r14为lr寄存器,可以保存发生异常时指令的地址(保存的是从哪里跳过来的地址)。
快中断模式比其他几个异常模式还多了五个专有的寄存器,这是为了在中断发生时可以更快的响应中断。先来回顾一下中断的处理流程,中断处理流程分为以下三步:
保存现场
调用处理程序
恢复现场
假设程序运行于用户模式下,当中断发生时我们需要将用户模式的特有寄存器入栈保存,然后跳到中断模式去处理,由于快中断的r8-r12是自己专有的寄存器,那么r8-r12就不用保存了,这样响应和处理的时间就比正常的IRQ模式要快。
寄存器(CPSR/SPSR)
下面是CPSR/SPSR寄存器(当前的程序状态寄存器Current Program Status Register和保存的程序状态寄存器Saved Program Status Register),其中SPSR保存的是被中断的模式下,CPSR的寄存器。
其中M4-M0表示当前CPU处于哪种模式,我们可以读取M4-M0来判断当前CPU处于哪种模式,也可以修改M4-M0来切换CPU进入哪种模式(用户模式不可以)。M4-M0有一个表,可以通过这个表来查看CPU当前处于哪种模式。
bit5(T)表示CPU工作与ARM State还是Thumb State。
bit6(F)为快中断使能位,为1表示禁止所有快中断。
bit7(I)为中断使能位,为1表示禁止所有中断。
bit8-bit27为保留位。
bit28-bit31为状态位,一般cmp这些比较指令会改变这些状态位。比如cmp r0, r1,这条指令就会影响Z位。



当异常发生时,处理流程如上图所述,这是由硬件帮我们完成的。
保存被中断的下一条指令地址到LR_异常,在ARM State下保存的是PC+8,在Thumb State下保存的是PC+4;
把CPSR存入SPSR_异常;
修改CPSR的[M4:M0]进入异常模式;
跳到向量表。

处理完异常后,退出异常的流程如上图所述,
将LR_异常减去offset,得到的值赋给PC(offset的取值如下表)。
CPSR = SPSR_异常,将SPSR_异常的值赋回给CPSR。
如果有中断标志位的话,清楚中断标志位。

CPU状态(State)
CPU有两种State,分为ARM State和Thumb State,在ARM State下使用ARM指令集,每个指令占四个字节,在Thumb State下使用Thumb指令,每个指令占两个字节(即最终编译为机器码时占四个字节还是两个字节)。从这里可以看出,Thumb指令集更为高效,事实上,我们引入Thumb指令集正是为了节省程序的存储空间,这对单片机特别有效。但是在嵌入式Linux系统中,Nand Flash或Nor Flash非常大,所以我们都是使用ARM指令集。
先区分下ARM指令集合Thumb指令集:Thumb指令可以看作是ARM指令集压缩形式的子集,是针对代码密度的问题而提出的,它具有16位的代码密度,但是它不如ARM指令的效率高。Thumb不是一个完整的体系结构,不能指望处理器只执行Thumb指令而不支持ARM指令集。因此,Thumb指令只需要支持通用功能,必要时可以借助于完善的ARM指令集。比如,所有异常自动进入ARM状态。在编写Thumb指令时,先要使用伪指令CODE16声明,并且在ARM指令中要使用BX指令跳转到Thumb指令,以切换处理器状态。编写ARM指令时,则可以使用伪指令CODE32声明。
史海拾趣
|
在Linux环境下,安装嵌入式系统的好处 在Linux操作系统下建立交叉编译环境,进行内核的配置,编译,程序的开发等,具有通用性.适合于所有嵌入式设备的系统移植,具有广泛性. 相比在IDE下安装uClinux,安装过程是比较复杂,但后续使用过程中会比较顺利. ...… 查看全部问答> |
|
能否有办法查出本线程在运行过程中有没有被其它线程抢占时间片? 假设某一线程就绪后开始运行,需要比较长的时间,大概500ms,如果这个过程被其它线程抢占,则必须想办法让这个线程知道自己被抢占过。 仅靠CE的API函数,而不动用硬件定时器,能办到吗? … 查看全部问答> |
|
我在wince 5.0的注册表配置文件platform.reg下,加了[HKEY_LOCAL_MACHINE\\Drivers\\BuiltIn\\USB\\camera]USB 的摄像头表值如下: \"DLL\" = \"zc030x.dll\" \"Prefix\" = ...… 查看全部问答> |
|
EVC连接SQLCE出问题:recordset 的open方法总是提示:first—chance exception in XX.exe:0X0 EVC连接SQLCE出问题:recordset 的open方法总是提示:first—chance exception in XX.exe:0X00000f0:stack overflow。 程序如下 ...… 查看全部问答> |
|
请教关于SetFilePointer和IRP_MJ_SET_INFORMATION的问题 我在文件过滤驱动中拦截了IRP_MJ_SET_INFORMATION,为什么在用户层调用SetFilePointer后,我的文件过滤驱动中拦截不到IRP_MJ_SET_INFORMATION呢? 我用了FileSpy和Irptracker发现就没有IRP_MJ_SET_INFORMATION产生,这是为什么呢?… 查看全部问答> |
|
不是说是可以用430的PWM波来控制步进电机(m35sp-7np型号的步进电机,很常见的电机)吗?就是实现步进电机正转反转,加速减速。 但是m35sp-7np型号的步进电机上面除了公共端以外,还有4根线啊,难道说每一根线都要送一个独立的PWM波,还是怎么样的 ...… 查看全部问答> |
|
AD9957的锁相环一直失锁,不用锁相环输出点频信号时正常的,用了锁相环后,PLL_LOCK信号一直为低,sync_clk输出信号也不是稳定的周期信号,环路滤波器的值有点误差,因为现有的器件没有那么精确的电容电阻值,问下锁相环的控制除了控制CFR3之外还要 ...… 查看全部问答> |
|
TC35的GSM模块,我用串口与PC怎么也不能通信,串口线没问题 输入:AT回车 发送后,没有返回。 是不是进行测试前要把sim卡安上,可是我是移动卡安上怎么没反应 是不是无网络 求求各位大神怎么搞… 查看全部问答> |




