Cortex-A7中断详解(一)

news2024/11/17 11:35:30

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 接口段寄存器。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑开机memory management错误蓝屏了怎么办?

电脑开机memory management错误蓝屏了怎么办&#xff1f;windows系统出现不兼容问题之后&#xff0c;很容易出现电脑蓝屏的情况。最近有用户遇到了上述的蓝屏错误情况&#xff0c;不知道怎么去进行解决。今天我们就一起来看看以下的解决方法分享吧。 准备工作&#xff1a; 1、U…

yolov5半自动打标签(opencv版本),识别目标画框并将坐标信息保存在xml中

文章目录 1.yolov5预训练模型推理2. opencv边缘检测结果展示 yolov5训练数据集时&#xff0c;需要对数据进行打标签&#xff0c;可以通过两种方法进行半自动化打标签。 1.yolov5预训练模型推理 yolov5预训练模型&#xff1a;将待打标签的图片输入预训练模型中进行推理&#xf…

实现PXE批量网络装机及kickstrat无人值守安装(富士山终究留不住欲落的樱花)

一、PXE概述和部署PXE批量装机 1.PXE简介 PXE&#xff08;预启动执行环境&#xff0c;在操作系统之前运行&#xff09;是由Intel公司开发的网络引导技术&#xff0c;c/s架构&#xff0c;允许客户机通过网络从远程服务器下载引导镜像&#xff0c;并加载安装文件或者整个操作系统…

2023_8.0.33版windows版MySql安装_配置远程连接_修改设置初始密码---MySql工作笔记0001

MySQL :: Download MySQL Community Server https://dev.mysql.com/downloads/mysql/ 首先去下载mysql 可以看到这里下载第一个就可以了,最新版的8.0.33 这里点击仅仅下载 just start my download 然后解压到一个文件夹,然后配置一下环境变量 然后新建一个my.ini文件 然后把…

ubuntu22.04下挂载第二块硬盘

文章目录 一、查看硬盘情况二、找到nvme1n1三、挂载四、修改分区文件 一、查看硬盘情况 首先要查看一下系统识别出来的设备。也就是说&#xff0c;我希望知道&#xff0c;ubuntu到底发现了几块硬盘。用命令&#xff1a;lsblk 显示结果如下&#xff1a; 有两块硬盘&#xff1a…

Win11打开移动热点后电脑无法上网怎么办?

Win11打开移动热点后电脑无法上网怎么办&#xff1f;有用户将自己的电脑开启移动热点来使用的时候&#xff0c;发现自己的电脑出现了无法上网的情况。那么为什么开启热点之后&#xff0c;就会无法进行上网呢&#xff1f;来看看以下的解决方法分享吧。 Win11打开移动热点无法上网…

virtual kubelet 简单使用例子

virtual kubelet 简单使用例子 实现过程制作virtual kubelet节点证书下载virtual kubelet代码并编译virtual kubelet virtual kubelet 顾名思义就是虚拟的kubelet节点 效果如下&#xff1a; 实现过程 制作virtual kubelet节点证书 openssl genrsa -out client.key 2048 opens…

EPICS aSub记录使用实例

本实例描述了在数据库中如何使用aSub记录 本实验中使用了三个k型热电偶&#xff0c;一个3路k型热电偶变送器以及一个串口服务器&#xff1a; 温度变送器参数&#xff1a; 串口服务器&#xff1a; 1) 用makeBaseApp.pl构建IOC应用程序的目录结构&#xff1a; [blctrllocalhost…

OpenGL入门教程之 摄像机

引言 前面的教程中我们讨论了观察矩阵以及如何使用观察矩阵移动场景。OpenGL本身没有摄像机的概念&#xff0c;但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机&#xff0c;这样感觉就像我们在移动&#xff0c;而不是场景在移动。  本节我们将会讨论如何…

从零开始学架构——高可用存储架构

双机架构 存储高可用方案的本质都是通过将数据复制到多个存储设备&#xff0c;通过数据冗余的方式来实现高可用&#xff0c;其复杂性主要体现在如何应对复制延迟和中断导致的数据不一致问题。因此&#xff0c;对任何一个高可用存储方案&#xff0c;我们需要从以下几个方面去进…

【MySQL】一个脚本启动MySQL 8.0并初始化数据库

引 很多情况下需要在客户端发布时发布 MySQL 数据库&#xff0c;这种发布方式虽然存在文件资源较大、易出错等缺点&#xff0c;但是却可以让桌面产品的发布更加完整。 本文将阐述如何使用一个脚本启动并初始化 MySQL 8.0 的方法&#xff0c;涵盖数据库下载、脚本源码、测试及…

PFSK162 3BSE015088R1通常都要做空载全电压合闸冲击试验

​ PFSK162 3BSE015088R1通常都要做空载全电压合闸冲击试验 变压器励磁涌流影响的保护整定 摘要&#xff1a;在大型变压器空栽冲击过程中&#xff0c;由于励磁涌流和负序电压的存在&#xff0c;如果定值整定不得当&#xff0c;会导致差动保护&#xff0c;复压过流保护等误动作&…

设计模式——组件协作模式之观察者模式

文章目录 前言一、“组件协作” 模式二、Observer 观察者模式1、动机2、模式定义3、伪代码示例①、第一种方案&#xff0c;最朴素的方式②、第二种方案&#xff0c;重构使得遵循DIP原则&#xff1a;③、进一步的小优化&#xff1a;④、修改使得支持多个观察者&#xff1a; 4、结…

028:Mapbox GL 绘制线段,实时测量长度距离值

第028个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中添加draw组件,绘制线段,编辑线段,实时显示长度值。这里使用turf来计算长度值,采用默认的单位千米。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代…

Elasticsearch:Standard Text Analyzer - 标准文本分析器

Elasticsearch 提供了超过很多开箱即用的分析器&#xff0c;我们可以在文本分析阶段使用它们。 这些分析器很可能足以满足基本情况&#xff0c;但如果需要创建自定义分析器&#xff0c;可以通过使用构成该模块的所需组件实例化一个新的分析器模块来实现。 下表列出了 Elasticse…

SuSE linux server 11通过SAP来安装oracle11g

这里安装通过xmanager4进行安装&#xff0c;之前文章已经说了怎么通过xmanager4来连接linux系统&#xff0c;这里说一下安装oracle11g。 我这里是通过sap来安装oracle11g&#xff0c;所以需要 export LD_LIBRARY_PATH/oracle/P90/112_64/lib/:/sapmnt/P90/exe/ 同时在orap90用…

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

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

马云的创业故事及他人生中的摆渡人-卖掉中国黄页去北漂(四)

马云上京&#xff0c;是在外经贸部一位名叫王建国的朋友牵线之下&#xff0c;受邀担任外经贸部下属的中国国际电子商务中心&#xff08;下面简称EDI&#xff09;总经理&#xff0c;负责搭建外经贸部官网和网上中国商品交易市场。 马云团队在潘家园租了房子&#xff0c;白天上班…

如何编写高质量代码、提高编程效率?

一、 前言 高质量代码是指在满足功能需求的基础上&#xff0c;具备高性能、安全、可扩展、易维护、可测试等特点的代码。它不仅可以提高开发效率和代码质量&#xff0c;更能有效减少代码维护成本&#xff0c;促进团队协作和项目成功。因此&#xff0c;编写高质量代码对程序员来…

妙记多「我的主页」升级,日历聚合任务待办,为你打造个人时间管理系统⏰

我们应该如何处理“日程”和“待办”的关系&#xff1f; 日程和待办的区别与联系 从字面意义上来理解&#xff0c;日程是这一天的安排&#xff0c;待办是需要去完成的事情&#xff0c;日程与待办本质上是一种相互包含的关系。将所有事情都视作待办显然是不科学的&#xff0c;那…