• STM32中断相关概念阐述


    STM32中断相关概念阐述


    未完待续。。。

    想完整的写完并写清楚不容易,修修改改ing。。。


    注:本文以STM32F1系列为例,F1系列为Cortex M3内核。



    1、STM32 CM3 中断阐述

    ARM Cortex M3内核支持256个中断(16个内核中断+240个外部中断),与其相关的中断控制寄存器和中断优先级控制寄存器(NVIC、SYSTICK)也都属于Cortex M3内核的一部分。

    16分内部中断如下图:

    STM32使用了ARM Cortex M3内核并对其进行了裁减,使之在原本支持240个外部中断裁减变成了68个外部中断,外加内部的16个中断,一共16+68=84个中断。

    现在知道了STM32一共84个中断,那么在实际使用的时候怎么对它进行管理的呢?

    这就引入了中断优先级的概念。


    2、优先级的定义

    名词:NVIC(Nested vectored interrupt controller),嵌套向量中断控制器。

    • CM3内核使用NVIC来管理中断;
    • CM3中优先级的数值越小,优先级越高,支持256级中断(所以CM3配置中断优先级的寄存器是8bit的);
    • CM3 支持中断嵌套,使得高优先级异常会抢(preempt)低优先级异常。
    • CM3有3个系统异常:复位,NMI 以及硬 fault,它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其它异常。除了这三个,其它异常的优先级则都是可编程的(但不能编程为负数)。

    CM3最大支持到了256个等级的中断优先级但是实际上用不到这么多,所以大多数采用了M3内核的芯片会对其进行精简设计,ST就是裁掉了这个寄存器的低4bit,只用高4bit来表示优先级,以达到减少优先级数的目的,而4bit所能代表的最大数就是16,所以说STM32支持16级的可编程中断。

    CM3的240个外部中断都有自己的中断优先级配置寄存器PRI_n,这个寄存器是8位的,每4个相邻的中断优先级寄存器拼成一个32位的寄存器。这是NVIC的重要组成部分。

    而STM32只支持68个外部中断,在NVIC控制结构中虽然体现了240个,但是实际用不到这么多,如下图是STM32的NVIC控制结构(STM32裁掉了这个寄存器的低4bit,只用高4bit来表示优先级等级)。

    所以你可以看到在STM32标准库函数NVIC_Init函数内配置外设的优先级的时候,这里对优先级进行了左移4位的操作:


    3、中断优先级分组

    NVIC中有一个寄存器是“应用程序中断及复位控制寄存器“(AIRCR),它里面有一个位段名为“优先级组”。该位段的值对每一个优先级可配置的异常都有影响——把其优先级分为个位段: MSB 所在的位段(左边的)对应抢占优先级,而 LSB 所在的位段(右边的)
    对应亚优先级,如下图:

    SCB->AIRCR寄存器的[10:8]位是用来设置中断优先级分组的,通过这3位的配置,可以对IP(中断优先级)寄存器的[7:4]进行优先级的管理,例如:

    • 将AIRCR的10:8位写成101,那么IP寄存器的[7:4]这四个bit,[7:6]用来表示抢占优先级,[5:4]用来表示响应优先级。
    • 将AIRCR的10:8位写成011,那么IP寄存器的[7:4]这四个bit都用来表示抢占优先级,无响应优先级,4bit做能代表的范围是0~15,所以优先级的设置就是0-15级,这个分组模式通常用于RTOS,例如FreeRTOS。

    4、特殊寄存器(PRIMASK、FAULTMASK、BASEPRI)开关中断设置

    这三个寄存器用来开关中断用,只能在特权模式下进行访问,不过CMSIS提供了函数能够在C环境中进行调用。这三个寄存器描述如表(摘自CM3权威指南):

    • PRIMASK(优先级屏蔽寄存器)
      这个寄存器只有1bit,如果设置为1,除了NMI和Hard Fault中断被允许外,其他中断全部被屏蔽,默认为0;
      CMSIS提供的C环境中操作该寄存器:

      __set_PRIMASK(1);  /* 屏蔽中断 */
      __set_PRIMASK(0);  /* 取消屏蔽 */`
      
      • 1
      • 2
    • FAULTMASK(断层屏蔽寄存器)
      这个寄存器也是只有1bit,如果设置为1,除了NMI中断被允许,其他全部中断包括Hard Fault中断也被屏蔽,默认为0;
      CMSIS提供的C环境中操作该寄存器:

      __set_FAULTMASK(1);  /* 屏蔽中断 */`
      __set_FAULTMASK(0);  /* 取消屏蔽 */
      
      • 1
      • 2
    • BASEPRI(基本优先级屏蔽寄存器):这个寄存器能够提供更精细化的中断屏蔽,往这个寄存器里写一个值,可以屏蔽比该优先级值低的中断,在CM3中,这个寄存器只用到了[7:4]这四个位,这与IP寄存器是一致的;(下图摘自PM0056-STM32编程手册)
      CMSIS提供的C环境接口如下:

      	__set_BASEPRI(0x50);   /* 屏蔽优先级小于5的中断 */
      	__get_BASEPRI();       /* 获取当前屏蔽的优先级等级 */
      
      • 1
      • 2

      FreeRTOS就是使用了该寄存器来管理中断,屏蔽相应的中断进行临界区资源保护,而不是关全部中断。

    补充①:除了使用以上寄存器开关中断,CMSIS还提供了另外的开关中断的接口:

    __enable_irq();    /* 关全部中断,操作的是PRIMASK */
    __disable_irq();   /* 开全部中断,操作的是PRIMASK*/
    __enable_frq();    /* 关全部中断,操作的是FAULTMASK */
    __disable_frq();   /* 开全部中断,操作的是FAULTMASK*/
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    补充②:ARM的汇编指令CPS,全称Change Processor State,改变处理器状态。

    IE:Interrupt or abort enable. 中断使能

    ID: Interrupt or abort disable. 关闭中断

    利用该指令来快速开关中断:

    cpsid i,关闭中断,实际操作的是PRIMASK

    cpsie i,开启中断,实际操作的是PRIMASK

    cpsid f,关闭中断,实际操作的是FAULTMASK

    cpsie f,开启中断,实际操作的是FAULTMASK

  • 相关阅读:
    【深度学习】YOLO-Pose 人体关键点估计 人体姿态估计
    MySQL高级语句(二)
    webpack高级配置
    Golang专题——fsnotify 文件及目录监控
    低代码开发的兴衰
    Vue原理篇——响应式实现(双向数据绑定)
    Python学习记录
    JAVA学习第2步——项目创建和导包
    leetcode-23.合并K个升序链表
    1.Window10 JDK8安装与配置(更新版)
  • 原文地址:https://blog.csdn.net/qq153471503/article/details/126177103