cortex-M3 异常和中断

发布者:科技独行者最新更新时间:2020-01-07 来源: eefocus关键字:cortex-M3  异常  中断 手机看文章 扫描二维码
随时随地手机看文章

问题:


1、如何开启、关闭中断


2、如何开启、关闭异常


3、程序只跳转一次时,把跳转需要返回地址直接存储在寄存器LR中。多次跳转呢?


基础概述:

操作模式:

Cortex‐M3 支持 2 个模式和两个特权等级。handler模式和线程模式;  特权级和用户级。

cortex-M3 寄存器组:

Cortex‐M3 处理器拥有 R0‐R15 的寄存器组。其中 R13 作为堆栈指针 SP。SP 有两个,但在同一时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。--影子寄存器


如下图:

这里,R13作为堆栈指针寄存器SP(Stack Pointer),R14作为链接寄存器LR(Link register),R15作为程序计数器PC(program counter);


R0-R12:通用寄存器

R0‐R12 都是 32 位通用寄存器,用于数据操作。但是注意:绝大多数 16 位 Thumb 指令只能访问 R0‐R7,而 32 位 Thumb‐2 指令可以访问所有寄存器。


Banked R13:两个堆栈指针

Cortex‐M3 拥有两个堆栈指针,然而它们是 banked,因此任一时刻只能使用其中的一个。


主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)---master SP

进程堆栈指针(PSP):由用户的应用程序代码使用。 ---process SP

堆栈指针的最低两位永远是 0,这意味着堆栈总是 4 字节对齐的。==>u32 的 0x2000 00Fc=......1111 1100b,即最低两位总是0,能够被4整除,不会出现0x2000 00FE这种地址于SP中。


ARM中异常:

凡是打断程序顺序执行的事件,都被称为异常(exception)。除了外部中断外,当有指令执行了“非法操作”,或者访问被禁的内存区间,因各种错误产生的fault,以及不可屏蔽中断发生时,都会打断程序的执行,这些情况统称为异常。在不严格的上下文中,异常与中断也可以混用。另外,程序代码也可以主动请求进入异常状态的(常用于系统调用)。


R14:连接寄存器

当呼叫一个子程序时,由 R14 存储返回地址。

不像大多数其它处理器,ARM为了减少访问内存的次数(访问内存的操作往往要3 个以上指令周期,带MMU和cache的就更加不确定了),把返回地址直接存储在寄存器中。这样足以使很多只有1级子程序调用的代码无需访问内存(堆栈内存),从而提高了子程序调用的效率。如果多于1级,则需要把前一级的R14值压到堆栈里。在ARM上编程时,应尽量只使用寄存器保存中间结果,迫不得以时才访问内存。在RISC处理器中,为了强调访内操作越过了处理器的界线,并且带来了对性能的不利影响,给它取了一个专业的术语:溅出。


R15:程序计数寄存器

指向当前的程序地址。如果修改它的值,就能改变程序的执行流。


特殊功能寄存器

Cortex‐M3 还在内核水平上搭载了若干特殊功能寄存器,包括:

程序状态字寄存器组(PSRs)

中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)

控制寄存器(CONTROL) 

特殊功能寄存器只能被专用的 MSR 和 MRS指令访问,而且它们也没有存储器地址。

MRS  ;读特殊功能寄存器的值到通用寄存器 

MSR  ,   ;写通用寄存器的值到特殊功能寄存器 


程序状态寄存器(PSRs 或曰 PSR)

程序状态寄存器在其内部又被分为三个子状态寄存器:

应用程序 PSR(APSR)

中断号 PSR(IPSR) 

执行 PSR(EPSR) 

通过 MRS/MSR 指令,这 3 个 PSRs即可以单独访问,也可以组合访问(2 个组合,3 个组合都可以)。当使用三合一的方式访问时,应使用名字“xPSR”或者“PSR”。


关于ICI/IT、T: 

ICI:在中断延迟中有提到,与LDM/STM的处理机制有关。LDM/STM是一串LDR/STR的速度优化版。于是,为了加速中断的响应,CM3支持LDM/STM指令的中止和继续,就好像它们只是普通的一串LDR/STR一样。为了实现“指令撕裂与粘合”的目的,需要记录中断时数据传送的进程。为此,CM3在xPSR中开出若干个“ICI位”,记录下一个即将传送的寄存器是哪一个(LDM/STM在汇编时,都把寄存器号升序排序)。在服务例程返回后,xPSR被弹出,CM3再从ICI bits中获取当时LDM/STM执行的进度,从而可以继续传送。 

这个办法听起来是个好主意,只是在个别情况下还有一点限制: 

IF‐THEN(IT)指令的执行也需要在xPSR中使用几个位,可它需要的位刚好与ICI位重合(类似C中的union)——both ICI bits和IT条件都记录在EPSR中。所以,如果在IF‐THEN中使用了LDM/STM,则不再记录LDM/STM 

的执行进度。但尽管如此,及时响应中断依然是首要任务。此时只好把LDM/STM取消,待中断返回后继续执行。

详见:cortex-M3权威指南


PRIMASK/FAULTMASK/BASEPRI

这三个寄存器用于控制异常的使能和除能。


PRIMASK 这是个只有1个位的寄存器。当它置1时, 就关掉所有可屏蔽的异常,只剩下NMI

和硬 fault可以响应。它的缺省值是 0,表示没有关中断。

FAULTMASK 这是个只有1个位的寄存器。当它置 1时,只有NMI 才能响应,所有其它的异常,

包括中断和 fault,通通闭嘴。它的缺省值也是0,表示没有关异常。

BASEPRI 这个寄存器最多有9 位(由表达优先级的位数决定)。它定义了被屏蔽优先级的阈

值。当它被设成某个值后,所有优先级号大于等于此值的中断都被关(优先级号

越大,优先级越低)。但若被设成0,则不关闭任何中断,0 也是缺省值。 


对于时间‐关键任务而言,PRIMASK 和 BASEPRI 对于暂时关闭中断是非常重要的。而FAULTMASK 则可以被 OS 用于暂时关闭 fault 处理机能,这种处理在某个任务崩溃时可能需要。因为在任务崩溃时,常常伴随着一大堆 faults。在系统料理“后事”时,通常不再需要响应这些 fault——人死帐清。总之 FAULTMASK 就是专门留给 OS用的。

要访问 PRIMASK, FAULTMASK 以及 BASEPRI,同样要使用 MRS/MSR 指令。只有在特权级下,才允许访问这 3个寄存器。

其实,为了快速地开关中断,CM3还专门设置了一条 CPS指令,有4种用法 :

CPSID I   ;PRIMASK=1,  ;关中断 

CPSIE I  ;PRIMASK=0,  ;开中断 

CPSID F  ;FAULTMASK=1,  ;关异常 

CPSIE F  ;FAULTMASK=0  ;开异常 


控制寄存器(CONTROL)

控制寄存器用于定义特权级别,还用于选择当前使用哪个堆栈指针。

CONTROL[1] :

在 Cortex‐M3的 handler 模式中,CONTROL[1]总是 0。在线程模式中则可以为 0 或 1。 仅当处于特权级的线程模式下,此位才可写,其它场合下禁止写此位。改变处理器的模式也有其它的方式:在异常返回时,通过修改 LR 的位 2,也能实现模式切换。--详见权威指南

CONTROL[0] 

仅当在特权级下操作时才允许写该位。一旦进入了用户级,唯一返回特权级的途径,就是触发一个(软)中断,再由服务例程改写该位。


如前所述,特权等级和堆栈指针的选择均由 CONTROL 负责。当 CONTROL[0]=0 时,在异常处理的始末,只发生了处理器模式的转换,如下图所示。

中断前后的状态转换:

但若 CONTROL[0]=1(线程模式+用户级),则在中断响应的始末,both  处理器模式和特权等极都要发生变化,如下图所示。

CONTROL[0]只有在特权级下才能访问。用户级的程序如想进入特权级,通常都是使用一条“系统服务呼叫指令(SVC)”来触发“SVC 异常”,该异常的服务例程可以选择修改CONTROL[0]。 当然,其他的异常也可。


一个指定PSP 进行更新的例子:

LDR R0, =0x20008000 

MSR PSP, R0 

BX LR ;

如果是从异常返回到线程状态,则使用新的PSP 的值作为栈顶指针

SVC(supervisor call)和PendSV(可悬起系统调用),

参见:cortex-M3 的SVC、PendSV异常,与操作系统(ucos实时系统)


异常类型

异常类型,优先级以及位置。位置是指与向量表开始处的字偏移。在优先级列中,数字越小表示优先级越高。表中还显示了异常类型的激活方式,及是同步的还是异步的标注。


渐渐地认清自己的状况,这么多年了,菜鸟依旧伴着我。


开/关中断

CM3专门设置的CPS指令,有四种用法:

CPSID I   ;PRIMASK=1,  ;关中断 

CPSIE I  ;PRIMASK=0,  ;开中断 

CPSID F  ;FAULTMASK=1,  ;关异常 

CPSIE F  ;FAULTMASK=0  ;开异常 


CMSIS-M3微控制器软件接口标准中的core_cm3.h也给出了开关中断或异常的函数:

/**

 * @brief  Set the Priority Mask value

 *

 * @param  priMask  PriMask

 *

 * Set the priority mask bit in the priority mask register

 */

static __INLINE void __set_PRIMASK(uint32_t priMask)

{

  register uint32_t __regPriMask         __ASM("primask");

  __regPriMask = (priMask);

}

说明:

使用__set_PRIMASK(1)关闭中断;__setPRIMASK(0)开启中断。

__INLINE是宏定义,对应__inline,这是keil编译器自定义关键字,表示这个函数是内联函数,但并不是强制性内联,编译器最终决定是否内联。

__ASM(“primask”): __ASM也是一个宏,对应__asm,这是keil编译器自定义关键字,关于这个关键字,有相当多的用法,可以在C中内嵌汇编语言、内嵌汇编函数、指定汇编标号以及本代码中的声明一个已命名寄存器变量。这里,已命名的寄存器是("primask"),也就是说寄存器变量__regPriMask等同于编译器已命名的primask。语法为:

register type var-name __asm(reg);


开/关异常

/**

 * @brief  Set the Fault Mask value

 *

 * @param  faultMask  faultMask value

 *

 * Set the fault mask register

 */

static __INLINE void __set_FAULTMASK(uint32_t faultMask)

{

  register uint32_t __regFaultMask       __ASM("faultmask");

  __regFaultMask = (faultMask & 1);

}



以上...

关键字:cortex-M3  异常  中断 引用地址:cortex-M3 异常和中断

上一篇:cortex-M3粗略延时计算
下一篇:OS_CPU_A.ASM cortex-M3 解析

推荐阅读最新更新时间:2024-11-17 01:42

[MSP430] 2.中断和计时器
在这一部分中我们将会初步了解到中断的概念及其作用, 我们会尝试使用计时器中断和 I/O 中断操作 LED 灯,让我们开始吧! 什么是中断?我们可以将它理解为一个约定的信号,来告知单片 机特定的事件发生了,引起程序从正常运行的主函数中断开,转而 执行中断处理程序,处理特定的事件。 中断是一个非常重要的概念,它可以让处理器免于执行冗余的轮 询操作等待特定的外部事件的发生。在 MSP430 的架构中,有许 多种类的中断:计时器中断,I/O 中断,ADC 中断等等。每一种中 断在使用前都要使能和配置,每一种中断又分别有中断处理程序 (Service Routine)。 下面就让我们尝试写一个小程序,实现使用计时器中断和 I/O 中 断
[单片机]
cortex-M3 异常中断
问题: 1、如何开启、关闭中断 2、如何开启、关闭异常 3、程序只跳转一次时,把跳转需要返回地址直接存储在寄存器LR中。多次跳转呢? 基础概述: 操作模式: Cortex‐M3 支持 2 个模式和两个特权等级。handler模式和线程模式; 特权级和用户级。 cortex-M3 寄存器组: Cortex‐M3 处理器拥有 R0‐R15 的寄存器组。其中 R13 作为堆栈指针 SP。SP 有两个,但在同一时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。--影子寄存器 如下图: 这里,R13作为堆栈指针寄存器SP(Stack Pointer),R14作为链接寄存器LR(Link registe
[单片机]
<font color='red'>cortex-M3</font> <font color='red'>异常</font>和<font color='red'>中断</font>
利用CAN中断进行简单的数据接收
CAN是控制器局域网络(Controller Area Network, CAN)的简称,是国际上应用最广泛的现场总线之一。 在北美和西欧,CAN总线协议已经成为汽车计算机控制系统和嵌入式工业控制局域网的标准总线,并且拥有以CAN为底层协议专为大型货车和重工机械车辆设计的J1939协议。 本例通过用MC9S12XS128MAA来实现CAN标准帧的接收。 以下为本例所用到的寄存器介绍(CAN初始化部分用到的寄存器此篇不再赘述,见“利用CAN进行简单的数据发送”) CANRFLG寄存器 WUPIF (唤醒中断标志)= 1 时,MSCAN在CAN总线上检测到活动并请求唤醒 = 0 时,睡眠模式下未观察到唤醒活动 CSCIF(
[单片机]
利用CAN<font color='red'>中断</font>进行简单的数据接收
LPC2000系列的向量中断控制器(VIC)
LPC2000系列的向量中断控制器(VIC)支持32个中断请求输入,也即是支持32个中断源。这32个中断按顺序称为VIC通道0,VIC通道1, ,VIC通道31(实际上只使用了18个其他的预留) 每一个VIC通道都支持软件中断与硬件中断,即每个中断均可由软件或硬件中断产生,软件中断与对应通道上的硬件中断是逻辑 或 的关系。软件中断可通过置位VICSoftInt寄存器相应位来产生,也可通过置位VICSoftIntClear寄存器相应位来清除。 LPC2000具有3类中断:FIQ、向量IRQ和非向量IRQ。LPC2000系列可通过对VICIntSelect和VICVectCntlx(x=0,1, ,15
[单片机]
51单片机学习之路 —— 1.6 单片机的中断(2)
上一次我们简单了解了单片机的中断概念 这一次我们着重了解单片机的定时器中断 先补充点知识 补 : 单片机的几个周期       1:时钟周期:也称振荡周期,就是外接晶振的倒数,如12M的晶振,时钟周期就是1/12um,他是最基本最小的时间单位。      2:状态周期:时钟周期的两倍。       3:机器周期。单片机的基本操作周期,在一个周期内单片机完成一项基本操作,他由12个时钟周期组成,比如12M的晶振,那么机器周期就是1um。其实机器周期就是完成一个单指令的时间。      4:指令周期。他是指CPU执行一条指令所需的时间。比如有单周期指令,双周期指令三周期指令等等。 1 定时器简单概念了解      1
[单片机]
51单片机学习之路 —— 1.6 单片机的<font color='red'>中断</font>(2)
STM32中断优先级和开关总中断
一,中断优先级: STM32(Cortex-M3)中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念 抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。 当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理
[单片机]
UART0串口编程(三):中断方式的串口编程;用中断编写发送
一:中断方式的串口编程 1.用中断方式编写串口程序由那几部分组成 2.硬件上的支持 1 UART0 发送FIFO缓冲区 A.UART0含有1个16字节的发送FIFO缓冲区 B.U0THR是UART0发送FIFO的最高字节 C.UART的发送FIFO是一直使能的 2 UART0接收FIFO缓冲区 A. UART0含有一个16字节的接收FIFO缓冲区。 B. 软件设置接收FIFO缓冲区的触发字节。 3 中断接口:UART0的中断接口包含中断使能寄存器(U0IER)和中断标识寄存器(U0IIR)。 第一:U0IIR:提供状态码用于指示一个挂起中断的中断源和优先级。 第二:U0IER可
[单片机]
UART0串口编程(三):<font color='red'>中断</font>方式的串口编程;用<font color='red'>中断</font>编写发送
μC/OS-II在Cortex-M3系列单片机上的移植
引言   μC/OSII是一种简单高效、源代码公开的实时嵌入式操作系统,具有良好的扩展性和可移植性,被广泛应用到各种嵌入式处理器上;对于提高产品的质量,减少开发周期和降低成本有着重要的意义。本文以μC/OSII为移植对象,以ARM CortexM3内核微处理器为移植目标来讨论其移植过程及应用。    1 μC/OSII及ARM CortexM3简介   实时操作系统μC/OSII是一个基于优先级的抢占式实时内核,程序可读性强,移植性好,代码固定,可裁剪,非常灵活。至今,从8位到64位,μC/OSII已在超过40种不同架构的微处理器上运行。μC/OSII的主要特点有:是优先级可剥夺的实时多任务操作系统;可处理和调度56个
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved