You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cortex-M3/4/7的CMSIS是否有ATOMIC_INC?自定义实现是否可靠?

针对你的问题的解答

1. ATOMIC_MODIFY_REG的归属

这个宏不是标准CMSIS的一部分,是ST在STMCubeIDE中提供的自定义原子操作扩展。标准CMSIS仅封装了__LDREXW、__STREXW这类底层汇编指令的接口,ATOMIC_MODIFY_REG是ST基于这些指令实现的上层宏。

2. 关于ATOMIC_INC/DEC的思路合理性

你的思路完全没问题——原子增减的核心逻辑和ATOMIC_MODIFY_REG一致,都是靠LDREX/STREX的独占访问+循环重试机制来避免竞争。实际上标准CMSIS和编译器本身已经提供了原子增减的实现:

  • 底层可以直接用__LDREXW/__STREXW手动实现循环
  • GCC/ARMCC这类编译器也支持__atomic_inc、__atomic_dec这类内建函数,只是ST没把它们封装成类似ATOMIC_MODIFY_REG的宏而已。

3. 基于ATOMIC_MODIFY_REG改造实现原子增减

你可以直接修改宏逻辑来实现,比如:

原子递增宏

#define ATOMIC_INC(REG)                    \
  do {                                     \
    uint32_t val;                          \
    do {                                   \
      val = __LDREXW((__IO uint32_t *)&(REG)) + 1U; \
    } while ((__STREXW(val, (__IO uint32_t *)&(REG))) != 0U); \
  } while(0)

原子递减宏

#define ATOMIC_DEC(REG)                    \
  do {                                     \
    uint32_t val;                          \
    do {                                   \
      val = __LDREXW((__IO uint32_t *)&(REG)) - 1U; \
    } while ((__STREXW(val, (__IO uint32_t *)&(REG))) != 0U); \
  } while(0)

这个实现的原子性是可靠的:LDREX会给目标内存地址打上独占访问标记,STREX只有在标记未被其他操作(比如中断、多核心访问)破坏时才会写入成功;一旦写入失败(返回非0),循环会重新读取最新值再执行操作,直到成功完成。

4. 原子性的验证方法

验证原子性确实需要针对性测试,推荐两种实用方法:

  • 中断抢占测试:在主循环中持续调用原子增减操作修改一个全局变量,同时在高优先级中断里也对同一个变量执行相同操作。运行足够长时间(比如几十万次循环)后,检查变量最终值是否等于主循环操作次数加上中断触发次数的总和(递增场景)。如果数值完全匹配,说明原子性有效;如果出现少增/少减,说明存在竞争问题。
  • 多核心测试(仅限带双核心的M7芯片):让两个核心同时对同一个共享变量执行增减操作,统计总操作次数和变量最终值是否一致。单核心场景下,中断测试就足以覆盖绝大多数竞争情况。

内容的提问来源于stack exchange,提问作者Martin_from_K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:15:30