news 2026/7/2 2:34:58

两种常见开关中断方式对比

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
两种常见开关中断方式对比

经常会遇到两种典型的中断禁用 / 启用实现:一种是基于纯汇编编写的Arch_IntSave/Arch_IntDisable函数,另一种是编译器内置的__enable_irq/__disable_irq内联函数,这两种的区别和功能具体拆解一下。

一、核心实现与功能拆解

1. 纯汇编实现:Arch_IntSave/Arch_IntDisable

.globl Arch_IntSave Arch_IntSave: MRS R0, PRIMASK @ 读取PRIMASK寄存器值到R0 CPSID I @ 禁用IRQ中断 BX LR @ 返回 .globl Arch_IntDisable Arch_IntDisable: CPSID I @ 禁用IRQ中断 BX LR @ 返回
  • 核心指令解析
    • MRS R0, PRIMASK:将 PRIMASK 寄存器(ARM Cortex-M 核心的中断屏蔽寄存器)的值读取到通用寄存器 R0 中。PRIMASK 是 1 位寄存器,值为 0 时表示中断未屏蔽,值为 1 时表示仅屏蔽普通 IRQ 中断(硬件 FAULT 类异常不受影响)。
    • CPSID I:修改 CPSR(当前程序状态寄存器)的 I 位,直接禁用所有普通 IRQ 中断。
    • BX LR:函数返回,ARM 汇编中通过链接寄存器 LR 返回调用处。

2. 编译器内联汇编实现:__enable_irq/__disable_irq

/** \brief Enable IRQ Interrupts \details Enables IRQ interrupts by clearing the I-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __enable_irq(void) { __ASM volatile ("cpsie i" : : : "memory"); } /** \brief Disable IRQ Interrupts \details Disables IRQ interrupts by setting the I-bit in the CPSR. Can only be executed in Privileged modes. */ __STATIC_FORCEINLINE void __disable_irq(void) { __ASM volatile ("cpsid i" : : : "memory"); }
  • 核心指令解析
    • __STATIC_FORCEINLINE:编译器强内联关键字,确保函数直接嵌入调用处,无函数调用开销。
    • __ASM volatile ("cpsie/cpsid i" : : : "memory"):内联汇编执行中断开关指令,volatile防止编译器优化该指令,memory约束告知编译器该指令会修改内存状态,避免内存重排序。
    • cpsie i:清除 CPSR 的 I 位,启用 IRQ 中断;cpsid i:设置 CPSR 的 I 位,禁用 IRQ 中断。

二、核心区别对比

1. 功能完整性:“仅禁用” vs “保存 + 禁用”

这是二者最核心的区别,也是嵌入式开发中最易踩坑的点:

  • Arch_IntDisable:仅执行CPSID I,单纯禁用中断,无任何状态保存;Arch_IntSave则在禁用中断前,先读取当前 PRIMASK 寄存器的值并通过 R0 返回 —— 这意味着Arch_IntSave保存中断禁用前的原始状态
  • __disable_irq:仅执行cpsid i禁用中断,无状态保存;__enable_irq仅执行cpsie i启用中断,二者均不涉及任何中断状态的读取或保存。

直接调用__disable_irq后调用__enable_irq,可能破坏系统原有中断状态 —— 若调用__disable_irq前中断已被禁用,执行__enable_irq会错误启用中断,导致临界区保护失效。

2. 调用开销:汇编函数 vs 内联函数

  • Arch_IntSave/Arch_IntDisable:作为独立汇编函数,调用时会产生函数调用开销(如 LR 寄存器入栈、PC 跳转),在对执行效率要求极高的临界区(如实时性要求微秒级的外设操作)中,额外开销可能影响性能。
  • __enable_irq/__disable_irq:通过__STATIC_FORCEINLINE实现强内联,汇编指令直接嵌入调用处,无函数调用开销,执行效率与直接写汇编指令一致。

内联汇编的中断操作指令,在编译器优化开启时(-O2/-O3),执行周期与纯汇编指令完全一致,且避免了函数调用的栈操作开销。

3. 状态恢复能力:可精准恢复 vs 强制恢复

  • Arch_IntSave:返回值为中断禁用前的 PRIMASK 状态,开发者可保存该值,在临界区结束后通过MSR PRIMASK, R0恢复原始中断状态 —— 即使调用前中断已被禁用,也不会错误启用。示例:
    ; 调用Arch_IntSave保存状态并禁用中断 BL Arch_IntSave PUSH R0 ; 保存原始PRIMASK值到栈 ; 临界区代码(如操作共享资源) POP R0 ; 取出原始PRIMASK值 MSR PRIMASK, R0 ; 恢复中断状态(而非强制启用)
  • __enable_irq:强制执行cpsie i启用中断,无论调用前中断状态如何,都会直接开启 IRQ—— 若临界区嵌套调用(如 A 函数禁用中断后调用 B 函数,B 函数执行__enable_irq),会导致 A 函数的临界区失去中断保护。

4. 可移植性与编译器兼容性

  • Arch_IntSave/Arch_IntDisable:纯汇编代码,与编译器无关(如 ARMCC、GCC、Clang 均可兼容),但依赖具体的 ARM 内核架构(仅适用于 Cortex-M 系列)。
  • __enable_irq/__disable_irq:属于编译器内置函数(如 ARMCC 的cmsis_gcc.hcmsis_armcc.h中定义),不同编译器的实现可能略有差异(如 GCC 需添加memory约束,ARMCC 则无需),但符合 CMSIS 标准的编译器均提供该接口,可移植性更强。

三、使用场景选择

1. 优先使用 Arch_IntSave 的场景

  • 临界区嵌套调用:如中断服务函数中调用其他需要禁用中断的函数,需保存原始中断状态,避免错误启用;
  • 精准控制中断状态:如仅临时禁用中断,执行完临界区后需完全恢复原有状态(而非强制启用);
  • 底层内核代码:如操作系统的任务切换、锁机制实现,需最大程度保证中断状态的准确性。

2. 优先使用__enable_irq/__disable_irq 的场景

  • 简单临界区:无嵌套调用的单次中断禁用 / 启用,如单次读写外设寄存器;
  • 跨编译器开发:项目需兼容 ARMCC、GCC 等多种编译器,遵循 CMSIS 标准;
  • 对执行效率要求极高:内联函数无调用开销,适合微秒级响应的实时场景。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/26 12:10:47

城市仿真软件:CityEngine_(10).建筑物与环境细节优化

建筑物与环境细节优化 在城市仿真软件中,建筑物与环境的细节优化是至关重要的一步,它直接影响到最终场景的真实感和用户体验。本节将详细介绍如何在CityEngine中进行建筑物与环境的细节优化,包括纹理优化、模型优化、光照优化以及环境效果的添…

作者头像 李华
网站建设 2026/6/26 4:49:02

城市仿真软件:CityEngine_(11).城市仿真案例分析

城市仿真案例分析 在前一节中,我们介绍了CityEngine的基本功能和使用方法。接下来,我们将通过具体的案例分析,进一步探讨如何利用CityEngine进行城市仿真。本节将涵盖以下几个方面:案例背景介绍数据准备模型构建规则文件编写仿真运…

作者头像 李华
网站建设 2026/7/1 4:45:36

Python RPA解放Excel生产力

一、环境准备:3行代码搭建自动化工具箱1. 核心库安装必装3件套:pandas:数据处理“瑞士军刀”,1行代码完成数据清洗;openpyxl:轻量级Excel写入工具,适合生成基础报表;xlwings&#xf…

作者头像 李华
网站建设 2026/6/30 6:20:42

Java毕设选题推荐:基于springboot的物流管理系统基于Springboot+Vue智能物流管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/6/26 8:04:30

基于MATLAB的图像处理实践:当工业零件遇上非均匀光照

标题:基于matlab的图像处理实践 关键词:otsu 非均匀照度 光照补偿 log函数和gamma函数 Dice和Hausdorff测度 工件有孔,无孔进行分类 中心点标记 描述:主要是使用图像处理算法处理非均匀光照图像,进行光照模型补偿&…

作者头像 李华
网站建设 2026/7/1 0:46:27

腾讯地图TMap标记反显,新增标记

功能: 1. 根据省市区获取对于的经纬度,设置为地图的center 2. 如果传入了经纬度,则在地图中反显 3. 根据输入内容,调用接口,获取关联关键字的地址列表,点击列表项后,根据地址经纬度,…

作者头像 李华