news 2026/5/23 7:22:21

ARM架构——中断系统详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ARM架构——中断系统详解

目录

一、中断的引用

1.1 轮询方式的局限性

1.2 中断系统简介

二、ARM 中断系统硬件架构

2.1 通用中断控制器 GIC

2.1.1 GIC 中断分类

2.1.2 架构组成

2.2 协处理器 CP15

2.2.1 访问指令

2.2.2 关键寄存器

三、代码实现:中断驱动的按键控制

3.1 向量表管理与初始化

3.2 GPIO 与中断配置

3.3 中断服务函数 (ISR)

3.4 主程序流程

四、软件设计原则:低耦合与 OCP


一、中断的引用

1.1 轮询方式的局限性

在学习中断之前,我们通常使用轮询(Polling)的方式来处理按键等外设输入:

while (1) { if ((GPIO1->DR & (1 << 18)) == 0) // 检测到低电平 { led_nor(); beep_nor(); } delay(0x7FFFFF); // 模拟大量复杂业务 }

轮询方式的原理:CPU 周期性地读取 GPIO 引脚状态,判断是否有按键按下。

轮询的致命缺陷:

  • 漏查风险:当主程序需要处理大量、复杂且耗时的业务时(例如模拟一个 delay(0x7FFFFF) 的长延时),CPU 无法及时检查按键状态。
  • 实时性差:就像“汽车刹车”这种高实时性场景,如果 CPU 正在处理其他任务而无法立即响应刹车信号,后果不堪设想。

因此,我们需要引入中断(Interrupt)。

1.2 中断系统简介

定义:中断是指 CPU 能打断当前正在进行的工作,去处理更为紧急的任务(中断服务函数),并且在处理完后,能自动回到原先的地方继续工作。

中断处理的标准流程:

  1. 中断请求:中断源(外设)发出信号。
  2. 中断响应检查:CPU 检查是否响应该中断,以及该中断是否被屏蔽。
  3. 优先级检查:GIC 判定当前中断的优先级。
  4. 保护现场:保存被暂停程序的上下文。
  5. 执行中断服务函数(ISR):处理紧急任务。
  6. 恢复现场:还原上下文,继续执行原程序。

二、ARM 中断系统硬件架构

2.1 通用中断控制器 GIC

IMX6ULL 使用的是单核 Cortex-A7,其内部集成了 GIC v2.0 控制器。GIC 负责管理所有的中断源,并决定分发给哪个核心处理。GIC逻辑分区如下:

GIC逻辑分区

2.1.1 GIC 中断分类

根据 ARM GIC v2.0 规范,中断源被分为三类(共 1020 个 ID):

类型全称ID 范围描述
SGISoftware-generated Interrupt (软件中断)0 - 15由软件向寄存器 GICD_SGIR 写入数据触发,常用于多核间通信。
PPIPrivate Peripheral Interrupt (私有中断)16 - 31每个核心独有的中断(如 Generic Timer),必须由指定核心处理。
SPIShared Peripheral Interrupt (共享中断)32 - 1019外部外设产生的中断(如 GPIO、I2C 等),所有核心共享。

注意:这里的 SPI 指的是共享中断,不要和通信协议 SPI 总线混淆。

2.1.2 架构组成

GIC 主要由两部分组成:

  • Distributor (分发器):负责检测、排序和分发中断。
  • CPU Interface (CPU 接口):负责将分发器发送的中断信号传输给处理器核心。

2.2 协处理器 CP15

在配置中断和系统底层时,离不开协处理器 CP15。它负责系统控制、MMU 配置、Cache 管理以及虚拟化等任务。

2.2.1 访问指令

CP15 包含 c0 到 c15 组寄存器,通过专用指令访问:

  • MRC:读 CP15 寄存器。
  • MCR:写 CP15 寄存器。

2.2.2 关键寄存器

  • MIDR (Main ID Register, c0):存储内核的基本信息。
  • SCTLR (System Control Register,c1):系统控制寄存器,其中两个位至关重要:
    • Bit 13 (V 位):控制异常向量表的基地址。
      • 0:基地址为 0x00000000(软件可通过 VBAR 重映射)。
      • 1:基地址为 0xFFFF0000(高地址向量,不可重映射)。
    • Bit 12 (I 位):指令 Cache 开关。
  • VBAR (Vector Base Address Register, c12):向量基地址寄存器,用于重新映射异常向量表的基地址。在IMX6ULL中,我们将向量表重映射到 0x87800000。
  • CBAR (Configuration Base Address Register, c15):配置基地址寄存器,指向GIC控制器的物理基地址。

三、代码实现:中断驱动的按键控制

本文的核心目标是实现 "按键中断触发 LED 翻转 + 蜂鸣器翻转",遵循 "低耦合、高可扩展" 的设计原则。

3.1 向量表管理与初始化

首先,我们需要定义一个中断服务函数指针数组,用于注册和管理中断。

// 定义中断向量表 typedef void (*irq_handler_t)(void); irq_handler_t Vector_table[160]; // 系统中断初始化 void system_interrupt_init(void) { // 1. 重映射异常向量表基地址 __set_VBAR(0x87800000); // 2. 初始化GIC控制器 GIC_Init(); } // 注册中断处理函数 int system_interrupt_register(IRQn_Type irq, irq_handler_t handler) { if (irq > PMU_IRQ2_IRQn || irq < IOMUXC_IRQn) return -1; if (handler == NULL) return -2; Vector_table[irq] = handler; // 将中断号与处理函数关联 return 0; }

3.2 GPIO 与中断配置

在 key_init 中,我们不仅配置 GPIO 为输入,还需要配置 GPIO 的中断触发方式和使能。

  • 复用配置:将 UART1_CTS_B 复用为 GPIO1_IO18。
  • 电气特性:配置上拉电阻和输入迟滞。
  • 中断触发:配置 GPIO1->ICR2 寄存器,选择下降沿触发(按下时电平由高变低)。
  • 中断使能:配置 GPIO1->IMR 寄存器,置位对应位以允许中断。
void key_init(void) { // 1. 复用功能配置 IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0); // 2. 电气特性配置 IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0xF0B0); // 3. 引脚方向设置为输入模式 GPIO1->GDIR &= ~(1 << 18); // 4. 配置中断触发方式 (ICR2寄存器,bit4-5对应GPIO1_18) GPIO1->ICR2 |= (3 << 4); // 下降沿触发 // 5. 中断屏蔽寄存器 (IMR) - 解除屏蔽 GPIO1->IMR |= (1 << 18); // 6. GIC配置 GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn); // 使能该中断 GIC_SetPriority(GPIO1_Combined_16_31_IRQn, 0); // 设置优先级 // 7. 注册回调函数 system_interrupt_register(GPIO1_Combined_16_31_IRQn, key_irq_handler); }

3.3 中断服务函数 (ISR)

当中断发生时,CPU会跳转到对应的处理函数。

void key_irq_handler(void) { // 检查GPIO中断状态寄存器 (ISR) // 注意:ISR用于指示中断是否发生,IMR用于使能/屏蔽。 if ((GPIO1->ISR & (1 << 18)) != 0) { // 执行业务逻辑:翻转LED和蜂鸣器 led_nor(); beep_nor(); // 必须手动清除中断标志位 GPIO1->ISR |= (1 << 18); } }

3.4 主程序流程

主程序在初始化完成后,进入无限循环,此时CPU可以自由执行其他任务(如 g_delay),而按键的中断请求会被GIC捕获并打断主循环。

int main(void) { system_interrupt_init(); // 初始化中断系统 clock_cg_init(); // 开启时钟 beep_init(); led_init(); key_init(); // 配置按键中断 while (1) { g_delay(0x7FFFF); // 主循环执行耗时任务,但不会阻塞中断响应 } return 0; }

四、软件设计原则:低耦合与 OCP

在编写中断驱动代码时,我们遵循了良好的软件工程原则:

  1. 低耦合:
    1. 中断模块只负责中断的底层处理(如向量表管理)。
    2. GPIO模块只负责引脚的输入输出。
    3. 业务逻辑(按键处理)独立封装。
  2. 开闭原则 (OCP):
    1. 对修改关闭:核心的中断分发逻辑(system_interrupt_handler)不需要因为新增设备而修改。
    2. 对扩展开放:当需要增加一个新的按键或设备时,只需调用 system_interrupt_handler 注册一个新的函数指针,无需改动核心代码。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 20:28:07

Qwen3-1.7B客服机器人集成:Webhook调用详细步骤

Qwen3-1.7B客服机器人集成&#xff1a;Webhook调用详细步骤 Qwen3-1.7B 是阿里巴巴通义千问系列中的一款高效轻量级语言模型&#xff0c;适用于对响应速度和部署成本敏感的场景。尤其在构建智能客服系统时&#xff0c;该模型凭借其较小的参数规模与出色的对话理解能力&#xf…

作者头像 李华
网站建设 2026/5/20 13:40:27

Qwen-Image-2512显存占用过高?量化压缩技术实战优化方案

Qwen-Image-2512显存占用过高&#xff1f;量化压缩技术实战优化方案 你是不是也遇到过这种情况&#xff1a;想用最新的Qwen-Image-2512模型生成高清大图&#xff0c;结果刚加载模型就提示“显存不足”&#xff1f;明明是4090D这样的高端显卡&#xff0c;却只能眼睁睁看着它卡在…

作者头像 李华
网站建设 2026/5/11 16:43:56

教育资源数字化转型:基于Qwen的课件配图生成部署实践

教育资源数字化转型&#xff1a;基于Qwen的课件配图生成部署实践 在当前教育内容制作中&#xff0c;教师和课程开发者常常面临一个现实问题&#xff1a;如何快速为低龄儿童设计出既生动又安全的视觉素材&#xff1f;传统方式依赖设计师手动绘制或从图库中筛选&#xff0c;耗时…

作者头像 李华
网站建设 2026/5/20 14:21:07

实战场景解析:如何高效运用osquery进行系统监控与安全防护

实战场景解析&#xff1a;如何高效运用osquery进行系统监控与安全防护 【免费下载链接】osquery 项目地址: https://gitcode.com/gh_mirrors/osq/osquery osquery作为一款强大的端点监控工具&#xff0c;能够通过SQL查询实时监控系统状态&#xff0c;帮助开发者和运维人…

作者头像 李华
网站建设 2026/5/21 8:12:39

新手避坑指南:使用PyTorch通用镜像常见问题全解

新手避坑指南&#xff1a;使用PyTorch通用镜像常见问题全解 1. 引言&#xff1a;为什么你需要这份避坑指南&#xff1f; 你是不是也遇到过这种情况&#xff1a;兴致勃勃地拉取了一个PyTorch开发镜像&#xff0c;准备大展身手训练模型&#xff0c;结果刚进环境就卡在了第一步—…

作者头像 李华
网站建设 2026/5/23 4:23:04

Java网络编程学习笔记,从网络编程三要素到TCP/UDP协议

什么是网络编程 什么是网络编程&#xff0c;相比于编写程序在本机上运行&#xff0c;网络编程是指编写两台不同的计算机的程序&#xff0c;基于网络协议&#xff0c;通过网络进行数据通信。 常见的网络程序软件架构有&#xff1a;BS&#xff08;Broser浏览器/Server服务器&am…

作者头像 李华