Cortex-A7中断详解(一)

STM32中断系统回顾

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

中断向量表

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

中断向量表在整个程序的最前面,如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     RTC_Alarm_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

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

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

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

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

#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 

中断向量表偏移配置在函数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 接口段寄存器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/15414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux入门】linux指令(1)

【Linux入门】linux指令&#xff08;1&#xff09; 目录 【Linux入门】linux指令&#xff08;1&#xff09;操作系统登录服务器Linux下的基本指令ls指令pwd指令Linux路径分割符 /cd指令touch指令mkdir指令&#xff08;重要&#xff09;rmdir指令&&rm指令&#xff08;重…

linux实现网络程序

1️⃣ 在linux下&#xff0c;通过套接字实现服务器和客户端的通信。 2️⃣ 实现单线程、多线程通信。或者实现线程池来通信。 3️⃣ 优化通信&#xff0c;增加守护进程。 有情提醒&#xff0c;类里面默认的函数是内联。内联函数在调用的地方展开&#xff0c;没有函数地址&…

Mac使用命令行工具解压和压缩rar文件

目前在Mac电脑里支持解压缩的格式主要有&#xff1a;zip、gz等&#xff0c;但是还不支持rar格式的文件&#xff0c;接下来带着大家学习一下如何解压缩rar格式文件。 1.下载rar工具 打开&#xff1a;https://www.rarlab.com/download.htm 根据自己电脑的芯片要求选择自己的安装…

【计算机基本原理-数据结构】数据结构中树的详解

【计算机基本原理-数据结构】数据结构中树的详解 1&#xff09;总览2&#xff09;树的相关概念3&#xff09;二叉树、满二叉树、完全二叉树4&#xff09;二叉查找树 - BST5&#xff09;平衡二叉树 - AVL6&#xff09;红黑树7&#xff09;哈弗曼树8&#xff09;B 树9&#xff09…

TCP流量控制与拥塞控制

什么是流量控制 一条TCP连接的每一侧主机都为该连接设置了接收缓存。当该TCP连接接收到正确的、有序的报文段&#xff0c;就会将数据放入接收缓存。相关联的应用会从缓存中读取数据。 如果发送者发送数据过快、过多&#xff0c;而接收方的应用程序从缓冲区读取的速度较慢&…

机器学习实战教程(十):逻辑回归

概述 逻辑回归&#xff08;Logistic Regression&#xff09;是一种用于解决二分类或多分类问题的统计学习方法。它以自变量线性组合的形式进行建模&#xff0c;并使用Sigmoid函数将结果映射到[0, 1]的值域内&#xff0c;表示样本属于某个类别的概率。 Logistic Regression是最…

Stable Diffusion-生式AI的新范式

! 扩散模型&#xff08;Stable Diffusion)现在是生成图像的首选模型。由于扩散模型允许我们以提示( prompts)为条件生成图像&#xff0c;我们可以生成我们所选择的图像。在这些文本条件的扩散模型中&#xff0c;稳定扩散模型由于其开源性而最为著名。 在这篇文章中&#xff0…

STM32平衡小车 TB6612电机驱动学习

TB6612FNG简介 单片机引脚的电流一般只有几十个毫安&#xff0c;无法驱动电机&#xff0c;因此一般是通过单片机控制电机驱动芯片进而控制电机。TB6612是比较常用的电机驱动芯片之一。 TB6612FNG可以同时控制两个电机&#xff0c;工作电流1.2A&#xff0c;最大电流3.2A。 VM电…

力劲塑机:用CRM“塑造”数字化能力

你知道吗&#xff1f;从手机到电脑&#xff0c;从暖气到扶梯&#xff0c;从家用电器到汽车、摩托车&#xff0c;从眼镜、手表到拉链、纽扣&#xff0c;这些物品的生产过程都离不开压铸和注塑工艺。如果说压铸和注塑这个几百亿的产业带动了几万亿的市场&#xff0c;一点也不夸张…

fc坦克大战游戏完美复刻

文章目录 一、 介绍二、 制作基本物体三、 控制玩家坦克移动、转向四、 子弹脚本、爆炸脚本五、 敌人AI寻路算法六、 坦克生成点脚本七、 用链表实例化地图八、 玩家游戏控制器脚本九、 添加音效十、 资源包 一、 介绍 儿时经典游戏《坦克大战》完整复刻 发射子弹、生成敌人、…

巧用千寻位置GNSS软件|一文教会横断面测量

测横断面主要用于线路工程和水利工程的前期设计中&#xff0c;在线路平曲线设计好之后&#xff0c;千寻位置GNSS软件可用于在中桩处测定垂直于线路中线方向原地貌的地面起伏的数据&#xff0c;本期就为大家介绍具体的操作技巧。 点击【测量】->【测横断面】&#xff0c;选择…

java——最小的K个数

题目链接 牛客在线oj题——最小的K个数 题目描述 给定一个长度为 n 的可能有重复值的数组&#xff0c;找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字&#xff0c;则最小的4个数字是1,2,3,4(任意顺序皆可)。 数据范围&#xff1a;0≤k,n≤10000&…

Flink之TaskManager内存解析

一、CK失败 Flink任务的checkpoint操作失败大致分为两种情况&#xff0c;ck decline和ck expire: &#xff08;1&#xff09;ck decline 发生ck decline情况时&#xff0c;我们可以通过查看JobManager.log或TaskManager.log查明具体原因。其中有一种特殊情况为ck cancel&…

idea使用 ( 二 ) 创建java项目

3.创建java项目 3.1.创建普通java项目 3.1.1.打开创建向导 接 2.3.1.创建新的项目 也可以 从菜单选择建立项目 会打开下面的选择界面 3.1.2.不使用模板 3.1.3.设置项目名 Project name : 项目名 Project location : 项目存放的位置 确认创建 3.1.4.关闭tips 将 Dont s…

增强型PID-自适应-前馈-神经网络控制研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

解决docker启动mysql无法输入中文以及中文不显示或乱码问题

前言 我在使用MySQL时&#xff0c;遇到了两个问题。一是在插入中文数据时&#xff0c;无法输入中文。二是在select的时候&#xff0c;查出来的中文数据是空的&#xff08;因为插入时为空&#xff09;&#xff0c;然后我就使用Navicat连接数据库添加了中文数据&#xff0c;再到…

搭建家庭影音媒体中心 --公网远程连接Jellyfin流媒体服务器

文章目录 前言1. 安装Home Assistant2. 配置Home Assistant3. 安装cpolar内网穿透3.1 windows系统3.2 Linux系统3.3 macOS系统 4. 映射Home Assistant端口5. 公网访问Home Assistant6. 固定公网地址6.1 保留一个固定二级子域名6.2 配置固定二级子域名 转载自远程穿透的文章&…

人工智能时代来临,殊不知低代码早已出手

科普一下人工智能的等级划分&#xff0c;按照实力&#xff0c;人工智能可以分为弱人工智能(Artificial Narrow Intelligence&#xff0c;简称ANI)、强人工智能(Artificial General Intelligence简称AGI)、超人工智能(Artificial Superintelligence简称ASI)三个等级。 弱人工智能…

JavaWeb学习------Servlet

目录 JavaWeb学习------Servlet Servlet 生命周期 Servlet 生命周期 Servlet 方法介绍 •Servlet 体系结构 Servlet 体系结构 •Servlet urlPattern配置 Servlet urlPattern配置 •XML 配置方式编写 Servlet XML 配置方式编写 Servlet JavaWeb学习------Servlet •快速…

【汽车品牌案例02-设置右侧索引 Objective-C语言】

一、刚才我们说了一下,如何把那个汽车品牌加载起来,我们使用了一个模型的嵌套,以及我们在创建单元格的时候,是不是指定了一个,单元格的可重用ID吧, 1.根据重用ID来创建单元格,那么我们运行的时候,已经能把这个大致的效果做出来了, 大致就是这么一个效果, 接下来,还…