news 2026/6/10 16:26:51

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/6/10 11:10:18

实测Qwen-Image-Layered图像分解能力,细节表现惊人

实测Qwen-Image-Layered图像分解能力&#xff0c;细节表现惊人 发布时间&#xff1a;2025年12月30日 作者&#xff1a;AITechLab 模型页面&#xff1a;https://huggingface.co/Qwen/Qwen-Image-Layered 官方仓库&#xff1a;https://github.com/QwenLM/Qwen-Image-Layered Qw…

作者头像 李华
网站建设 2026/6/10 12:34:42

语音质检系统搭建:基于FSMN-VAD的分割模块部署教程

语音质检系统搭建&#xff1a;基于FSMN-VAD的分割模块部署教程 1. FSMN-VAD 离线语音端点检测控制台 你是否在处理大量录音文件时&#xff0c;被冗长的静音片段拖慢了效率&#xff1f;是否希望有一套工具能自动帮你“剪掉”无效部分&#xff0c;只留下真正有价值的对话内容&a…

作者头像 李华
网站建设 2026/6/10 3:32:44

亲测Qwen3-VL-8B镜像:电商图片解析效果超乎想象

亲测Qwen3-VL-8B镜像&#xff1a;电商图片解析效果超乎想象 你有没有遇到过这样的场景&#xff1f; 一家中小电商运营人员&#xff0c;每天要审核200张商品图——主图是否合规、促销标签位置是否醒目、价格数字是否清晰可读、有没有违规文字……全靠人工一张张点开、放大、截图…

作者头像 李华
网站建设 2026/6/10 9:26:09

Harvester管理平台定制化配置指南

Harvester管理平台定制化配置指南 【免费下载链接】harvester 项目地址: https://gitcode.com/gh_mirrors/har/harvester 作为一款基于Kubernetes的现代化基础设施管理平台&#xff0c;Harvester让虚拟化资源管理变得前所未有的简单。今天&#xff0c;我将带你深入了解…

作者头像 李华
网站建设 2026/6/10 9:22:18

零配置部署:Live Avatar让AI数字人落地更简单

零配置部署&#xff1a;Live Avatar让AI数字人落地更简单 你是否也遇到过这样的困境&#xff1f;想用最新的AI数字人技术做虚拟主播、智能客服或教学助手&#xff0c;却被复杂的环境依赖、模型下载和参数调优卡在第一步。好不容易跑通代码&#xff0c;却发现显存爆了、推理卡顿…

作者头像 李华
网站建设 2026/6/10 9:29:02

深入探究.NET中Stream:灵活高效的数据流处理核心

深入探究.NET中Stream&#xff1a;灵活高效的数据流处理核心 在.NET开发领域&#xff0c;处理数据流是许多应用程序的关键任务&#xff0c;从文件读取、网络通信到内存数据操作等场景都离不开数据流处理。Stream类作为.NET中数据流处理的核心抽象&#xff0c;为开发者提供了一…

作者头像 李华