news 2026/7/4 9:25:23

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/7/1 3:41:31

FunASR speech_ngram_lm_zh-cn 语音识别实战|WebUI一键部署方案

FunASR speech_ngram_lm_zh-cn 语音识别实战&#xff5c;WebUI一键部署方案 1. 项目背景与核心价值 你有没有遇到过这样的场景&#xff1a;会议录音要整理成纪要、课程内容想快速转为文字笔记&#xff0c;或者视频素材需要生成字幕&#xff1f;传统方式靠人工听写&#xff0c…

作者头像 李华
网站建设 2026/7/1 20:30:33

AutoGLM-Phone验证码场景处理?人工介入机制实战教程

AutoGLM-Phone验证码场景处理&#xff1f;人工介入机制实战教程 1. Open-AutoGLM&#xff1a;智谱开源的手机端AI Agent框架 你有没有想过&#xff0c;让AI帮你操作手机——不只是发个消息、点个赞&#xff0c;而是像真人一样理解屏幕内容、完成复杂任务&#xff1f;比如&…

作者头像 李华
网站建设 2026/7/2 17:49:35

YOLOv12镜像如何提升训练稳定性?这里有答案

YOLOv12镜像如何提升训练稳定性&#xff1f;这里有答案 你是否也遇到过这样的情况&#xff1a;满怀期待地启动YOLOv12训练任务&#xff0c;结果几个epoch后loss突然爆炸&#xff0c;梯度疯狂震荡&#xff0c;显存占用节节攀升&#xff0c;最终只能无奈中断&#xff1f;别急&am…

作者头像 李华
网站建设 2026/7/1 15:33:49

YOLOv13实战应用:用官版镜像快速实现物体识别

YOLOv13实战应用&#xff1a;用官版镜像快速实现物体识别 1. 引言&#xff1a;为什么选择YOLOv13与官版镜像&#xff1f; 你是否还在为配置目标检测环境而烦恼&#xff1f;下载依赖、解决版本冲突、编译加速库……每一步都可能卡住进度。今天&#xff0c;我们换一种更高效的方…

作者头像 李华
网站建设 2026/7/1 21:57:29

FSMN-VAD部署监控:日志记录与性能指标采集教程

FSMN-VAD部署监控&#xff1a;日志记录与性能指标采集教程 1. 引言&#xff1a;构建可监控的FSMN-VAD服务 你已经成功部署了基于达摩院FSMN-VAD模型的语音端点检测服务&#xff0c;能够精准识别音频中的有效语音片段。但如果你希望将这个工具用于生产环境或长期运行的任务&am…

作者头像 李华
网站建设 2026/6/30 13:21:52

无需GPU配置!Paraformer镜像自动适配环境快速启动

无需GPU配置&#xff01;Paraformer镜像自动适配环境快速启动 你是否还在为语音识别模型部署复杂、依赖繁多而头疼&#xff1f; 想快速实现中文语音转文字&#xff0c;却卡在环境配置、模型下载和代码调试上&#xff1f; 今天介绍的这个AI镜像——Paraformer-large语音识别离…

作者头像 李华