日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Cortex-A7中断详解(一)

發布時間:2024/1/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Cortex-A7中断详解(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STM32中斷系統回顧

  • 中斷向量表
  • NVIC(內嵌向量中斷控制器)
  • 中斷使能
  • 中斷服務函數
  • 中斷向量表

    中斷向量表是一個表,表里面存放的是中斷向量。
    中斷服務程序的入口地址或存放中斷服務程序的首地址成為中斷向量,因此中斷向量表是一系列中斷服務程序入口地址組成的表。
    中斷服務程序在中斷向量表中的位置是由半導體廠商定好的,當某個中斷被觸發以后就會自動跳轉到中斷向量表中對應的中斷服務程序入口地址處。

    中斷向量表在整個程序的最前面,如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個異常中斷。

  • 復位中斷(Reset),CPU復位后就會進入復位中斷,我們可以在復位中斷服務函數里面做一些初始化工作,比如初始化SP指針,DDR等。
  • 未定義指令中斷(Undefined Instuction),如果指令不能識別的話就會產生此中斷。
  • 軟中斷(Software Interrupt,SWI),由SWI指令引起的中斷,Linux的系統調用會用SWI指令來引起軟中斷,通過軟中斷來陷入到內核空間。
  • 指令預取中止中斷(Prefetch Abort),預取指令出錯的時候會產生此中斷。
  • 數據訪問中止中斷(Data Abort),訪問數據出錯的時候會產生此中斷。
  • IRQ中斷:芯片外設中斷都會引起此中斷發生。
  • 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將總多的中斷源分為三類:

  • SPI(Shared Peripheral Interrupt),共享中斷,所有Core共享的中斷,所有外部中斷都屬于SPI中斷。比如按鍵中斷、串口中斷等等,這些中斷所有的 Core 都可以處理,不限定特定 Core。
  • PPI(Private Peripheral Interrupt),私有中斷, GIC 是支持多核的,每個核肯定有自己獨有的中斷。這些獨有的中斷肯定是要指定的核心處理,因此這些中斷就叫做私有中斷。
  • SGI(Software-generated Interrupt),軟件中斷,由軟件觸發引起的中斷,通過向寄存器GICD_SGIR 寫入數據來觸發,系統會使用 SGI 中斷來完成多核之間的通信。
  • 中斷ID

    中斷源很多,為了區分這些不同的中斷源肯定要給他們分配一個唯一的ID,這些ID就是中斷ID。每一個 CPU 最多支持 1020 個中斷 ID,中斷 ID 號為 ID0~ID1019。這 1020 個 ID 包含了 PPI、SPI 和 SGI。

  • ID0~ID15:這 16 個 ID 分配給 SGI。
  • ID16~ID31:這 16 個 ID 分配給 PPI。
  • 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接口端。分發器端要做的主要工作是:
  • 全局中斷使能控制
  • 控制每一個中斷的使能或者關閉
  • 設置每個中斷的優先級
  • 設置每個中斷的目標處理器列表
  • 設置每個外部中斷的觸發模式:電平觸發或邊沿觸發
  • 設置每個中斷屬于組0還是組1
    • CPU Interface(CPU接口端):與CPU Core相連接,也就是分發器和CPU Core之間的橋梁。主要工作:
  • 使能或者關閉發送到CPU Core的中斷請求信號
  • 應答中斷
  • 通知中斷處理完成
  • 設置優先級掩碼,通過掩碼來設置哪些中斷不需要上報給CPU Core
  • 定義搶占策略
  • 當多個中斷到來的時候,選擇優先級最高的中斷通知給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中断详解(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。