news 2026/4/18 6:30:52

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

作者头像

张小明

前端开发工程师

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

城市仿真软件:CityEngine_(11).城市规划与设计实践

城市规划与设计实践 在上一节中,我们探讨了城市仿真软件的基本功能和应用场景。接下来,我们将深入到城市规划与设计的实践部分,通过具体的案例和代码示例,展示如何利用CityEngine进行城市模型的创建、编辑和仿真。本节将涵盖以下…

作者头像 李华
网站建设 2026/4/16 23:21:43

MySQL介绍

一、MySQL1. MySQL是什么?(简单直白版)想象一下,你开了一家超级棒的奶茶店,每天要记录:顾客点的奶茶口味顾客的联系方式每天的销售数据仓库里的原料库存如果用Excel表格记录,当数据量达到10万条…

作者头像 李华
网站建设 2026/4/17 13:03:02

解决requestFullscreen()全屏模式下复制功能丢失问题

引入js公共方法 export async function copyToClipboard(text, options = {}) { const { showMessage = true, onSuccess, onError, } = options // 优先使用新的 Clipboard API if (navigator.clipboard && window.isSecureContext) { try { await navigator.clipboar…

作者头像 李华
网站建设 2026/4/17 20:25:27

C#每日面试题-进程和线程的区别

C#每日面试题-进程和线程的区别 在C#面试的基础高频题中,“进程和线程的区别”绝对占有一席之地。很多新手会把两者理解成“大程序和小程序”的关系,实则不然——它们是操作系统资源管理和任务调度的两个核心层级,核心定位、资源占用、调度方…

作者头像 李华
网站建设 2026/4/18 5:37:02

DeviceNet转ProfiNet工业网关助力风机振动在线诊断

一、项目背景 华东某大型生物制药集团 2025 年新建“注射用头孢冻干制剂追溯线”,要求每一瓶、每一盒、每一箱都必须具备符合《药品追溯码编码要求》(NMPA 2022 年 12 号令) 的唯一序列化标签。整条产线由西门子 SIMATIC S7-1500 统一调度,现场级网络采用…

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

Windows系统文件ucrtbase.dll丢失损坏 免费下载方法

在使用电脑系统时经常会出现丢失找不到某些文件的情况,由于很多常用软件都是采用 Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC运行库或者安装…

作者头像 李华