浅谈ARM Cortex-M系列架构——指令集
浅谈ARM Cortex-M系列架构——架构篇
目录
浅谈ARM Cortex-M系列架构文章
前言
一、异常是什么?
二、嵌套向量中断控制器(NVIC)
1.灵活的中断和异常管理
挂起状态
2.嵌套向量/中断支持
3.向量化的异常/中断入口
4.中断屏蔽
三、中断管理
四、向量表
总结
Cortex-M3和Cortex-M4 处理器中存在一个名为嵌套向量中断控制器(NVIC)的中断控制器,它是可编程的且其寄存器经过了存储器映射。NVIC 的地址固定,而且 NVIC 的编程模型对于所有的Cortex-M处理器都是一致的。
下图是NVIC(嵌套向量中断控制器)在存储器中映射的位置。
除了外设和其他外部输入的中断外,NVIC还支持多个系统异常,其中,包括不可屏蔽中断(NMI)和处理器内部的其他异常源。
异常是会改变程序流的事件,当其产生时,处理器会暂停当前正在执行的任务,转而执行段被称作异常处理的程序。在异常处理执行完后,处理器会继续正常地程序执行。对于ARM架构,中断就是异常的一种,它一般由硬件(如外设和外部输人引脚)产生,有时也可以由软件触发中断的异常处理也被称作中断服务程序(ISR)。
由上图可以看出Cortex-M处理器支持多个异常源,如NMI、IQR、Systick、系统异常。
异常类型
异常编号 | CMSIS中断编号 | 异常类型 | 优先级 | 功能 |
1 | —— | 复位 | -3(最高) | 复位 |
2 | -14 | NMI | -2 | 不可屏蔽中断 |
3 | -13 | 硬件错误 | -1 | 对于所有等级的错误,若相应的错误处理由于被禁止或被异常屏蔽阻止而未被激活,则会触发该异常 |
4 | -12 | MemManage错误 | 可设置 | 存储器管理错误,由MPU冲突或非法访问引发(如从不可执行区域取指) |
5 | -11 | 总线错误 | 可设置 | 从总线系统收到的错误响应,由指令预取终止和数据访问错误引发 |
6 | -10 | 使用错误 | 可设置 | 使用错误,典型原因为非法指令或非法的状态转换尝试(如在CortexM3中试图切换至ARM状态) |
7~10 | —— | —— | —— | 保留 |
11 | -5 | SVC | 可设置 | 通过SVC实现的请求管理调用 |
12 | -4 | 调试监控 | 可设置 | 调试监控,用于基于软件的调试(一般用不上) |
13 | —— | —— | —— | 保留 |
14 | -2 | PendSV | 可设置 | 可挂起的系统服务请求 |
15 | -1 | SYSTICK | 可设置 | 系统节拍定时器 |
16~255 | 0~239 | IRQ | 可设置 | IRQ输入#0~239 |
通过上面的异常类型表格可以知道,每一个异常都有对应的编号,异常编号1~15我们称为系统异常,而16号以上的异常我们用于中断。所以理论上Cortex-M3/M4处理器最多支持240个中断,但我们使用芯片的时候往往看不到芯片能够支持这么多中断,往往只有16~100个左右。例如F103芯片支持16个系统异常中断和60可屏蔽中断。这样设计好处在于能够减小硅片面积,减少功耗。
异常编号在多个寄存器中都有体现,之前我们讲过PSR(程序状态寄存器)中就包含一个IPSR(中断程序状态寄存器)该寄存器用于确定异常向量地址,因为异常向量存储在向量表中,在异常入口流程中,处理器就会去读取向量表中该异常的起始地址。但是要注意的是异常编号和CMSIS中断编号的定义是不一样的,而在CMSIS中中断的编号从0开始,而系统异常编号为负。
NVIC为Cortex-M处理器的一部分,它是可编程的,且寄存器位于存储器映射的系统控制空间(SCS),可以翻看前言部分的图片。NVIC处理异常和中断配置优先级以及中断屏蔽。NVIC具有以下特性:
每个中断(除了NMI)都可以被使能或禁止,而且都具有可由软件设置或清除的挂起状态。NVIC在设计上既支持产生脉冲中断请求的外设,也支持产生高电平中断请求的外设无须配置任何一个NVIC寄存器以选择其中一种中断类型。NVIC可以处理多种类型的中断源:
尽管外部中断请求在I/O引脚上的电平可能是低有效的,但NVIC收到的请求信号为高有效,会被片上系统逻辑转换为有效的高电平信号。
这里提到了一个概念:挂起状态
挂起状态的意思是,中断被置于一种等待处理器处理的状态。有些情况下,处理器在中断挂起时就会进行处理。不过,若处理器已经在处理另外一个更高或同等优先级的中断,或者中断被某个中断屏蔽寄存器给屏蔽掉了,那么在其他的中断处理结束前或中断屏蔽被清除前,挂起请求会一直保持。
中断的挂起状态被存储在NVIC的可编程寄存器中,当NVIC 的中断输人被确认后,它就会引发该中断的挂起状态。即便中断请求被取消,挂起状态仍会为高。这样,NVIC 可以处理脉冲中断请求。
这一点和传统的 ARM处理器不同。按照之前的方式,若设备产生了中断,如中断请求(IRQ)/快速中断请求(FIQ),那么在它们得到处理前需要一直保持请求信号。目前,由于NVIC中的挂起请求寄存器保存中断请求,即使请求中断的源设备取消了请求信号,已产生的中断仍会被处理,除非在中断处理前清除寄存器中的挂起状态。
中断设置挂起(NVIC->ISPR[n])和中断清除挂起(NVIC->ICPR[n])寄存器
其地址为0xE000E200~0xE000E21C和0xE000280~0xE00029C
访问中断挂起寄存器的函数:
void NVIC_SetPendingIRQ(IRQn Type IRQn);//设置中断的挂起状态
void NVIC_ClearPendingIRQ(IRQn Type IRQn);//清除中断的挂起状态
uint32_tNVICGetPendingIRQ(IRQn TypeIRQn);//查询中断的挂起状态
每个异常都有一个优先级,中断等一些异常具有可编程的优先级,而其他的则可能会有固定的优先级。当异常产生时,NVIC 会将异常的优先级和当前等级相比较,若新异常的优先级较高,当前正在执行的任务就会暂停,有些寄存器则会被保存在栈空间,而且处理器会开始执行新异常的异常处理,这个过程叫作“抢占”。当更高优先级的异常处理完成后,它就会被异常返回操作终止,处理器自动从栈中恢复寄存器内容,并且继续执行之前的任务。利用这种机制,异常服务嵌套不会带来任何软件开销。
当异常发生时,处理器需要确定相应的异常处理入口的位置。对于ARM7TDMI等ARM处理器,这一操作由软件实现,Cortex-M 处理器则会从存储器的向量表中自动定位异常处理的入口。因此,这样也降低了从异常产生到异常处理执行间的延时。
Cortex-M3和Cortex-M4处理器中的NVIC提供了多个中断屏蔽寄存器如PRIMASK特殊寄存器。利用PRIMASK 寄存器,可以禁止除HardFault和NMI外的所有异常。这种屏蔽对不应被中断的操作非常有用,如时序关键控制任务或实时多媒体编解码器。另外,还可以使用BASEPRI寄存器来选择屏蔽低于特定优先级的异常或中断。
CMSIS-Core 提供了一组可以很方便访问各种中断控制功能的函数。NVIC的灵活性和能力还使得 Cortex-M处理器非常易于使用,而且通过降低中断处理的软件开销,在减小了代码体积的同时,还提高了系统的响应速度。
Cortex-M处理器具有多个用于中断和异常管理的可编程寄存器,这些寄存器多数位于NVIC和系统控制块(SCB)中。实际上,SCB 是作为 NVIC 的一部分实现的,不过CMSISCore将其寄存器定义在了单独的结构体中。处理器内核中还有用于中断屏蔽的寄存器(如PRIMASKFAULTMASK 和 BASEPRI)。为了简化中断和异常管理,CMSIS-Core 提供了多个访问函数。NVIC和SCB位于系统控制空间(SCS),地址从0xE000E000 开始大小为4KB,总的地址范围为0xE000E000~0xE000EFFF。SCS中还有 SysTick定时器存储器保护单元(MPU)以及用于调试的寄存器等。该地址区域中基本上所有的寄存器都只能由运行在特权访问等级的代码访问。唯一的例外为软件触发中断寄存器(STIR),它可被设置为非特权模式访问。
常用的中断控制 CMSIS-Core 函数
Void NVIC_EnablelRQ(IRQn_Type IRQn) //使能外部中断
Void NVIC_DisablelRQ(IRQn_Type IRQn) //禁止外部中断
Void NVIC_SetPriority (IRQn_Type IRQn,uint32_t priority) //设置中断的优先级
Void _enable_irq( void) //清除PRIMASK使能中断
Void _disable_irq(void) //设置PRIMASK禁止所有中断
Void NVIC_SetPriorityGrouping(uint32_tPriorityGroup) //设置优先级分组配置
当异常事件产生且被处理器内核接受后,相应的异常处理就会执行。要确定异常处理的起始地址,处理器利用了一种向量表机制。向量表为系统存储器内的字数据数组,每个元素都代表一个异常类型的起始地址,如图 4.26 所示。向量表是可以重定位的,重定位由 NVIC中名为向量表偏移寄存器(VTOR)的可编程寄存器控制。复位后,VTOR 默认为0,向量表则位于地址0x0处。
下图是STM32F4启动文件中定义的向量表(系统异常向量)
IRQ中断向量 (部分)
以上就是今天要讲的内容,本文仅仅简单介绍了中断的一小部分,后续会继续完善中断部分讲解以及Cortex-M处理器的异常处理流程。