imx6ull中断系统 一

本文深入介绍了Cortex-A7处理器的中断系统,包括IRQ、FIQ等中断类型,以及GICV2中断控制器的工作原理。GICV2支持多核处理,将中断源分为SPI、PPI和SGI,并详细解释了中断ID的分配。

Cortex-A7 中断系统简介

在这里插入图片描述
在这里插入图片描述

IRQ中断

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

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 个核。 ARM 会根据 GIC 版本的不同研发出不同的 IP 核,那些半导体厂商直接购买对应的 IP 核即可,比如 ARM 针对 GIC V2 就开发出了 GIC400 这个中断控制器 IP 核。当 GIC 接收到外部中断信号以后就会报给 ARM 内核,但是ARM 内核只提供了四个信号给 GIC 来汇报中断情况: VFIQ、 VIRQ、 FIQ 和 IRQ,他们之间的关系如图 17.1.3.1 所示
**在这里插入图片描述
在图 17.1.3.1 中, GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号报给 ARM 内核,这四个信号的含义如下:
VFIQ:虚拟快速 FIQ。
VIRQ:虚拟快速 IRQ。
FIQ:快速中断 IRQ。
IRQ:外部中断 IRQ。
VFIQ 和 VIRQ 是针对虚拟化的,我们讨论虚拟化,剩下的就是 FIQ 和 IRQ 了,我们前面都讲了很多次了。本教程我们只使用 IRQ,所以相当于 GIC 最终向 ARM 内核就上报一个 IRQ信号。那么 GIC 是如何完成这个工作的呢? GICV2 的逻辑图如图 17.1.3.2 所示:
在这里插入图片描述
在这里插入图片描述
图 17.1.3.1 中左侧部分就是中断源,中间部分就是 GIC 控制器,最右侧就是中断控制器向处理器内核发送中断信息。我们重点要看的肯定是中间的 GIC 部分, GIC 将众多的中断源分为分为三类:
①、 SPI(Shared Peripheral Interrupt),共享中断,顾名思义,所有 Core 共享的中断,这个是最常见的,那些外部中断都属于 SPI 中断(注意!不是 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,那么这三类中断是如何分配这 1020 个中断 ID 的呢?这 1020 个 ID 分配如下:
ID0~ID15:这 16 个 ID 分配给 SGI。
ID16~ID31:这 16 个 ID 分配给 PPI。
ID32~ID1019:这 988 个 ID 分配给 SPI,像 GPIO 中断、串口中断等这些外部中断 ,至于具体到某个 ID 对应哪个中断那就由半导体厂商根据实际情况去定义了。比如 I.MX6U 的总共使用了 128 个中断 ID,加上前面属于 PPI 和 SGI 的 32 个 ID, I.MX6U 的中断源共有 128+32=160个
在这里插入图片描述
具体定义查表imx6ull参考手册184页

### iMX6ULL 中断号列表及其查看方法 iMX6ULL 处理器支持多达 128 个中断源,这些中断被分配为标准的 SPI(Shared Peripheral Interrupts)。以下是关于如何获取和理解 iMX6ULL中断号的相关信息: #### 1. **中断号范围** iMX6ULL 支持的标准中断号范围如下: - ID0-ID15:保留给 SGI(Software Generated Interrupts),通常由软件生成。 - ID16-ID31:保留给 PPI(Private Peripheral Interrupts),主要用于 ARM 内核内部功能。 - ID32-ID1019:分配给 SPI(Shared Peripheral Interrupts),涵盖了外部设备的中断请求。 对于 iMX6ULL 而言,其主要使用的中断号集中在 SPI 部分,即从 `ID32` 开始[^2]。 --- #### 2. **中断号的具体映射** 具体的中断号可以通过查阅官方文档中的《i.MX 6UltraLite Reference Manual》来获得。该手册详细列出了每个外设对应的中断号。例如: - GPIO 中断可能分布在多个编号范围内,具体取决于所配置的端口和引脚。 - UART 或其他通信接口也会有自己的固定中断号。 如果需要快速定位某个特定外设的中断号,可以参考芯片的数据手册或者 SDK 提供的头文件(如 `interrupt.h` 或类似的定义文件)[^4]。 --- #### 3. **程序化方式查询中断号** 在开发环境中,也可以通过代码访问相关寄存器来动态确认当前系统中断状态以及关联的中断号。以下是个简单的示例流程: ##### (1)初始化 GIC 控制器 GIC 是负责管理 Cortex-A7 架构下中断的核心组件。需先对其进行基本配置,包括启用中断、设定优先级等操作。 ```c void gic_init(void) { // 初始化 GIC 寄存器基址 volatile uint32_t *gicc_ctlr = (uint32_t *)0x00A00100; volatile uint32_t *gicc_pmr = (uint32_t *)0x00A00104; // 启用 GIC CPU 接口控制寄存器 *gicc_ctlr |= 1 << 0; // 设置最低优先级阈值 *gicc_pmr = 0xFF; } ``` ##### (2)捕获中断号 当发生中断时,系统会自动跳转至 IRQ 函数入口,在此函数中可通过协处理器指令提取当前发生的中断号,并将其存储于寄存器 R0 中。 ```asm .global SystemIrqHandler SystemIrqHandler: mrc p15, 0, r0, c2, c0, 0 @ 获取中断号到 R0 push {lr} @ 保存链接寄存器 bl HandleInterrupt @ 调用高级语言实现的处理逻辑 pop {pc} @ 返回原地址 ``` 随后可以在 `HandleInterrupt()` 函数中进步解析 R0 值以决定调用哪个具体的外设中断服务例程。 --- #### 4. **GPIO 中断配置实例** 作为典型应用场景之,下面展示了个针对 GPIO 引发的中断进行设置的例子: ```c #include "ccm_reg.h" #include "gpio_reg.h" void enable_gpio_interrupt(uint32_t port, uint32_t pin) { if(port == 4 || port == 5){ CCM->CCGR4 = 0xFFFFFFFFU; // Enable clock for GPIO4/5 CCM->CCGR5 = 0xFFFFFFFFU; switch(port){ case 4: GPIO4->EDGE_SEL |= (1 << pin); // Set edge detection type GPIO4->IMR |= (1 << pin); // Unmask the interrupt GPIO4->ISR |= (1 << pin); // Clear pending status break; case 5: GPIO5->EDGE_SEL |= (1 << pin); GPIO5->IMR |= (1 << pin); GPIO5->ISR |= (1 << pin); break; } } } ``` 上述代码片段展示了如何使能指定 GPIO 口上的中断事件,并确保不会因残留信号而导致误触发。 --- #### 5. **总结** 综上所述,了解 iMX6ULL中断号不仅依赖硬件设计本身还涉及软件层面的支持。建议开发者熟悉以下几个方面的工作: - 查询官方资料明确各外围模块对应的唯标识符; - 编写合适的驱动代码适配目标平台特性; - 利用调试工具验证最终效果是否符合预期需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值