精华内容
下载资源
问答
  • 中断和异常的区别
    2021-09-11 11:50:43

    中断

    由CPU以外的事件引起的中断

    如:I/O中断,时钟中断,控制台中断

    异常

    来自CPU内部事件或程序执行中的事件引起的过程

    如:硬件故障中断

    典型异常:程序性中断,访管指令异常

    程序性中断:算术溢出,被零除,虚拟存储中缺页

    更多相关内容
  • stm32异常中断和事件的区别

    千次阅读 2019-08-20 09:36:28
    中断和异常的区别 中断是指系统停止当前正在运行的程序转到...Cortex-M3内核总共支持256个中断,其中包含16个内核异常和240个外部中断,但是各个芯片产商在设计芯片的时候会对CM3内核的芯片进行精简设计,如STM...

    中断和异常的区别

    1. 中断是指系统停止当前正在运行的程序转到其他的服务,可能是程序接收了比自身高优先级的请求,或者是人为设置中断,中断是属于正常现象

    2. 异常是指由于CPU本身故障、程序故障或者请求服务等引起的错误,异常属于不正常现象。

      Cortex-M3内核总共支持256个中断,其中包含16个内核异常和240个外部中断,但是各个芯片产商在设计芯片的时候会对CM3内核的芯片进行精简设计,如STM32F103系列,所搭载的异常响应系统,包含10个系统异常和60个外部中断,用一张表将它们管理起来,编号0~15为系统异常(优先级为-3到6),16以上称为外部中断。

    系统异常清单:

    在这里插入图片描述
    比较常见的异常就是hardfault异常了,可以看到他的优先级被设置为了-1,而且是不允许用户修改的。

    外部中断清单:

    在这里插入图片描述
    ……
    在这里插入图片描述

    外部中断信号从核外发出信号最终要传递到NVIC(嵌套向量中断控制器)NVIC跟内核紧密耦合,它控制着整个芯片中断的相关功能。

    中断优先级

    STM32支持两种优先级:抢占优先级和子优先级。所有优先级可编程的中断源都需要指定这两种优先级。抢占优先级决定是否可以产生中断嵌套,子优先级决定中断响应顺序,若两种优先级一样则看中断源在中断向量表中的偏移量,偏移量小的先响应。
    对这句话的解释为:

    1. 抢占优先级高的中断源可以中断抢占优先级低的中断处理函数,进而执行高优先级的中断处理函数,执行完毕后再继续执行被中断的低优先级的处理函数。
    2. 当两个中断源的抢占优先级相同时,即这两个中断将没有嵌套关系,当一个中断到来后,若此时cpu正在处理另一个中断,则这个后到来的中断就要等到前一个中断处理函数处理完毕后才能被处理当这两个中断同时到达,则中断控制器会根据它们的子优先级决定先处理哪个
    3. 如果两个中断的优先级都设置为一样了,那么谁先触发的就谁先执行;如果是同时触发的,那么就根据中断向量表的位置来决定谁先执行。

    中断和事件的区别

    产生中断线路目的是把输入信号输入到 NVIC进一步会运行中断服务函数,实现功能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号传输,属于硬件级的

    简单点来说,就是中断最终会自动进入中断服务函数,而事件则不会有对应的服务函数。中断是软件级的,而事件是硬件级的。

    展开全文
  • STM32异常中断过程详解

    千次阅读 多人点赞 2021-06-14 15:14:52
    1. 异常中断概念引入 异常主要是指来自CPU内部的意外事件,比如执行了未定义指令、算术溢出、除零运算等发生在CPU内部...下面对异常和中断的介绍,如果中断信号的产生原因来自CPU内部,则称之为异常;如果中断信号来

    1. 异常与中断概念引入

    异常主要是指来自CPU内部的意外事件,比如执行了未定义指令、算术溢出、除零运算等发生在CPU内部的意外事件,这些异常的发生,会引起CPU运行相应的异常处理程序;中断一般来自硬件(如片上外设、外部I/O输入等)发生的事件,当这些硬件产生中断信号时,CPU会暂停当前运行的程序,转而去处理相关硬件的中断服务程序。但无论是异常还是中断,都会引起程序执行偏离正常的流程,转而去执行异常/中断的处理函数。

    下面对异常和中断的介绍,如果中断信号的产生原因来自CPU内部,则称之为异常;如果中断信号来自CPU外部,则称之为中断。有些场合如果没有明确指出是异常还是中断,就统称为中断。

    1.1 为什么需要中断

    在网上看到一个非常有意思的例子,这里引用下类似的例子来说明为什么需要中断。当你正在看一部很喜欢的电影时,这个时候你觉得有点口渴了,需要去烧一壶开水,假设水烧开需要10分钟。那么请问你如何知道水烧开了呢?也许你会有这两种选择:

    1. 每隔一小会你就跑去看一下这壶水有没有被烧开,然后回来接着看电影;
    2. 你可以等到水壶发出水被烧开的声音才去看一下,这期间你一直在看电影。

    第一种情况的处理方式,实际上就是不断的查询水是否被烧开了,如果烧开了就关火,没烧开就接着继续看电影,这种处理方式可能会累死你,而且你也会觉得自己有点笨。写程序描述如下:

    while (1)
    {
    	see a film(看电影)
        check water boiling(查看水是否烧开)
        if (水还没开)
            return(继续看电影)
        else
            关火    
    }
    

    第二种方式可以看作是烧开水的声音发出了一个信号给你,你接收到这个信号,然后就知道了我该去关火了,也就是说这个信号中断了你看电影的过程,而在这之前你可以一直享受看电影的过程。写程序描述如下:

    while (1)
    {
    	see a film(看电影)   
    }
    
    中断服务程序()
    {
        关火
    }
    

    这个例子类比于CPU的话,CPU也是可以选择这两种方式去处理意外事件的,查询方式或者中断方式。对于查询方式很明显会使得CPU的资源无法得到充分的利用,因为CPU的速度是远远大于外设的速度的,CPU在查询外设的状态时就需要等待外设的响应,使得CPU做了很多无用功。而对于中断方式,当外部事件还没达到就绪状态时(类比就是水还没烧开这件事),CPU可以专心的做其他任务,一旦CPU接收到中断信号时,转而去处理中断请求,CPU处理完毕之后再接着执行原来的任务。

    从这个类比的例子可以看出,中断机制使得CPU具有了异步处理能力。有了中断机制之后,CPU可以一直专心的执行它的主任务,不用一直去查询设备的状态。设备本身如果达到了就绪状态,需要CPU去处理的时候,此时设备发出一个中断信号给CPU,通知CPU说:“我要你来处理一下了,赶紧来吧”!CPU收到通知之后,先把主任务暂停一会,然后跳转到相应外设的中断服务函数处理该外设的中断请求,处理完之后CPU再继续回去执行主任务。

    1.2 ARM体系如何使用中断

    在ARM体系中,使用中断的过程一般有如下步骤:

    1. 中断初始化

      1.1 设置中断源,让某个外设可以产生中断;

      1.2 设置中断控制器,使能/屏蔽某个外设的中断通道,设置中断优先级等;

      1.3 使能CPU中断总开关

    2. CPU在运行正常的程序

    3. 产生中断,比如用户按下了按键 —> 中断控制器 —> CPU

    4. CPU每执行完一条指令都会检查是否有异常/中断产生

    5. 发现有异常/中断产生,开始处理:

      5.1 保存现场

      5.2 分辨异常/中断,调用对应的异常/中断处理函数

      5.3 恢复现场

    2. STM32异常与中断处理流程

    2.1 概述

    上面讲到当CPU产生异常/中断时,CPU会暂停当前程序的运行,转而去处理异常/中断的处理函数。但是这里有一些疑问:CPU如何调用异常/中断的处理函数?调用完之后如何返回?在运行中断处理函数之后,如何保证原来被打断的运行环境不被中断处理函数所改变?这几个问题是异常与中断处理流程中非常关键的问题,这些问题会在下面进行讨论,并给出解答。

    当异常/中断发生时,ARM架构对于异常/中断的处理流程基本都是:

    1. 保存现场
    2. 分辨异常/中断,调用对应的异常/中断处理函数
    3. 恢复现场

    但是细分到不同的架构(比如M3和A7架构)时,具体的处理流程还是有一些差异的,而对于STM32来说,中断的整个处理流程硬件帮我们做了大部分的工作,比如保存现场、分别异常/中断,跳转执行、恢复现场等工作,都是硬件帮我们实现了的。那么我们要做的事情是什么?我们只需要编写中断服务函数中具体想要实现的逻辑代码即可,发生异常/中断后,CPU跳转执行的就是我们实现的这部分代码。

    2.2 异常向量表

    对于STM32,当某一个外设的中断发生时,CPU如何去调用相应外设的中断服务函数?这就需要引入异常向量表的概念了。STM32的中断向量表可以看成是一个指针数组,这个数组里面存放的就是一个个的中断服务函数的入口地址(向量表首地址规定是栈顶指针)。当CPU检查到某个中断产生时,硬件会根据我们提供的中断号自动跳转到向量表中与这个中断号对应的这个中断服务函数的入口地址,从而执行相应的中断服务函数。

    比如发生了Reset异常,那么CPU会从异常向量表的第1项找到Reset_Handler函数的地址,然后跳转到该函数执行;如果发生其他中断,CPU同样可以从表格里面找到对应的中断服务函数的地址,然后跳转到该函数执行。

    STM32F103的中断向量表如下所示:

    __Vectors       DCD     __initial_sp               ; Top of Stack
                    DCD     Reset_Handler              ; Reset Handler
                    DCD     NMI_Handler                ; NMI Handler
                    DCD     HardFault_Handler          ; Hard Fault Handler
                    DCD     MemManage_Handler          ; MPU Fault Handler
                    DCD     BusFault_Handler           ; Bus Fault Handler
                    DCD     UsageFault_Handler         ; Usage Fault Handler
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     SVC_Handler                ; SVCall Handler
                    DCD     DebugMon_Handler           ; Debug Monitor Handler
                    DCD     0                          ; Reserved
                    DCD     PendSV_Handler             ; PendSV Handler
                    DCD     SysTick_Handler            ; SysTick Handler
    
                    ; External Interrupts
                    DCD     WWDG_IRQHandler            ; Window Watchdog
                    DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                    DCD     TAMPER_IRQHandler          ; Tamper
                    DCD     RTC_IRQHandler             ; RTC
                    DCD     FLASH_IRQHandler           ; Flash
                    DCD     RCC_IRQHandler             ; RCC
                    DCD     EXTI0_IRQHandler           ; EXTI Line 0
                    DCD     EXTI1_IRQHandler           ; EXTI Line 1
                    DCD     EXTI2_IRQHandler           ; EXTI Line 2
                    DCD     EXTI3_IRQHandler           ; EXTI Line 3
                    DCD     EXTI4_IRQHandler           ; EXTI Line 4
                    DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                    DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                    DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                    DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                    DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                    DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                    DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                    DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2
                    DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                    DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                    DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                    DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                    DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                    DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                    DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                    DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                    DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                    DCD     TIM2_IRQHandler            ; TIM2
                    DCD     TIM3_IRQHandler            ; TIM3
                    DCD     TIM4_IRQHandler            ; TIM4
                    DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                    DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                    DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                    DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                    DCD     SPI1_IRQHandler            ; SPI1
                    DCD     SPI2_IRQHandler            ; SPI2
                    DCD     USART1_IRQHandler          ; USART1
                    DCD     USART2_IRQHandler          ; USART2
                    DCD     USART3_IRQHandler          ; USART3
                    DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                    DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                    DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
                    DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
                    DCD     TIM8_UP_IRQHandler         ; TIM8 Update
                    DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
                    DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
                    DCD     ADC3_IRQHandler            ; ADC3
                    DCD     FSMC_IRQHandler            ; FSMC
                    DCD     SDIO_IRQHandler            ; SDIO
                    DCD     TIM5_IRQHandler            ; TIM5
                    DCD     SPI3_IRQHandler            ; SPI3
                    DCD     UART4_IRQHandler           ; UART4
                    DCD     UART5_IRQHandler           ; UART5
                    DCD     TIM6_IRQHandler            ; TIM6
                    DCD     TIM7_IRQHandler            ; TIM7
                    DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
                    DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                    DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                    DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
    __Vectors_End
    

    一般来说向量表都会被链接到一个程序存储的最前面的位置的,对于STM32F103来说,程序运行和加载的起始地址都是0x08000000,所以STM32的异常向量表也会会被加载到0x08000000地址处的。

    对于ARM架构,规定向量表的基地址默认是0x00000000或0xFFFF0000位置的(对于STM32向量表的默认基地址就是0地址),而STM32向量表的基地址是被链接在了0x08000000的地址处,这样当中断发生时,不就跳转到了错误的函数入口地址了吗?为了解决这个问题,ARM允许可以修改异常向量表的基地址,这样就可以把异常向量表的基地址重新修改在内部Flash的起始地址0x08000000位置了。完成这一工作的是官方固件库的SystemInit函数,相关代码如下:

    #define FLASH_BASE       ((uint32_t)0x08000000) /*!< FLASH base address in the alias region */
    #define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */
    #define SCB              ((SCB_Type *)           SCB_BASE)         /* !< SCB configuration struct         */
    
    void SystemInit (void)
    {
        /****************此处省略部分代码****************/
    #ifdef VECT_TAB_SRAM
      SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;  /* Vector Table Relocation in Internal SRAM.  */
    #else
      SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
    #endif 
    }
    

    其中 SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; 这一行代码就是把异常向量表基地址更改到了0x08000000的地址中去了。

    补充:我曾自己写过简单的启动文件测试,并没有去调用SystemInit函数,自己也没有在其他地方对向量表的基地址更改到0x08000000的地址中去,但是当CPU检查到有中断发生时,还是可以跳转到正确的中断服务函数的入口地址处。为什么会这样?我查阅了下相关的资料,了解到当STM32从Flash启动时,实际上会把Flash的那段存储空间0x08000000 ~ 0x0807FFFF映射到0x00000000 ~ 0x0007FFFF这一段地址的存储空间,也就是说当CPU从Flash启动时,CPU从0地址处开始执行指令和从0x08000000地址处开始执行指令是一样的。所以,这个时候我没有去更改异常向量表的基地址,CPU仍然可以跳转到正确的中断服务程序。

    2.3 保存现场

    2.3.1 概念引入

    我们在Keil里面写一段非常简单的代码,实现 a = a + b; 这个式子。当然我们并不是要去关心这个式子本身,而是利用Keil的仿真功能,去查看一下CPU执行这个式子后,其内部寄存器的变化。仿真截图如下:
    在这里插入图片描述
    从上面这个仿真的汇编代码可以看出,CPU要完成 a = a + b; 的运算,实际上是先去读取a, b的内存所保存的数据到内部寄存器r0, r1中,然后再执行r0 = r0 + r1的运算,最后把r0的值写回到内存a中,这样才完成了一次a = a + b; 的运算。另外,可以观察到CPU在运行程序的过程中,它内部的r0 - r15,还有程序状态寄存器xPSR的值,都是在不断的变化中的。

    那么问题来了,假设CPU在运行 a = a + b; 这个式子的中途,程序运行过程被中断信号打断了。要想这个式子可以得到正确的结果,那么就要确保中断前CPU的这几个寄存器的值以及中断返回后这些寄存器的值都要保持不变,还有保存在内存空间a, b的值也不会被改变。这样运行这个式子得到的最终结果才是正确的。

    对于保持a, b内存的值不变,这个好办,中断程序中不要去改写a, b的值即可。但是我们如何保持中断前后CPU内部寄存器的值不被改变呢?因为中断程序的运行肯定也是需要用到CPU内部的寄存器的,所以必须得有一种机制去保持中断前后CPU内部寄存器的值不被改变。也就是说,所谓的现场,实际上就是CPU运行到某一时刻时,CPU内部寄存器的值

    那么如何保存现场和恢复现场呢?这就需要用到栈。CPU在跳转到异常/中断程序前,就需要把这些不希望被中断程序所改变的寄存器的值保存到栈中,这就是保存现场。在异常/中断处理完之后,从栈中恢复这些寄存器的值,这就是恢复现场

    2.3.2 保存哪些寄存器的值

    上面说了,所谓保存现场就是保存CPU内部一些寄存器的值到栈中。CPU内部常用的寄存器有 r0 ~ r15,再加上程序状态寄存器,一共16个(当然其他模式下可能还有对应的其他寄存器)。下图就是STM32F103内部寄存器示例(M3内核不具有浮点运算单元,这里不讨论浮点运算单元的寄存器了):
    在这里插入图片描述
    当发生异常/中断时,CPU跳转之前,就需要把这些寄存器的值保存到栈中,那么我们需要把CPU的这16个寄存器都保存到栈中吗?很显然是不需要的。

    ARM公司推出了一个ATPCS标准,即ARM-THUMB procedure call standard(ARM-Thumb过程调用标准)。在这份标准里面,都规定了这16个寄存器的使用规则,如下表所示:

    寄存器别名使用规则
    r15pc程序计数器
    r14lr连接寄存器
    r13sp数据栈指针
    r12ip子程序内部调用的scratch寄存器
    r11v8ARM状态局部变量寄存器8
    r10v7、s1ARM状态局部变量寄存器7、在支持数据栈检查的ATPCS中为数据栈限制指针
    r9v6、sbARM状态局部变量寄存器6、在支持RWPI的ATPCS中为静态基址寄存器
    r8v5ARM状态局部变量寄存器5
    r7v4、wrARM状态局部变量寄存器4、Thumb状态工作寄存器
    r6v3ARM状态局部变量寄存器3
    r5v2ARM状态局部变量寄存器2
    r4v1ARM状态局部变量寄存器1
    r3a4参数/结果/scratch 寄存器4
    r2a3参数/结果/scratch 寄存器3
    r1a2参数/结果/scratch 寄存器2
    r0a1参数/结果/scratch 寄存器1

    其中,r0 ~ r3是函数调用时用来传递参数或者保存函数返回值的,r4 ~ r11是用来保存局部变量的,r12 ~ r15是特殊功能寄存器。这些寄存器一般会被拆分成2部分:调用者保存的寄存器(r0-r3, r12, lr, psr)被调用者保存的寄存器(r4-r11)

    比如函数A调用函数B,那么函数A就是调用者,函数B就是被调用者。那么根据这份ATPCS规则,函数A在调用函数B之前,函数A就应该要保存r0-r3, r12, lr, psr这几个调用者要保存的寄存器;而对于r4-r11这几个寄存器,调用函数B的前后,函数B本身会保证调用前后这些寄存器的值保持不变。

    那么,如果函数B是中断服务函数,因为函数B本身会保证r4-r11的值不会被改变,所以保存现场也就是保存r0-r3, r12, lr, psr这几个寄存器的值即可。

    2.3.3 STM32如何保存现场

    我们已经知道了什么是现场,保存现场要保存哪些寄存器的值了。那么对于STM32来说,是如何保存这些寄存器的值到栈中的呢?

    非常幸运的是,STM32保存现场的工作是CPU的硬件自动帮我们完成的(我们不要想当然的认为所有架构的硬件都会帮我们完成这部分工作,对于Cortex-A7架构来说就不是硬件帮我们完成的),我们不需要自己写代码去把中断前需要保存的寄存器的值存放到栈中。具体过程如下图所示:
    在这里插入图片描述

    2.4 恢复现场

    恢复现场就是指CPU执行完异常/中断服务函数后,返回到LR寄存器所指示的地址处(就是中断前的下一条指令的地址),并且把保存在栈中寄存器的值恢复到寄存器中去。

    对于如何返回到中断前下一条指令的地址,其实很容易就可以实现,只要我们把下一条指令的地址存放到LR寄存器即可,CPU返回的话就是把LR寄存器的值赋值给PC程序计数器,这样就可以返回到了中断前下一条指令中继续运行程序了。但是如果这样做的话,硬件帮我们保存在栈中的寄存器的值,返回去是怎么恢复那些寄存器的值?

    对于这个问题,STM32帮我们实现了一套机制。CPU进入异常/中断服务程序时,LR寄存器保存的并不是中断前下一条指令的地址,而是会保存一个特殊的数值,被称为EXC_RETURN。对于EXC_RETURN位域的定义和具体的数值含义,可以查看《ARM Crotex-M3与Cortex-M4权威指南》一书中第八章的描述。这里截图如下作为参考:
    在这里插入图片描述
    所以,当异常/中断返回时,LR寄存器赋值给PC的值是一个被称为EXC_RETURN的值,而一旦CPU识别到PC的值等于EXC_RETURN的话,那么就会触发异常/中断返回机制,这个机制会帮我们把保存在栈中r0-r3, r12, lr, psr的寄存器的值恢复回去。

    展开全文
  • STM32-异常中断

    2020-10-10 19:07:19
    异常与我们所说的中断相似,但也有不同之处。 异常(内核中断外部中断 异常是CPU内部产生的中断,即在CPU执行特定指令的时候出现的非法情况,如除数为0等等,所以不可能在执行指令期间发生异常,只会在执行...

    在使用单片机的时候我们常用到的中断,但是但是我们常说的中断都是由(内核的)外部事件引起的、正常的紧急事件。而异常与我们所说的中断相似,但也有不同之处。

    异常(内核中断)和外部中断

    异常是CPU内部产生的中断,即在CPU执行特定指令的时候出现的非法情况,如除数为0等等,所以不可能在执行指令期间发生异常,只会在执行一条指令后有可能发生,所以也称同步中断。而中断则是一种异步的,它与特定的进程是无关的,又称为异步中断

    CM3 内核支持 256 个中断,其中包含了 16 个内核中断(主要用于系统异常)和 240 个外部中断,并且具有 3 个固定的高优先级和256级(8位)的可编程中断设置。因为芯片设计者可以修改 CM3 的硬件描述源代码,所以做成芯片后,支持的中断源数目常常不到 240 个,并且优先级的位数也由芯片厂商最终决定,实际上支持的优先级数会少于256级(8位),如 8 级(3位),16 级(4位),32(5位) 级等。需要注意的是CM3允许的最少使用位数为3个位,即至少支持8级优先级。

    STM32 有 84 个中断,包括 16 个内核中断和 68 个外部中断,具有 16 级(4位)可编程的中断优先级。而我们常用的就是这 68 个可屏蔽中断,但是 STM32 的 68 个可屏蔽中断,在 STM32F103 系列上面,又只有 60 个(在 107 系列才有 68 个)。

    内核中断

    内核中断如下图所示

    需要了解的是NMI,不可屏蔽中断。我们知道,对于可屏蔽中断,除了受本身的屏蔽位的控制外,还都要受一个总的控制,即CPU标志寄存器中的中断允许标志位IF(Interrupt Flag)的控制,IF位为1,可以得到CPU的响应,否则,得不到响应。对于不可屏蔽中断,CPU收到有效的NMI中断中断信号必须进行响应!不需要发出中断请求!不可屏蔽中断通常用于故障处理(如系统掉电等)。

    外部中断

    CM3内核的外部中断如下图所示,他们被芯片设计厂商定义为各种片上外设的中断请求接口。

    中断向量表

    当发生了异常并且要响应它时,CM3 需要定位其处理例程的入口地址。这些入口地址存储在所谓的“(异常)向量表”中。我们在启动文件中可以看到中断向量表,这里详细列举了该启动文件支持的所有中断,下面这个是STM32F103的启动文件。

    __Vectors       DCD     __initial_sp               ; Top of Stack
                    DCD     Reset_Handler              ; Reset Handler
                    DCD     NMI_Handler                ; NMI Handler
                    DCD     HardFault_Handler          ; Hard Fault Handler
                    DCD     MemManage_Handler          ; MPU Fault Handler
                    DCD     BusFault_Handler           ; Bus Fault Handler
                    DCD     UsageFault_Handler         ; Usage Fault Handler
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     0                          ; Reserved
                    DCD     SVC_Handler                ; SVCall Handler
                    DCD     DebugMon_Handler           ; Debug Monitor Handler
                    DCD     0                          ; Reserved
                    DCD     PendSV_Handler             ; PendSV Handler
                    DCD     SysTick_Handler            ; SysTick Handler
    
                    ; External Interrupts
                    DCD     WWDG_IRQHandler            ; Window Watchdog
                    DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                    DCD     TAMPER_IRQHandler          ; Tamper
                    DCD     RTC_IRQHandler             ; RTC
                    DCD     FLASH_IRQHandler           ; Flash
                    DCD     RCC_IRQHandler             ; RCC
                    DCD     EXTI0_IRQHandler           ; EXTI Line 0
                    DCD     EXTI1_IRQHandler           ; EXTI Line 1
                    DCD     EXTI2_IRQHandler           ; EXTI Line 2
                    DCD     EXTI3_IRQHandler           ; EXTI Line 3
                    DCD     EXTI4_IRQHandler           ; EXTI Line 4
                    DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                    DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                    DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                    DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                    DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                    DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                    DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                    DCD     ADC1_2_IRQHandler          ; ADC1_2
                    DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                    DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                    DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                    DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                    DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                    DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                    DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                    DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                    DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                    DCD     TIM2_IRQHandler            ; TIM2
                    DCD     TIM3_IRQHandler            ; TIM3
                    DCD     TIM4_IRQHandler            ; TIM4
                    DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                    DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                    DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                    DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                    DCD     SPI1_IRQHandler            ; SPI1
                    DCD     SPI2_IRQHandler            ; SPI2
                    DCD     USART1_IRQHandler          ; USART1
                    DCD     USART2_IRQHandler          ; USART2
                    DCD     USART3_IRQHandler          ; USART3
                    DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                    DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                    DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
    __Vectors_End

    优先级

    内核中断编号1-3为3 个系统异常:复位,NMI 以及硬 fault,它们是不可编程的有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常(优先级的数值越小,则优先级越高),所有其它异常的优先级则都是可编程的(优先级不能使负数)。

    CM3支持中断嵌套,NMI和外部中断优先级由NVIC中断管理器进行管理。我们知道STM32支持16级(4位)可编程优先级,与51单片机不同,这里的优先级包括了抢占优先级和响应优先级(或称亚优先级)。即抢占优先级和响应优先级共占4位,共同构成了16级(4位)优先级。根据抢占优先级和响应优先级分别占多少位,STM32 将中断分为 5 个组,组 0~4,对应关系如下:

    我们可以按照需求设置为2^{m}个抢占优先级,每个抢占优先级下又有2^{4-m}个响应优先级(0≤m≤4),抢占优先级的优先级比响应优先级的优先级高。抢占优先级决定了抢占行为:当系统正在响应某异常 L 时,如果来了抢占优先级更高的异常 H,则 H 可以抢占 L。响应优先级则处理“内务”:当抢占优先级相同的异常有不止一个悬起时(有的文章称“同时发生”,其实不然,因为不可能存在绝对的“同时”),就优先处理响应优先级最高的异常。

    什么是悬起?

    如果一个发生的异常不能被即刻响应,就称它被“悬起”(pending)。不过,少数 fault异常是不允许被悬起的。一个异常被悬起的原因,可能是系统当前正在执行一个更高优先级异常的服务例程,或者因相关掩蔽位的设置导致该异常被除能。对于每个异常源,在被悬起的情况下,都会有一个对应的“悬起状态寄存器”保存其异常请求,直到该异常能够执行为止,这与传统的 ARM 是完全不同的。在以前,是由产生中断的设备保持住请求信号。现在NVIC 的悬起状态寄存器的出现解决了这个问题,即使后来设备已经释放了请求信号,曾经的中断请求也不会错失。

     

     

     

    展开全文
  • STM32的"异常“、“中断“事件”区别理解

    千次阅读 多人点赞 2018-01-18 11:34:35
    1 异常中断(Cortex-M3)1.1 异常中断原话: Cortex‐M3 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。 其中,编号为 1-15 的对应系统异常,大于等于 16 的则全是外部中断。 ...
  • 目录一、Cortex-M3 处理器内核 vs 基于Cortex-M3的MCU一一、EXTI 简介一、外部中断/事件关系 一、Cortex-M3 处理器内核 vs 基于Cortex-M3的MCU Cortex-M3 处理器内核是由 ARM 公司设计的,传统意义上的 ARM7/ARM9...
  • 具体为在 STM32H743ZI 上,利用 DMA 自动实现 ADC 数据周期采集转移,在采集指定数量的采样值后产生中断,对数据进行处理。   文中仅对上述实现过程出现的一种异常,进行介绍分析。不涉及具体的 ADC ...
  • 1,意思是APB2接高速设备2、Stm32f10x.h相当于reg52.h(里面基本的位操作定义),另一个为stm32f10x_conf.h专门控制外围器件的配置,也就是开关头文件的作用3、HSE Osc(High Speed External Oscillator)高速外部晶振...
  • STM32中断和事件

    2020-08-23 10:52:35
    EXTI寄存器3.1 中断屏蔽寄存器 (EXTI_IMR)3.2 事件屏蔽寄存器 (EXTI_EMR)3.3 上升沿触发选择寄存器 (EXTI_RTSR)3.5 下降沿触发选择寄存器 (EXTI_FTSR)3.6 软件中断事件寄存器 (EXTI_SWIER)3.7 挂起寄存器 (EXTI_PR)...
  • STM32异常中断处理流程学习笔记

    千次阅读 2020-06-16 16:59:11
    STM32采用了4位,由中断优先级分组寄存器决定抢占优先级子优先级的位数。 处理器在运行一个中断处理时能否在响应另外一个中断,是由该中断的抢占优先级决定的,子优先级只会用在具有两个相同抢占优先级的异常...
  • STM32中断和异常

    千次阅读 2016-03-20 23:34:37
    外部中断主要指由外设产生的(如IO口,UART),异常主要是由系统产生的(如NMI,SYCTICK),外部中断也属于异常的一种,以下统称为异常 常用的操作异常的CMSIS函数,为了可移植性,建议使用这些函数操作异常异常...
  • 中断STM32里最重要的一环,可以说,如果学不会中断,你后期写的操作系统就是个废物,因为异常你根本无法处理,既然中断这么重要,那我们就先学习一下关于中断,都要什么寄存器。 目录一、中断和异常二、NVIC...
  • 1,意思是APB2接高速设备2、Stm32f10x.h相当于reg52.h(里面基本的位操作定义),另一个为stm32f10x_conf.h专门控制外围器件的配置,也就是开关头文件的作用3、HSE Osc(High Speed External Oscillator)高速外部晶振...
  • STM32中断原理

    2021-11-05 12:30:29
    目录 一、中断介绍 1.1 什么中断 1.2 中断的作用 1.3 中断的约束 二、STM32CubeMX中断方式点灯 ...1.介绍STM32中中断系统。 2.采用中断进行点灯实验。 3.采用串口中断方式实现串口通信。 ...
  • STM32 NVIC与中断控制

    2021-12-16 14:23:39
    STM32 NVIC与中断控制学习 NVIC全称向量中断控制器,NVIC 共支持 1 至 240 个外部中断输入(通常外部中断写作 IRQs)。NVIC 还支持一个 “永垂不朽”的不可屏蔽中断(NMI)输入。NVIC 的访问地址是 0xE000_E000。...
  • STM32中断优先级NVIC

    2021-12-03 10:23:02
    3、STM32有84个中断,包括了16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。 4、STM32F103系列上面,又只有60个可屏蔽中断(在107系列才68个) 5、中断管理方法:首先,对STM32中断进行分组,组0~4...
  • stm32中断详解

    2021-08-21 23:42:18
    当发生异常时,处理器暂停当前正在执行的任务,并执行程序称为异常处理程序的一部分。异常处理程序的执行完成后,处理器将恢复正常的程序执行。在ARM体系结构中断是一种异常类型。中断通常由外设或外部输
  • stm32 中断(f4)

    2022-02-28 22:25:19
    在学习 51 单片机时,我们就接触过中断中断其实就是当 CPU 执行程序时,由于发生了某种随机的事件(外部或内部),引起 CPU 暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以...
  • STM32】FreeRTOS中断配置

    千次阅读 2020-11-08 16:44:27
    00. 目录 文章目录00. 目录01. 概述02. 中断管理03. 优先级分组04. 优先级设置05. 特殊寄存器06. FreeRTOS中断配置宏07....Cortex-M3M4的NVIC最多支持240个IRQ中断请求,1个不可屏蔽中断NMI、1个Sy
  • STM32F103外部中断实现

    2021-10-13 19:43:44
    STM32系列单片机的中断主要由嵌套向量中断控制器来管理。   嵌套向量中断控制器特性如下: 68个可屏蔽中断通道(不包含16个Cortex™-M3的中断线); 16个可编程的优先等级(使用了4位中断优先级); 低延迟的异常和...
  • 本篇博文基于STM32F103ZET6芯片3.5.0标准库编写,从寄存器入手,最终实现编程的步骤。 一 基础知识 1. cortex-m3支持256个中断,其中包含了16个内核中断,240个外部中断。(本博文只介绍60个外部可屏蔽中断) 2....
  • 中断和异常
  • STM32F103】中断综述

    万次阅读 2019-01-19 21:26:21
     STM32中断很强大,每个外设都可以产生中断,F103在内核水平上搭载了异常响应系统,系统异常有8个(算上RESETHardFault也就10个),外部中断有60个,但是根据NVIC(嵌套向量中断控制器,控制整个芯片中断相关的...
  • STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程中断优先级。STM32F103 在内核水平上搭载了一个异常响应系统, 支持为数众多的系统异常和外部中断。其中系统异常有 8 个(如果把 Reset Hard...
  • STM32中断编程步骤

    千次阅读 2020-07-01 19:36:45
    介绍stm32f10x中断的概念,已经中断向量表,还有中断编程的一下要点,涉及的一下寄存器
  • Cotex-M3 的 NVIC 最多支持 240 个 IRQ(中断请求)、1 个不可屏蔽中断(NMI)、1 个 Systick(滴 答定时器)定时器中断和多个系统异常。 当多个中断来临的时候处理器应该响应哪一个中断是由中断的优先级来决定的,高...
  • STM32中断相关知识总结

    千次阅读 2020-10-07 21:58:00
    STM32中断相关知识总结 一:中断什么中断是指处理器运行过程,出现某些意外情况,CPU能自动停止正在运行的程序并转入处理新情况的...STM32F1系列 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断STM32F76
  • 学习stm32中断、DMA通信原理编程方法。使用stm32tubemxHAL库分别完成以下编程练习: 1. 用stm32F103核心板的GPIOA端一管脚接一个LED,GPIOB端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关...
  • 中断系统
  • stm32f103中断总结很详细

    千次阅读 2020-09-15 10:51:23
    一、NVIC 介绍 NVIC 英文全称是 Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它... (STM32中断系统学习资料) http://www.makeru.com.cn/live/1392_1124.html?s=45051  ST 公司的 STM

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,866
精华内容 1,146
关键字:

stn32 处理器中,中断和异常有什么不同

友情链接: FAT32.rar