Cortex-M系列中断和异常(一)

本文介绍了Cortex-M3/4处理器的中断与异常处理机制,包括中断的类型、优先级定义、向量表和向量表重定向、中断输入和挂起行为。中断与异常实际上是同一事物,中断由外设或外部引脚引起,异常由系统内部触发。文章详细阐述了NVIC中断控制器的工作原理,以及如何管理和配置中断,包括中断的启用、优先级设置和向量表的重定向。此外,还讨论了中断的挂起状态和中断请求的类型。
摘要由CSDN通过智能技术生成


1. 中断与异常

    什么是中断?什么是异常?其实他们是同一个东西,只是来源不同叫法不同。有系统内部引起的异常就叫异常,而由外设或外部引脚引起的异常就叫做中断,中断也是一种异常。提到异常和中断不得不提中断向量控制器NVIC,它是一个硬件结构,它会接收很多中断源产生的请求,根据中断编号执行对应的函数,具体的结构图如下:
[外链图片转存失败(img-7W9q6sTn-1568885073007)(F97A1AA04DC04578B2910DC5AFFAB61A)]
    Cortex-M3和Cortex-M4的NVIC最多支持240个IRQ(中断请求)、一个不可屏蔽中断(NMI),一个systick(系统节拍)定时器中断以及多个系统异常。多数IRQ由定时器、I/O端口和通信接口(如UART、I2C)等外设产生。NMI通常由看门狗定时器或掉电检测器等外设产生,其余的异常则是来气处理器内核,中断还可以利用软件生成。

1.1 异常的类型

    Cortex-M架构支持多种异常和外部中断,编号1~15为系统异常,16及以上的则为中断输入。包括中断在内的大多数的异常的优先级都是可编程的,一些系统异常具有固定的优先级。(中断编号和中断优先级不是同一个概念,注意区分;异常的枚举值和异常编号也不是一个概念)

系统异常列表:
在这里插入图片描述
外部中断列表:
在这里插入图片描述
    中断编号(如中断#0)表示NVIC的中断输入,对于识别是哪一个中断有重要意义,例如:当前正在运行的异常的编号数值位于特殊寄存器-中断程序状态寄存器(IPSR)中,或者NVIC中一个名为中断控制状态寄存器中。如果使用CMSIS-Core来编程,中断编号由枚举来定义,从数值0开始(代表中断 #0),系统异常的编号为负数,具体的定义如下:
在这里插入图片描述
中断编号和相关的枚举是根据具体的芯片而定的,他们一般位于微控制器供应商提供的头文件中,一个名为IRQn的typedef段中。

1.2 异常及中断的管理

    异常及中断的管理都是通过寄存器来控制的,相关寄存器主要有NVIC和系统控制块(SCB system control block),而实际上SCB也是NVIC的一部分,只是CMSIS-Core将其定义在了单独的结构体中。NVIC和SCB位于系统控制空间(SCS system control space),地址从0xE000E000开始,大小为4KB。SCS空间中还有systick定制器,存储器保护单元MPU以及调试的寄存器。该地址区的寄存器基本上都只能由运行在特权访问等级的代码访问。唯一的例外是-软件触发中断寄存器(STIR)。中断操作一般可以使用CMSIS-Core提供的函数:函数列表如下:
在这里插入图片描述

1.2.1 中断的一般使用方法

    复位后所有的中断都处于禁止状态,且默认优先级都为0。在使用任何一个中断之前,(1)设置中断优先级(2)使能外设中的可以触发中断的中断产生控制(3)使能NVIC的中断。
    中断服务程序(ISR)需要写入启动代码中的中断向量表里面,ISR的名字要与启动代码中向量表使用的名字一样,启动代码由芯片供应商来提供。

1.3 优先级的定义

    无论是异常还是有中断都是有优先级的,优先级的大小决定了中断的执行顺序和能够嵌套(优先级数值越小,优先级越高),抢占优先级高的能够打断抢占优先级的的中断,这就是所谓的中断嵌套。有一些异常时有固定优先级的不能够被编程,例如:复位、NMI和HardFault具有固定的负数优先级,其他可编程优先级的范围为0~255(8个bit)。

    可编程优先级的实际数量由芯片设计厂商直接决定,其实多数的Cortex-M3和Cortex-M4支持的有限级较少,如8(3个bit),16(4个bit),32(5个bit)等。这是因为大量的优先级会增加NVIC的复杂度,而且会增加功耗降低的速度。优先级数量的减少是通过去除优先级配置寄存器的最低位(LSB)实现的。中断优先级的个数由优先级寄存器控制,宽度为3~8bits,若设计中只有了三个bit,优先级配置寄存器如下图。(STM32使用4个bits,我们公司的BLE蓝牙芯片也是4个bits)如果是用3个bit来实现,有限级的值可以为0x00(高优先级), 0x02, 0x04, 0x60,0x80, 0xa0, 0xc0, 0xe0具体的优先级等级配置如下。
在这里插入图片描述
在这里插入图片描述
    之所以移除优先级寄存器的最低位LSB而不是最高位MSB,因为这样处理的话,在不同Cortex-M设备之间移植起来更方便。从上图可以看出,3位和4位宽度的优先级寄存器有重合的优先级,因此3位上写的代码可以不需要改动就一直到4位上。

    这8位的优先级寄存器配置寄存器,又被分成了两组,一组是抢占式优先级,另一组是子优先级。分组是利用系统控制块(SCB)中一个名为优先级分组的配置寄存器,具体的分组情况如下图:
[外链图片转存失败(img-kX4u3qTY-1568885073017)(BFE921C31939444AA5D264B58B8C8429)]
    配置优先级分组可以用CMSIS-Core提供的函数接口,具体的函数接口如下:
在这里插入图片描述
    在处理器已经运行一个中断处理时能否产生另一个中断,是由该中断的抢占优先级决定的。子优先级只会用在具有相同抢占优先级的情况,具有更高优先级的异常(即优先级数值越小)会被优先处理。由于优先级的分组存在,抢占优先级最多有7个bit,因此有128个等级,若优先级分组配置为7,所有具有可编程优先级的异常则会处于相同的等级,这些异常之间就不会发生抢占。但是hardfault、NMI和复位则是例外,因为他们的优先级分别为-1,-2,-3,它们可以抢占这些异常。
    若配置优先级寄存器的宽度为3,就会有2个bit的抢占优先级,6个bit的子优先级,因为配置优先级寄存器只有三位,所以只会有1个bit的子优先级,具体的优先级数值如下:
在这里插入图片描述
    STM32使用4个bit作为优先级配置寄存器,分组用的是NVIC_PRIORITYGROUP_4,写入分组寄存器的值是3,因此STM32是没有子优先级的,4个bit全部为抢占式优先级,是可以进行中断嵌套的。

    // stm32f7xx_hal_cortex.h
  • 3
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值