• 中断属于一种异常
    • 有各种各样的中断,中断一般来说是由硬件产生的,中断的来源有多种多样
    • 中断路径上的3个部件:
      • 中断源 : 中断源多种多样,比如GPIO、定时器、UART、DMA等等。它们都有自己的寄存器,可以进行相关设置:使能中断、中断状态、中断类型等等。
      • 中断控制器 : 各种中断源发出的中断信号,汇聚到中断控制器。可以在中断控制器中设置各个中断的优先级。中断控制器会向CPU发出中断信号,CPU可以读取中断控制器的寄存器,判断当前处理的是哪个中断。中断控制器有多种实现,比如:
        • STM32F103中被称为NVIC:Nested vectored interrupt controller(嵌套向量中断控制器)
        • ARM9中一般是芯片厂家自己实现的,没有统一标准
        • Cortex A7中使用GIC(Generic Interrupt Controller)
      • CPU : CPU每执行完一条指令,都会判断一下是否有中断发生了。CPU也有自己的寄存器,可以设置它来使能/禁止中断,这是中断处理的总开关。
    • image.png
    • 中断先汇聚到中断控制器中,再由中断控制器给CPU发信号
    • CPU检测到中断发生后,可以去读取中断控制器来判断是哪个中断
    • 不管是哪个芯片,中断路径上的3个部件都是一样的;它会根据不同的芯片演变处不同的硬件结构
      • image.png
    • GIC功能强大,除了管理中断源外,还可以决定把哪个中断发给哪个CPU
      • image.png
    • 对于STM32的芯片(MP157/F103),Pn[x]同一时间只能设置一个中断(N组GPIO的同标号引脚每次只能有一个起效)
      • image.png
      • EXTI0只能从PA0、……、PG0中选择一个,这也意味着PA0、……、PG0中只有一个引脚可以用于中断。这跟其他芯片不一样,很多芯片的任一GPIO引脚都可以同时用于中断
    • STM32芯片(MP157/F103)在外部中断控制器EXTI设置中断的触发方式:高电平触发、低电平触发、上升沿触发、下降沿触发等
      • image.png
      • 要设置:
        • Falling trigger selection register:是否选择下降沿触发
        • Rising trigger selection register:是否选择上升沿触发
        • Interrupt mask register:是否屏蔽中断
      • 虽然选择了某个引脚让其发出中断,但这个中断能不能被后一级的中断控制器处理,还需要设置中断屏蔽寄存器屏蔽/使能中断
      • 当发生中断时,可以读取下列寄存器判断是否发生了中断、发生了哪个中断:
        • Pending reqeust register
        • 处理完中断后,还得设置、清除该寄存器
    • NVIC要做什么事呢?
      • NVIC中断控制器,其中断来源多种多样;NVIC要挑出其中优先级最高的中断,用它来向CPU发出中断信号
    • 多个中断源汇聚到NVIC,NVIC的职责就是从多个中断源中取出优先级最高的中断,向CPU发出中断信号。处理中断时,程序可以写NVIC的寄存器,清除中断。
    • image.png
      • 这些寄存器的每一bit对应一个中断
      • 如: ISER0中的bit0对应异常向量表中的第16项(向量表从第0项开始)
      • image.png
    • 中断从NVIC到达CPU后就能处理了吗?
      • 并不是的,cortex M3/M4处理器内部有这几个寄存器:PRIMASK、FAULTMASK、BASEPRI
      • 设置PRIMASK的bit0设为0时CPU才能最终对中断进行处理
      • image.png
        • 把PRIMASK的bit0设置为1,就可以屏蔽所有优先级可配置的中断 ```c CPSIE I ; 清除PRIMASK,使能中断 CPSID I ; 设置PRIMASK,禁止中断

    或者: MOV R0, #1 MSR PRIMASK R0 ; 将1写入PRIMASK禁止所有中断

    MOV R0, #0 MSR PRIMASK, R0 ; 将0写入PRIMASK使能所有中断 ```

    • STM32MP157和STM32F103都是ST公司的产品,它们的中断处理硬件结构都是类似的;它们的差别在于157的中断控制器是GIC,103的中断控制器是NVIC
    • MP157中,GPIO控制器就跟中断没有什么关系了,里面没有相关的寄存器;这意味着某个引脚能否发出中断、在什么情况下发出中断完全由外部中断控制器EXTI来设置
    • image.png
    • 157的外部中断控制器EXTI中有某些寄存器可以设置选择外部中断
      • 通过EXTI_EXTICR1等寄存器来设置EXTIx的中断源是哪个GPIO引脚
      • image.png
    • 通过EXTI事件触发寄存器(EXTI_RTSR1上升沿、EXTI_FTSR1下降沿等)选择中断源的触发方式
      • image.png
    • 通过EXTI的masking寄存器来设置是否允许某个EXTI中断
    • 发生中断后可以去查看EXTI的中断状态寄存器查看中断状态,处理完中断后还需要清除这些状态
      • image.png
    • 中断进入GIC后,GIC的处理过程应该是跟NVIC类似的

      ARM体系结构定义了通用中断控制器(GIC),该控制器包括一组用于管理单核或多核系统中的中断的硬件资源。GIC提供了内存映射寄存器,可用于管理中断源和行为,以及(在多核系统中)用于将中断路由到各个CPU核。它使软件能够屏蔽,启用和禁用来自各个中断源的中断,以(在硬件中)对各个中断源进行优先级排序和生成软件触发中断。它还提供对TrustZone安全性扩展的支持。GIC接受系统级别中断的产生,并可以发信号通知给它所连接的每个内核,从而有可能导致IRQ或FIQ异常发生。

    • MP157的CPU是通过CPSR状态寄存器的相关位来使能中断;这点和F103不同(103通过一个寄存器PRIMASK来使能/禁止某个优先级以下的中断)

    • IMX6ULL的GPIO中断在硬件上的框架,跟STM32MP157是类似的。IMX6ULL中没有EXTI控制器,对GPIO的中断配置、控制,都在GPIO模块内部实现
    • 6ULL可以直接在GPIO控制器中设置引脚发出中断
      • 每组GPIO中都有对应的GPIOx_ICR1、GPIOx_ICR2寄存器(interrupt configuration register )。每个引脚都可以配置为中断引脚,并配置它的触发方式
      • image.png
    • 6ULL中对于每一个GPIO引脚,都可以发出中断,也都可以设置是否屏蔽/使能
      • image.png
    • 同样6ULL可以读取中断状态