当前位置: 首页 > ds >正文

【STM32】中断软件分支处理( NVIC 和 GIC)

中断软件分支处理、NVIC 和 GIC 是嵌入式系统和操作系统内核中非常关键的内容,尤其在 Cortex-MCortex-A 架构中有很大差别。本篇博客将分别介绍三者之间的关系。这部分内容涉及ARM 架构中断系统的底层机制,也是理解嵌入式系统、操作系统内核、驱动开发的关键知识。所以在我们接下来的文章向下一个阶段推进之前,我必须以系统化的方式向您详细介绍这三者的本质、区别与联系。

一、什么是中断软件分支处理?

中断软件分支(Software Interrupt Vectoring)的定义:

CPU 收到中断信号后,不通过硬件自动跳转,而是通过软件跳转到对应中断服务函数的机制。


详细点说:
中断发生后,CPU 不直接跳转到某个固定地址处理函数,而是进入统一入口,由软件读取中断号,再“查表跳转”到具体中断服务函数(ISR) 的机制。

一些前置概念先导:

中断					CPU 在执行程序时,被外部或内部事件打断,转去执行专门处理函数的机制
中断控制器(IC)		硬件模块,管理多个中断源,决定中断优先级、分发给哪个 CPU
中断向量表			存储中断处理函数地址的表,CPU 通过它跳转到对应中断处理逻辑
软件分支处理			CPU 进入统一异常入口后,由软件识别中断号并跳转到对应处理函数
中断软件分支详细示意流程:
graph TDA[外设产生中断] --> B[NVIC or GIC]B --> |Cortex-M| C[NVIC 处理]C --> D[CPU 跳转向量表]D --> E[ISR 执行]B --> |Cortex-A| F[GIC 分发]F --> G[CPU 进入统一入口]G --> H[读取中断号]H --> I[软件查表跳转 ISR]

这种方式便于用户空间自定义中断行为,常用于高级操作系统如 Linux


中断处理有两种方式:

中断控制器(IC):中断控制器是 CPU 的“中断信号调度中心”。它决定了:哪个中断优先响应?哪个 CPU 核来处理?中断号是多少?而这时候便出现了两大主流:1、NVIC(Cortex-M 内建);2、GIC(Cortex-A 外设)。

  • 硬件向量分支(如 Cortex-M)
    • CPU 自动从 中断号 × 4 + 向量基地址 中读取跳转地址
    • 由硬件完成中断分发和跳转
    • 使用 NVIC(Nested Vectored Interrupt Controller)
  • 软件分支派发(如 Cortex-A)
    • 所有中断统一进入一个入口地址(如 __irq_svc
    • 由软件读取中断号(从中断控制器),通过查表跳转到对应 ISR
    • 使用 GIC(Generic Interrupt Controller)

中断控制器架构分层模型
+-----------------------------+
|       外设设备(GPIO/UART)|
+-----------------------------+│▼
+-----------------------------+
| 中断控制器(NVIC / GIC)     |
| - 优先级控制                |
| - 中断屏蔽                  |
| - 中断号分配                |
| - 目标 CPU 分发(GIC)       |
+-----------------------------+│▼
+-----------------------------+
|    CPU 异常入口(向量表)   |
| - NVIC:自动跳转           |
| - GIC:统一入口 + 软件分派  |
+-----------------------------+│▼
+-----------------------------+
| 中断服务函数(ISR)        |
+-----------------------------+

二、NVIC(Nested Vectored Interrupt Controller)

适用于 ARM Cortex-M 系列(如 STM32) 的中断控制器。

✅ NVIC 特点:

内嵌在 Cortex-M 内核中,处理速度快
每个中断有唯一入口地址(ISR),在向量表中定义
自动保存/恢复上下文(部分寄存器)
特性说明
内置于 Cortex-M 内核无需外部中断控制器
支持中断嵌套优先级分组机制
编号由芯片厂商定义通常 IRQn_Type 枚举
中断入口固定硬件自动跳转,无需软件分发
优先级控制支持抢占优先级和响应优先级

✅ NVIC 相关函数(CMSIS):

NVIC_EnableIRQ(IRQn);         // 开启中断
NVIC_DisableIRQ(IRQn);        // 关闭中断
NVIC_SetPriority(IRQn, prio); // 设置优先级

✅ 向量表结构(以 STM32 为例):

const void* vector_table[] __attribute__((section(".isr_vector"))) = {(void*) &__StackTop,Reset_Handler,NMI_Handler,HardFault_Handler,...TIM2_IRQHandler,  // IRQ #28
};

📘 NVIC 示例:STM32 定时器中断

// 向量表中注册 ISR
void TIM2_IRQHandler(void) {HAL_TIM_IRQHandler(&htim2);
}// NVIC 设置优先级 & 使能中断
NVIC_SetPriority(TIM2_IRQn, 1);
NVIC_EnableIRQ(TIM2_IRQn);

✅ NVIC 中断流程图(硬件向量跳转):

外设产生中断 (如 TIM2)↓
NVIC 确认中断未屏蔽 → 比较优先级↓
CPU 自动跳转到向量表对应地址↓
执行 ISR(例如 TIM2_IRQHandler)↓
中断返回 → 恢复主流程

三、GIC(Generic Interrupt Controller)

适用于 ARM Cortex-A 系列(如 A7、A53、A55) 的中断控制器,主要用于运行 Linux、Android 的多核系统。

请添加图片描述

✅ GIC 架构组成(通常为 GICv2/v3):

组件说明
Distributor(GICD)接收中断请求,决定目标 CPU
CPU Interface(GICC)每个核对应的本地接口,控制本地中断处理
SGI软件生成中断
PPI私有外设中断(每核独享)
SPI共享外设中断(所有核共享)

中断类型:

类型编号范围说明
SGI(软件中断)0–15用于核间通信
PPI(私有中断)16–31针对当前核
SPI(共享中断)32–1019外设中断,多个核共享

GIC 配置步骤(简化流程):

1. 读取中断号 GICC_IAR
2. 查表跳转 ISR(软件分支)
3. 执行中断服务函数
4. 写 GICC_EOIR 通知中断处理完毕

Linux 中的中断处理就是基于此机制:irq_desc[] → handle_irq()

✅ 中断流程(GIC + Linux):

  1. 外设产生中断 → GICD 接收
  2. GIC 判断目标 CPU → 投递中断
  3. CPU 接收中断 → 进入 __irq_svc
  4. 内核调用 gic_read_iar() 获取中断号
  5. 查找中断描述符 irq_desc[]
  6. 调用对应 ISR(驱动注册的 handler)
1. __irq_svc: 汇编级中断入口
2.arch_irq_handler_default()
3.gic_handle_irq()
4. → read GICC_IAR → 得到中断号
5.generic_handle_irq(irq)
6. → irq_desc[irq].handle_irq()
7. → ISR(驱动注册的中断处理函数)
8. → write GICC_EOIR 表示中断结束

在 Linux 内核中:

// Linux 中断通用框架
__irq_svc:         // 异常向量入口-> entry.S-> irq_handler-> gic_handle_irq()-> generic_handle_irq()-> irq_desc[irq].handle_irq()-> 驱动注册的 ISR

即:Linux 通过统一的中断入口 gic_handle_irq() 获取中断号 → 查表 → 跳转到目标 驱动注册的中断处理函数。

✅ GIC 中断流程图(软件分派):
外设产生中断(如 UART1)↓
GIC Distributor 接收中断请求↓
确定目标 CPU(如 CPU0)↓
CPU0 收到中断 → 跳转到统一入口地址(__irq_svc)↓
软件读取中断号(GICC_IAR)↓
调用 irq_desc[irq].handler → 驱动注册函数↓
处理中断逻辑 → 写 GICC_EOIR 结束↓
返回用户态
GIC 架构图(简化)
+----------------------+
|     GIC Distributor  |
|   - 接收中断          |
|   - 目标 CPU 核      |
|   - SPIs(共享中断)  |
+----------------------+|
+--------+--------+
| CPU Interface 0 |
| CPU Interface 1 |
| ...             |
+-----------------+每个 CPU 核 ↔ GICC ↔ GICD ↔ 外设

📘 GIC 示例:Linux 驱动中注册中断

// 设备驱动中注册 IRQ
int irq = platform_get_irq(pdev, 0);
request_irq(irq, my_irq_handler, 0, "my_device", NULL);irqreturn_t my_irq_handler(int irq, void *dev) {printk("Interrupt received!\n");return IRQ_HANDLED;
}

硬件向量(NVIC)vs 软件分支(GIC)对比
对比项NVIC(Cortex-M)GIC(Cortex-A)
适用架构Cortex-M 系列Cortex-A 系列
中断数量一般 < 256可达 1020 个
工作模式(CPU 自动跳转 ISR)硬件向量跳转(需要代码处理)软件跳转(中断分发)
统一入口 → 查表
响应速度更快稍慢但灵活
多核支持不支持支持分发到不同 CPU 核
中断类型外设中断SGI / PPI / SPI
驱动复杂度高,需内核支持
常用系统裸机开发、RTOSLinux、Android 系统

那么,从发者视角出发:何时使用哪种?

开发场景使用方式控制器
STM32 裸机 / FreeRTOSNVIC + 硬件向量表NVIC
Cortex-A + LinuxGIC + 软件中断派发GIC
多核系统GIC 分发到指定 CPUGIC
安全系统(TrustZone)GIC 支持 Secure/Non-Secure 中断GICv2/3/4

通过对比可见:

  • NVIC 适用于单核 MCU,如 STM32、GD32
  • GIC 适用于多核 SoC,如 RK3568、i.MX6、A7
  • 软件分派方式是 Linux 内核中断的核心机制

NVIC 是硬件自动跳转中断处理函数;GIC 需要软件读取中断号后手动跳转。中断软件分派是 GIC 的核心特征,NVIC 则通过硬件向量表处理。

综上,

NVIC 是硬件帮你跳转,GIC 是你自己跳转。中断软件分支是“跳转方式的选择”,NVIC 和 GIC 是“分发机制的差异”。
Cortex-M 使用 NVIC,靠硬件向量跳转;Cortex-A 使用 GIC,依赖软件中断分派。

在后续的学习路径中,不同阶段需要掌握的内容有:

阶段				内容								建议平台
初级				NVIC、CMSIS 中断函数				STM32 / GD32
提高				GIC 配置、SGI 使用				Cortex-A7 / RK3568
系统级			Linux 中断子系统源码分析			STM32MP157 / IMX6ULL
驱动级			request_irq / 中断注册机制		Linux 驱动开发

熟练掌握和运用 中断机制是成为驱动工程师的基础,所以进入Linux驱动前要先介绍这部分核心的内容。

以上,欢迎有从事同行业的电子信息工程、互联网通信、嵌入式开发的朋友共同探讨与提问,我可以提供实战演示或模板库。希望内容能够对你产生帮助!

http://www.xdnf.cn/news/19708.html

相关文章:

  • Rviz-Gazebo联动
  • C语言数据结构之双向链表
  • 详细介绍 JMeter 性能测试
  • Mac idea 格式化代码快捷键
  • 第 94 场周赛:叶子相似的树、模拟行走机器人、爱吃香蕉的珂珂、最长的斐波那契子序列的长度
  • 【C++】什么是智能指针及应用
  • 六大关键步骤:用MES系统重构生产计划管理闭环
  • 从能耗黑洞到精准智控:ASCB2智慧空开重构高校宿舍用电能效模型
  • 均值滤波和中值滤波的简介、C语言实现和实测
  • Adobe Photoshop 2025 最新下载安装教程,附PS2025下载
  • 【项目】多模态RAG必备神器—olmOCR重塑PDF文本提取格局
  • 智慧水利系统解决方案-水利信息化平台
  • linux连接服务器sftp无法输入中文
  • 直播预告 | Excelize 跨语言实战
  • 代码随想录二刷之“回溯”~GO
  • Linux系统中yum包管理器安装软件时遇到的网络连接问题
  • 线上API接口响应慢?一套高效排查与定位问题的心法
  • 【frontend】w3c的发展历史ToDo
  • 基于Springboot + vue3实现的时尚美妆电商网站
  • MySQL 之索引的结构、分类与语法
  • 四个典型框架对比
  • 在 Unity 中调用腾讯云机器翻译
  • 一个好的智能体框架应该是什么样子
  • Activiti流程引擎的用户体系与MIS系统的用户体系打通
  • 一、Git与Gitee常见问题解答
  • 深度学习跨领域应用探索:从技术落地到行业变革
  • pcl案例2 叶片与根茎的分离step2
  • MyBatis 性能优化最佳实践:从 SQL 到连接池的全面调优指南
  • Java网络编程基础 Socket通信入门指南
  • 机器视觉软件--VisionPro、Visual Master,Halcon 和 OpenCV 的学习路线