STM32中断系统回顾

  1. 中断向量表
  2. NVIC(内嵌向量中断控制器)
  3. 中断使能
  4. 中断服务函数

中断向量表

中断向量表是一个表,表里面存放的是中断向量。
中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量,因此中断向量表是一系列中断服务程序入口地址组成的表。
中断服务程序在中断向量表中的位置是由半导体厂商定好的,当某个中断被触发以后就会自动跳转到中断向量表中对应的中断服务程序入口地址处。

中断向量表在整个程序的最前面,如STM32F103 的中断向量表如下所示:

__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     SysTick_Handler            ; SysTick Handler; External InterruptsDCD     WWDG_IRQHandler            ; Window WatchdogDCD     PVD_IRQHandler             ; PVD through EXTI Line detectDCD     TAMPER_IRQHandler          ; TamperDCD     RTC_IRQHandler             ; RTCDCD     FLASH_IRQHandler           ; FlashDCD     RCC_IRQHandler             ; RCCDCD     EXTI0_IRQHandler           ; EXTI Line 0DCD     EXTI1_IRQHandler           ; EXTI Line 1DCD     EXTI2_IRQHandler           ; EXTI Line 2DCD     EXTI3_IRQHandler           ; EXTI Line 3DCD     EXTI4_IRQHandler           ; EXTI Line 4DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TXDCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1DCD     CAN1_SCE_IRQHandler        ; CAN1 SCEDCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5DCD     TIM1_BRK_IRQHandler        ; TIM1 BreakDCD     TIM1_UP_IRQHandler         ; TIM1 UpdateDCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and CommutationDCD     TIM1_CC_IRQHandler         ; TIM1 Capture CompareDCD     TIM2_IRQHandler            ; TIM2DCD     TIM3_IRQHandler            ; TIM3DCD     TIM4_IRQHandler            ; TIM4DCD     I2C1_EV_IRQHandler         ; I2C1 EventDCD     I2C1_ER_IRQHandler         ; I2C1 ErrorDCD     I2C2_EV_IRQHandler         ; I2C2 EventDCD     I2C2_ER_IRQHandler         ; I2C2 ErrorDCD     SPI1_IRQHandler            ; SPI1DCD     SPI2_IRQHandler            ; SPI2DCD     USART1_IRQHandler          ; USART1DCD     USART2_IRQHandler          ; USART2DCD     USART3_IRQHandler          ; USART3DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10DCD     RTC_Alarm_IRQHandler        ; RTC Alarm through EXTI LineDCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspendDCD     TIM8_BRK_IRQHandler        ; TIM8 BreakDCD     TIM8_UP_IRQHandler         ; TIM8 UpdateDCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and CommutationDCD     TIM8_CC_IRQHandler         ; TIM8 Capture CompareDCD     ADC3_IRQHandler            ; ADC3DCD     FSMC_IRQHandler            ; FSMCDCD     SDIO_IRQHandler            ; SDIODCD     TIM5_IRQHandler            ; TIM5DCD     SPI3_IRQHandler            ; SPI3DCD     UART4_IRQHandler           ; UART4DCD     UART5_IRQHandler           ; UART5DCD     TIM6_IRQHandler            ; TIM6DCD     TIM7_IRQHandler            ; TIM7DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End

中断向量表都是链接到代码的最前面,比如一般ARM处理器都是从地址0x00000000开始执行指令的,那么中断向量表就是从0x00000000开始存放的。

__initial_sp就是第一条中断向量,存放的是栈顶指针,接下来是第2行复位中断服务函数Reset_Handler的入口地址,最后一行是中断服务函数DMA2_Channel4_5_IRQHandler的入口地址,这样STM32F103的中断向量表就建好了。

虽然ARM处理器都是从地址0x00000000开始运行的,但是我们学习STM32的时候代码是下载到0x8000000开始的存储区域中,因此中断向量表存放到了0x8000000地址处。

因此,Cortex-M架构引入了中断向量表偏移,通过中断向量表偏移就可以将中断向量表存放到任意地址处。

#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif

中断向量表偏移配置在函数SystemInit中完成,通过SCB->VTOR寄存器写入新的中断向量表首地址即可。

#define FLASH_BASE            0x08000000UL
#define VECT_TAB_OFFSET       0x0

基本都是将中断向量表设置到ROM中,也就是地址0x8000000处。

NVIC(内嵌向量中断控制器)

  • Cortex-M内核有中断系统的管理机构-NVIC
  • Cortex-A7内核的中断管理机构——GIC:general interrupt controller

中断使能

要使用某个外设的中断,肯定要先使能这个外设的中断,以STM32F103的PE2这个IO为例,假如我们要使用PE2的输入中断肯定要使用如下代码来使能对应的中断。使能PE2对应的EXTI2中断。

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);

中断服务函数

我们使用中断的目的就是为了使用中断服务函数,当中断发生以后中断服务函数就会被调用,我们要处理的工作就可以放到中断服务函数中去完成。同样以 STM32F103 的 PE2 为例,其中断服务函数如下所示:

void EXTI2_IRQHandler(void)
{/* 中断处理代码 */
}

当 PE2 引脚的中断触发以后就会调用其对应的中断处理函数 EXTI2_IRQHandler,我们可以在函数 EXTI2_IRQHandler 中添加中断处理代码。同理,I.MX6U 也有中断服务函数,当某个外设中断发生以后就会调用其对应的中断服务函数。

Cortex-A7中断系统简介

Cortex-A7的中断向量表也在代码的最前面,其内核有8个异常中断。

  1. 复位中断(Reset),CPU复位后就会进入复位中断,我们可以在复位中断服务函数里面做一些初始化工作,比如初始化SP指针,DDR等。
  2. 未定义指令中断(Undefined Instuction),如果指令不能识别的话就会产生此中断。
  3. 软中断(Software Interrupt,SWI),由SWI指令引起的中断,Linux的系统调用会用SWI指令来引起软中断,通过软中断来陷入到内核空间。
  4. 指令预取中止中断(Prefetch Abort),预取指令出错的时候会产生此中断。
  5. 数据访问中止中断(Data Abort),访问数据出错的时候会产生此中断。
  6. IRQ中断:芯片外设中断都会引起此中断发生。
  7. FIQ中断:如果需要快速处理中断的话就可以使用此中断。

Cortex-A内核CPU的所有外部中断都属于这个IRQ中断,当任意一个外部中断发生的时候都会触发IRQ中断。在IRQ中断服务函数里面就可以读取指定的寄存器来判断发生的具体是什么中断,进而根据具体的中断做出
相应的处理。

.global _start_start:ldr pc, =Reset_Handler     /* 复位中断                     */  ldr pc, =Undefined_Handler /* 未定义中断                    */ldr pc, =SVC_Handler     /* SVC(Supervisor)中断        */ldr pc, =PrefAbort_Handler   /* 预取终止中断                   */ldr pc, =DataAbort_Handler   /* 数据终止中断                   */ldr   pc, =NotUsed_Handler   /* 未使用中断                    */ldr pc, =IRQ_Handler     /* IRQ中断                    */ldr pc, =FIQ_Handler     /* FIQ(快速中断)未定义中断           */

GIC控制器简介

STM32(Cortex-M)的中断控制器叫做NVIC,I.MX6U(Cortex-A)的中断控制器叫做GIC。

GIC 是 ARM 公司给 Cortex-A/R 内核提供的一个中断控制器,类似 Cortex-M 内核中的NVIC。目前 GIC 有 4 个版本:V1~V4,V1 是最老的版本,已经被废弃了。V2~V4 目前正在大量的使用。GIC V2 是给 ARMv7-A 架构使用的,比如 Cortex-A7、Cortex-A9、Cortex-A15 等,V3 和 V4 是给 ARMv8-A/R 架构使用的,也就是 64 位芯片使用的。I.MX6U 是Cortex-A 内核的,因此我们主要讲解 GIC V2。GIC V2 最多支持 8 个核。


当GIC接收到外部中断信号以后就会报给ARM内核,但是ARM内核只提供了4个信号给GIC来汇报中断情况:VFIQ、VIRQ、FIQ和IRQ。

GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号
报给 ARM 内核,这四个信号的含义如下:

  • VFIQ:虚拟快速 FIQ。
  • VIRQ:虚拟外部 IRQ。
  • FIQ:快速中断 IRQ。
  • IRQ:外部中断 IRQ。


左侧部分就是中断源,中间部分就是GIC控制器,最右侧就是中断控制器向处理器内核发送中断信息。

GIC将总多的中断源分为三类:

  1. SPI(Shared Peripheral Interrupt),共享中断,所有Core共享的中断,所有外部中断都属于SPI中断。比如按键中断、串口中断等等,这些中断所有的 Core 都可以处理,不限定特定 Core。
  2. PPI(Private Peripheral Interrupt),私有中断, GIC 是支持多核的,每个核肯定有自己独有的中断。这些独有的中断肯定是要指定的核心处理,因此这些中断就叫做私有中断。
  3. SGI(Software-generated Interrupt),软件中断,由软件触发引起的中断,通过向寄存器GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。

中断ID

中断源很多,为了区分这些不同的中断源肯定要给他们分配一个唯一的ID,这些ID就是中断ID。每一个 CPU 最多支持 1020 个中断 ID,中断 ID 号为 ID0~ID1019。这 1020 个 ID 包含了 PPI、SPI 和 SGI。

  1. ID0~ID15:这 16 个 ID 分配给 SGI。
  2. ID16~ID31:这 16 个 ID 分配给 PPI。
  3. ID32~ID1019:这 988 个 ID 分配给 SPI,像 GPIO 中断、串口中断等这些外部中断。

I.MX6U 的总共使用了 128 个中断 ID,加上前面属于 PPI 和 SGI 的 32 个 ID,I.MX6U 的中断源共有 128+32=160个。

在MCIMX6Y2C.h中,定义了一个枚举类型IRQn_Type

typedef enum IRQn {/* Auxiliary constants */NotAvail_IRQn                = -128,             /**< Not available device specific interrupt *//* Core interrupts */Software0_IRQn               = 0,                /**< Cortex-A7 Software Generated Interrupt 0 */Software1_IRQn               = 1,                /**< Cortex-A7 Software Generated Interrupt 1 */Software2_IRQn               = 2,                /**< Cortex-A7 Software Generated Interrupt 2 */Software3_IRQn               = 3,                /**< Cortex-A7 Software Generated Interrupt 3 */Software4_IRQn               = 4,                /**< Cortex-A7 Software Generated Interrupt 4 */Software5_IRQn               = 5,                /**< Cortex-A7 Software Generated Interrupt 5 */Software6_IRQn               = 6,                /**< Cortex-A7 Software Generated Interrupt 6 */Software7_IRQn               = 7,                /**< Cortex-A7 Software Generated Interrupt 7 */Software8_IRQn               = 8,                /**< Cortex-A7 Software Generated Interrupt 8 */Software9_IRQn               = 9,                /**< Cortex-A7 Software Generated Interrupt 9 */Software10_IRQn              = 10,               /**< Cortex-A7 Software Generated Interrupt 10 */Software11_IRQn              = 11,               /**< Cortex-A7 Software Generated Interrupt 11 */Software12_IRQn              = 12,               /**< Cortex-A7 Software Generated Interrupt 12 */Software13_IRQn              = 13,               /**< Cortex-A7 Software Generated Interrupt 13 */Software14_IRQn              = 14,               /**< Cortex-A7 Software Generated Interrupt 14 */Software15_IRQn              = 15,               /**< Cortex-A7 Software Generated Interrupt 15 */VirtualMaintenance_IRQn      = 25,               /**< Cortex-A7 Virtual Maintenance Interrupt */HypervisorTimer_IRQn         = 26,               /**< Cortex-A7 Hypervisor Timer Interrupt */VirtualTimer_IRQn            = 27,               /**< Cortex-A7 Virtual Timer Interrupt */LegacyFastInt_IRQn           = 28,               /**< Cortex-A7 Legacy nFIQ signal Interrupt */SecurePhyTimer_IRQn          = 29,               /**< Cortex-A7 Secure Physical Timer Interrupt */NonSecurePhyTimer_IRQn       = 30,               /**< Cortex-A7 Non-secure Physical Timer Interrupt */LegacyIRQ_IRQn               = 31,               /**< Cortex-A7 Legacy nIRQ Interrupt *//* Device specific interrupts */IOMUXC_IRQn                  = 32,               /**< General Purpose Register 1 from IOMUXC. Used to notify cores on exception condition while boot. */DAP_IRQn                     = 33,               /**< Debug Access Port interrupt request. */SDMA_IRQn                    = 34,               /**< SDMA interrupt request from all channels. */TSC_IRQn                     = 35,               /**< TSC interrupt. */SNVS_IRQn                    = 36,               /**< Logic OR of SNVS_LP and SNVS_HP interrupts. */LCDIF_IRQn                   = 37,               /**< LCDIF sync interrupt. */RNGB_IRQn                    = 38,               /**< RNGB interrupt. */CSI_IRQn                     = 39,               /**< CMOS Sensor Interface interrupt request. */PXP_IRQ0_IRQn                = 40,               /**< PXP interrupt pxp_irq_0. */SCTR_IRQ0_IRQn               = 41,               /**< SCTR compare interrupt ipi_int[0]. */SCTR_IRQ1_IRQn               = 42,               /**< SCTR compare interrupt ipi_int[1]. */WDOG3_IRQn                   = 43,               /**< WDOG3 timer reset interrupt request. */Reserved44_IRQn              = 44,               /**< Reserved */APBH_IRQn                    = 45,               /**< DMA Logical OR of APBH DMA channels 0-3 completion and error interrupts. */WEIM_IRQn                    = 46,               /**< WEIM interrupt request. */RAWNAND_BCH_IRQn             = 47,               /**< BCH operation complete interrupt. */RAWNAND_GPMI_IRQn            = 48,               /**< GPMI operation timeout error interrupt. */UART6_IRQn                   = 49,               /**< UART6 interrupt request. */PXP_IRQ1_IRQn                = 50,               /**< PXP interrupt pxp_irq_1. */SNVS_Consolidated_IRQn       = 51,               /**< SNVS consolidated interrupt. */SNVS_Security_IRQn           = 52,               /**< SNVS security interrupt. */CSU_IRQn                     = 53,               /**< CSU interrupt request 1. Indicates to the processor that one or more alarm inputs were asserted. */USDHC1_IRQn                  = 54,               /**< USDHC1 (Enhanced SDHC) interrupt request. */USDHC2_IRQn                  = 55,               /**< USDHC2 (Enhanced SDHC) interrupt request. */SAI3_RX_IRQn                 = 56,               /**< SAI3 interrupt ipi_int_sai_rx. */SAI3_TX_IRQn                 = 57,               /**< SAI3 interrupt ipi_int_sai_tx. */UART1_IRQn                   = 58,               /**< UART1 interrupt request. */UART2_IRQn                   = 59,               /**< UART2 interrupt request. */UART3_IRQn                   = 60,               /**< UART3 interrupt request. */UART4_IRQn                   = 61,               /**< UART4 interrupt request. */UART5_IRQn                   = 62,               /**< UART5 interrupt request. */eCSPI1_IRQn                  = 63,               /**< eCSPI1 interrupt request. */eCSPI2_IRQn                  = 64,               /**< eCSPI2 interrupt request. */eCSPI3_IRQn                  = 65,               /**< eCSPI3 interrupt request. */eCSPI4_IRQn                  = 66,               /**< eCSPI4 interrupt request. */I2C4_IRQn                    = 67,               /**< I2C4 interrupt request. */I2C1_IRQn                    = 68,               /**< I2C1 interrupt request. */I2C2_IRQn                    = 69,               /**< I2C2 interrupt request. */I2C3_IRQn                    = 70,               /**< I2C3 interrupt request. */UART7_IRQn                   = 71,               /**< UART-7 ORed interrupt. */UART8_IRQn                   = 72,               /**< UART-8 ORed interrupt. */Reserved73_IRQn              = 73,               /**< Reserved */USB_OTG2_IRQn                = 74,               /**< USBO2 USB OTG2 */USB_OTG1_IRQn                = 75,               /**< USBO2 USB OTG1 */USB_PHY1_IRQn                = 76,               /**< UTMI0 interrupt request. */USB_PHY2_IRQn                = 77,               /**< UTMI1 interrupt request. */DCP_IRQ_IRQn                 = 78,               /**< DCP interrupt request dcp_irq. */DCP_VMI_IRQ_IRQn             = 79,               /**< DCP interrupt request dcp_vmi_irq. */DCP_SEC_IRQ_IRQn             = 80,               /**< DCP interrupt request secure_irq. */TEMPMON_IRQn                 = 81,               /**< Temperature Monitor Temperature Sensor (temperature greater than threshold) interrupt request. */ASRC_IRQn                    = 82,               /**< ASRC interrupt request. */ESAI_IRQn                    = 83,               /**< ESAI interrupt request. */SPDIF_IRQn                   = 84,               /**< SPDIF interrupt. */Reserved85_IRQn              = 85,               /**< Reserved */PMU_IRQ1_IRQn                = 86,               /**< Brown-out event on either the 1.1, 2.5 or 3.0 regulators. */GPT1_IRQn                    = 87,               /**< Logical OR of GPT1 rollover interrupt line, input capture 1 and 2 lines, output compare 1, 2, and 3 interrupt lines. */EPIT1_IRQn                   = 88,               /**< EPIT1 output compare interrupt. */EPIT2_IRQn                   = 89,               /**< EPIT2 output compare interrupt. */GPIO1_INT7_IRQn              = 90,               /**< INT7 interrupt request. */GPIO1_INT6_IRQn              = 91,               /**< INT6 interrupt request. */GPIO1_INT5_IRQn              = 92,               /**< INT5 interrupt request. */GPIO1_INT4_IRQn              = 93,               /**< INT4 interrupt request. */GPIO1_INT3_IRQn              = 94,               /**< INT3 interrupt request. */GPIO1_INT2_IRQn              = 95,               /**< INT2 interrupt request. */GPIO1_INT1_IRQn              = 96,               /**< INT1 interrupt request. */GPIO1_INT0_IRQn              = 97,               /**< INT0 interrupt request. */GPIO1_Combined_0_15_IRQn     = 98,               /**< Combined interrupt indication for GPIO1 signals 0 - 15. */GPIO1_Combined_16_31_IRQn    = 99,               /**< Combined interrupt indication for GPIO1 signals 16 - 31. */GPIO2_Combined_0_15_IRQn     = 100,              /**< Combined interrupt indication for GPIO2 signals 0 - 15. */GPIO2_Combined_16_31_IRQn    = 101,              /**< Combined interrupt indication for GPIO2 signals 16 - 31. */GPIO3_Combined_0_15_IRQn     = 102,              /**< Combined interrupt indication for GPIO3 signals 0 - 15. */GPIO3_Combined_16_31_IRQn    = 103,              /**< Combined interrupt indication for GPIO3 signals 16 - 31. */GPIO4_Combined_0_15_IRQn     = 104,              /**< Combined interrupt indication for GPIO4 signals 0 - 15. */GPIO4_Combined_16_31_IRQn    = 105,              /**< Combined interrupt indication for GPIO4 signals 16 - 31. */GPIO5_Combined_0_15_IRQn     = 106,              /**< Combined interrupt indication for GPIO5 signals 0 - 15. */GPIO5_Combined_16_31_IRQn    = 107,              /**< Combined interrupt indication for GPIO5 signals 16 - 31. */Reserved108_IRQn             = 108,              /**< Reserved */Reserved109_IRQn             = 109,              /**< Reserved */Reserved110_IRQn             = 110,              /**< Reserved */Reserved111_IRQn             = 111,              /**< Reserved */WDOG1_IRQn                   = 112,              /**< WDOG1 timer reset interrupt request. */WDOG2_IRQn                   = 113,              /**< WDOG2 timer reset interrupt request. */KPP_IRQn                     = 114,              /**< Key Pad interrupt request. */PWM1_IRQn                    = 115,              /**< hasRegInstance(`PWM1`)?`Cumulative interrupt line for PWM1. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.`:`Reserved`) */PWM2_IRQn                    = 116,              /**< hasRegInstance(`PWM2`)?`Cumulative interrupt line for PWM2. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.`:`Reserved`) */PWM3_IRQn                    = 117,              /**< hasRegInstance(`PWM3`)?`Cumulative interrupt line for PWM3. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.`:`Reserved`) */PWM4_IRQn                    = 118,              /**< hasRegInstance(`PWM4`)?`Cumulative interrupt line for PWM4. Logical OR of rollover, compare, and FIFO waterlevel crossing interrupts.`:`Reserved`) */CCM_IRQ1_IRQn                = 119,              /**< CCM interrupt request ipi_int_1. */CCM_IRQ2_IRQn                = 120,              /**< CCM interrupt request ipi_int_2. */GPC_IRQn                     = 121,              /**< GPC interrupt request 1. */Reserved122_IRQn             = 122,              /**< Reserved */SRC_IRQn                     = 123,              /**< SRC interrupt request src_ipi_int_1. */Reserved124_IRQn             = 124,              /**< Reserved */Reserved125_IRQn             = 125,              /**< Reserved */CPU_PerformanceUnit_IRQn     = 126,              /**< Performance Unit interrupt ~ipi_pmu_irq_b. */CPU_CTI_Trigger_IRQn         = 127,              /**< CTI trigger outputs interrupt ~ipi_cti_irq_b. */SRC_Combined_IRQn            = 128,              /**< Combined CPU wdog interrupts (4x) out of SRC. */SAI1_IRQn                    = 129,              /**< SAI1 interrupt request. */SAI2_IRQn                    = 130,              /**< SAI2 interrupt request. */Reserved131_IRQn             = 131,              /**< Reserved */ADC1_IRQn                    = 132,              /**< ADC1 interrupt request. */ADC_5HC_IRQn                 = 133,              /**< ADC_5HC interrupt request. */Reserved134_IRQn             = 134,              /**< Reserved */Reserved135_IRQn             = 135,              /**< Reserved */SJC_IRQn                     = 136,              /**< SJC interrupt from General Purpose register. */CAAM_Job_Ring0_IRQn          = 137,              /**< CAAM job ring 0 interrupt ipi_caam_irq0. */CAAM_Job_Ring1_IRQn          = 138,              /**< CAAM job ring 1 interrupt ipi_caam_irq1. */QSPI_IRQn                    = 139,              /**< QSPI1 interrupt request ipi_int_ored. */TZASC_IRQn                   = 140,              /**< TZASC (PL380) interrupt request. */GPT2_IRQn                    = 141,              /**< Logical OR of GPT2 rollover interrupt line, input capture 1 and 2 lines, output compare 1, 2 and 3 interrupt lines. */CAN1_IRQn                    = 142,              /**< Combined interrupt of ini_int_busoff,ini_int_error,ipi_int_mbor,ipi_int_txwarning and ipi_int_waken */CAN2_IRQn                    = 143,              /**< Combined interrupt of ini_int_busoff,ini_int_error,ipi_int_mbor,ipi_int_txwarning and ipi_int_waken */Reserved144_IRQn             = 144,              /**< Reserved */Reserved145_IRQn             = 145,              /**< Reserved */PWM5_IRQn                    = 146,              /**< Cumulative interrupt line. OR of Rollover Interrupt line, Compare Interrupt line and FIFO Waterlevel crossing interrupt line */PWM6_IRQn                    = 147,              /**< Cumulative interrupt line. OR of Rollover Interrupt line, Compare Interrupt line and FIFO Waterlevel crossing interrupt line */PWM7_IRQn                    = 148,              /**< Cumulative interrupt line. OR of Rollover Interrupt line, Compare Interrupt line and FIFO Waterlevel crossing interrupt line */PWM8_IRQn                    = 149,              /**< Cumulative interrupt line. OR of Rollover Interrupt line, Compare Interrupt line and FIFO Waterlevel crossing interrupt line */ENET1_IRQn                   = 150,              /**< ENET1 interrupt */ENET1_1588_IRQn              = 151,              /**< ENET1 1588 Timer interrupt [synchronous] request. */ENET2_IRQn                   = 152,              /**< ENET2 interrupt */ENET2_1588_IRQn              = 153,              /**< MAC 0 1588 Timer interrupt [synchronous] request. */Reserved154_IRQn             = 154,              /**< Reserved */Reserved155_IRQn             = 155,              /**< Reserved */Reserved156_IRQn             = 156,              /**< Reserved */Reserved157_IRQn             = 157,              /**< Reserved */Reserved158_IRQn             = 158,              /**< Reserved */PMU_IRQ2_IRQn                = 159               /**< Brown-out event on either core, gpu or soc regulators. */} IRQn_Type;

GIC逻辑分块

GIC架构分成了两个逻辑块:Distributor和CPU Interface,也就是分发器端和CPU接口端。

  • Distributor(分发器端):此逻辑块负责处理各个中断事件的分发问题,也就是中断事件应该发送到哪个CPU Interface上去。分发器收集所有的中断源,可以控制每个中断的优先级,它总是将优先级最高的中断事件发送到CPU接口端。分发器端要做的主要工作是:
  1. 全局中断使能控制
  2. 控制每一个中断的使能或者关闭
  3. 设置每个中断的优先级
  4. 设置每个中断的目标处理器列表
  5. 设置每个外部中断的触发模式:电平触发或边沿触发
  6. 设置每个中断属于组0还是组1
  • CPU Interface(CPU接口端):与CPU Core相连接,也就是分发器和CPU Core之间的桥梁。主要工作:
  1. 使能或者关闭发送到CPU Core的中断请求信号
  2. 应答中断
  3. 通知中断处理完成
  4. 设置优先级掩码,通过掩码来设置哪些中断不需要上报给CPU Core
  5. 定义抢占策略
  6. 当多个中断到来的时候,选择优先级最高的中断通知给CPU Core

在core_ca7.h定义了GIC结构体,此结构体里面的寄存器分为了分发器端和CPU接口端。

typedef struct{uint32_t RESERVED0[1024];__IOM uint32_t D_CTLR;                 /*!< Offset: 0x1000 (R/W) Distributor Control Register */__IM  uint32_t D_TYPER;                /*!< Offset: 0x1004 (R/ )  Interrupt Controller Type Register */__IM  uint32_t D_IIDR;                 /*!< Offset: 0x1008 (R/ )  Distributor Implementer Identification Register */uint32_t RESERVED1[29];__IOM uint32_t D_IGROUPR[16];          /*!< Offset: 0x1080 - 0x0BC (R/W) Interrupt Group Registers */uint32_t RESERVED2[16];__IOM uint32_t D_ISENABLER[16];        /*!< Offset: 0x1100 - 0x13C (R/W) Interrupt Set-Enable Registers */uint32_t RESERVED3[16];__IOM uint32_t D_ICENABLER[16];        /*!< Offset: 0x1180 - 0x1BC (R/W) Interrupt Clear-Enable Registers */uint32_t RESERVED4[16];__IOM uint32_t D_ISPENDR[16];          /*!< Offset: 0x1200 - 0x23C (R/W) Interrupt Set-Pending Registers */uint32_t RESERVED5[16];__IOM uint32_t D_ICPENDR[16];          /*!< Offset: 0x1280 - 0x2BC (R/W) Interrupt Clear-Pending Registers */uint32_t RESERVED6[16];__IOM uint32_t D_ISACTIVER[16];        /*!< Offset: 0x1300 - 0x33C (R/W) Interrupt Set-Active Registers */uint32_t RESERVED7[16];__IOM uint32_t D_ICACTIVER[16];        /*!< Offset: 0x1380 - 0x3BC (R/W) Interrupt Clear-Active Registers */uint32_t RESERVED8[16];__IOM uint8_t  D_IPRIORITYR[512];      /*!< Offset: 0x1400 - 0x5FC (R/W) Interrupt Priority Registers */uint32_t RESERVED9[128];__IOM uint8_t  D_ITARGETSR[512];       /*!< Offset: 0x1800 - 0x9FC (R/W) Interrupt Targets Registers */uint32_t RESERVED10[128];__IOM uint32_t D_ICFGR[32];            /*!< Offset: 0x1C00 - 0xC7C (R/W) Interrupt configuration registers */uint32_t RESERVED11[32];__IM  uint32_t D_PPISR;                /*!< Offset: 0x1D00 (R/ ) Private Peripheral Interrupt Status Register */__IM  uint32_t D_SPISR[15];            /*!< Offset: 0x1D04 - 0xD3C (R/ ) Shared Peripheral Interrupt Status Registers */uint32_t RESERVED12[112];__OM  uint32_t D_SGIR;                 /*!< Offset: 0x1F00 ( /W) Software Generated Interrupt Register */uint32_t RESERVED13[3];__IOM uint8_t  D_CPENDSGIR[16];        /*!< Offset: 0x1F10 - 0xF1C (R/W) SGI Clear-Pending Registers */__IOM uint8_t  D_SPENDSGIR[16];        /*!< Offset: 0x1F20 - 0xF2C (R/W) SGI Set-Pending Registers */uint32_t RESERVED14[40];__IM  uint32_t D_PIDR4;                /*!< Offset: 0x1FD0 (R/ ) Peripheral ID4 Register */__IM  uint32_t D_PIDR5;                /*!< Offset: 0x1FD4 (R/ ) Peripheral ID5 Register */__IM  uint32_t D_PIDR6;                /*!< Offset: 0x1FD8 (R/ ) Peripheral ID6 Register */__IM  uint32_t D_PIDR7;                /*!< Offset: 0x1FDC (R/ ) Peripheral ID7 Register */__IM  uint32_t D_PIDR0;                /*!< Offset: 0x1FE0 (R/ ) Peripheral ID0 Register */__IM  uint32_t D_PIDR1;                /*!< Offset: 0x1FE4 (R/ ) Peripheral ID1 Register */__IM  uint32_t D_PIDR2;                /*!< Offset: 0x1FE8 (R/ ) Peripheral ID2 Register */__IM  uint32_t D_PIDR3;                /*!< Offset: 0x1FEC (R/ ) Peripheral ID3 Register */__IM  uint32_t D_CIDR0;                /*!< Offset: 0x1FF0 (R/ ) Component ID0 Register */__IM  uint32_t D_CIDR1;                /*!< Offset: 0x1FF4 (R/ ) Component ID1 Register */__IM  uint32_t D_CIDR2;                /*!< Offset: 0x1FF8 (R/ ) Component ID2 Register */__IM  uint32_t D_CIDR3;                /*!< Offset: 0x1FFC (R/ ) Component ID3 Register */__IOM uint32_t C_CTLR;                 /*!< Offset: 0x2000 (R/W) CPU Interface Control Register */__IOM uint32_t C_PMR;                  /*!< Offset: 0x2004 (R/W) Interrupt Priority Mask Register */__IOM uint32_t C_BPR;                  /*!< Offset: 0x2008 (R/W) Binary Point Register */__IM  uint32_t C_IAR;                  /*!< Offset: 0x200C (R/ ) Interrupt Acknowledge Register */__OM  uint32_t C_EOIR;                 /*!< Offset: 0x2010 ( /W) End Of Interrupt Register */__IM  uint32_t C_RPR;                  /*!< Offset: 0x2014 (R/ ) Running Priority Register */__IM  uint32_t C_HPPIR;                /*!< Offset: 0x2018 (R/ ) Highest Priority Pending Interrupt Register */__IOM uint32_t C_ABPR;                 /*!< Offset: 0x201C (R/W) Aliased Binary Point Register */__IM  uint32_t C_AIAR;                 /*!< Offset: 0x2020 (R/ ) Aliased Interrupt Acknowledge Register */__OM  uint32_t C_AEOIR;                /*!< Offset: 0x2024 ( /W) Aliased End Of Interrupt Register */__IM  uint32_t C_AHPPIR;               /*!< Offset: 0x2028 (R/ ) Aliased Highest Priority Pending Interrupt Register */uint32_t RESERVED15[41];__IOM uint32_t C_APR0;                 /*!< Offset: 0x20D0 (R/W) Active Priority Register */uint32_t RESERVED16[3];__IOM uint32_t C_NSAPR0;               /*!< Offset: 0x20E0 (R/W) Non-secure Active Priority Register */uint32_t RESERVED17[6];__IM  uint32_t C_IIDR;                 /*!< Offset: 0x20FC (R/ ) CPU Interface Identification Register */uint32_t RESERVED18[960];__OM  uint32_t C_DIR;                  /*!< Offset: 0x3000 ( /W) Deactivate Interrupt Register */} GIC_Type;

GIC_Type就是GIC控制器,列举出了GIC控制器的所有寄存器,可以通过结构体 GIC_Type 来访问 GIC 的所有寄存器。
__IOM uint32_t D_CTLR; /* Offset: 0x1000 (R/W) */,分发器端相关寄存器,其相对于GIC基地址偏移为0x1000,因此我们获取到GIC基地址以后只需要加上0x1000即可访问GIC分发器端寄存器。

__IOM uint32_t C_CTLR; /*!< Offset: 0x2000 (R/W) CPU Interface Control Register */,CPU接口端相关寄存器,其相对于GIC基地址的偏移为0x2000,同样的,获取到 GIC 基地址以后只需要加上 0X2000 即可访问 GIC 的 CPU 接口段寄存器。

Cortex-A7中断详解(一)相关推荐

  1. linux内核中断详解

    linux内核中断详解 1.中断的硬件触发流程 外设:如果外设有操作或者有数据可用,那么就会产生一个电信号,这个电信号发送给中断控制器. 中断控制器:中断控制器接收到外设发来的电信号以后,进行进一步的 ...

  2. STM32开发 -- 外部中断详解

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/87376865 在讲三轴加速度计的时候,提到外部中断.接下来就看看中断为什么这 ...

  3. 【STM32学习笔记】(13)——外部中断详解

    EXTI 简介         EXTI(External interrupt/event controller)-外部中断/事件控制器,管理了控制器的 20 个中断/事件线.每个输入线可以独立地配置 ...

  4. 51单片机中断详解(上)

    一.中断的概念 中断发生 CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理 中断响应和中断服务 CPU暂时中断当前的工作,转去处理事件B 中断返回 待CPU将事件B处理完毕后,再回到原来 ...

  5. STM32 中断详解

    目录 1 EXTI控制器 2 NVIC控制器 3 code 中断,在单片机中占有非常重要的地位.代码默认地从上向下执行,遇到条件或者其他语句,会按照指定的地方跳转.而在单片机执行代码的过程中,难免会有 ...

  6. 【stm32】中断详解

    stm32中断的顺序: 1)初始化 IO 口. 2)开启 AFIO 时钟 3)EXTI配置. 4)NVIC配置. 5)编写中断服务函数. 1 NVIC中断优先级管理 CM3 内核支持 256 个中断, ...

  7. BIOS视频中断 10号中断详解

    10号中断 功能号 功能描述 00H 设置显示模式 01H 设置光标形状 02H 在文本坐标下设置光标位置 03H 在文本坐标下读取光标各种参数 04H 设置当前状态和光笔位置 05H 设置显示页,即 ...

  8. STM32-外部中断详解

    目录 前言 一.外部中断是什么? 二.STM32外部中断概述 1. STM32的外部中断线 2. 外部中断线与IO引脚对应关系 3. 中断向量与服务函数 三.STM32外部中断库函数配置 1. 常用库 ...

  9. STM32 外部中断详解(原理+配置代码)

    本文介绍了STM32基于标准外设库的外部中断配置,以及基于参考手册如何更加寄存器配置外部中断 文章目录 1 前言 2 STM32的外部中断 3 中断服务函数的映射关系 4 外部中断的配置 5 寄存器的 ...

  10. STM32F4_外部中断详解(EXTI)

    目录 1. EXTI 是什么? 2. EXTI主要特性 3. EXTI框图 3.1 外部中断/事件线映射 4. EXTI寄存器 4.1 中断屏蔽寄存器 EXTI_IMR 4.2 事件屏蔽寄存器 EXT ...

最新文章

  1. android打开wav格式,FileNotFoundException从Android资产中打开wav文件
  2. 华为鸿蒙有机会吗,谷歌重压之下,华为鸿蒙还有机会翻盘吗?全球系统生态之争开启...
  3. matlab训练集测试集划分
  4. jQuery调用其他JS文件中的方法
  5. java lodop打印_Java的云打印Lodop
  6. 你知道这 8 种 SQL 错误用法吗?
  7. 优控触摸屏使用手册_中达优控plc触摸屏一体机说明书资料
  8. 游戏外挂,其实是一门网络技术
  9. bug - Nacos - Ignore the empty nacos configuration and get it based on dataId
  10. java 向量 内积_【vector应用】计算两个向量的内积
  11. Android Retrofit网络请求返回HTTP 405 Method Not Allowed
  12. 最小采样频率计算公式_AD5933使用外部时钟获得更低的分析频率
  13. Python复习笔记———超详细
  14. 解决无法安装Axure RP 9(Windows 7 SP1 更新补丁)
  15. Blockchain Meets Edge Computing: A Distributed and Trusted Authentication System
  16. 香橙派 Orangepi Zero2 外壳天线改装
  17. (每日一练c++)CC114 有效的数独
  18. 商用密码应用与安全性评估之(四)密码应用安全性评估实施要点
  19. 微信小程序 表情小作坊 — 轻松定制表情包
  20. AFM模型原理及Pytorch代码复现

热门文章

  1. Matlab双目相机标定
  2. 无监督智能地震速度拾取(matlab实现)
  3. 文本指纹算法和内容指纹系统介绍
  4. 微信小程序实战--高仿人民日报
  5. Uva-1289 Stacking Plates
  6. 两将军问题和TCP三次握手
  7. Unity3d脚本改变GameObject的Material(二)
  8. 批量修改图片尺寸(适用于4:3和16:9的图片)
  9. 见人搭话:聊别人擅长或感兴趣的话题
  10. ByteBuffer.allocate()与ByteBuffer.allocateDirect()方法的区别