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

Cortex-M33 LDREX/STREX原子RMW操作STREX返回1问题咨询

问题背景
  • 开发环境:基于ARM Cortex-M33器件开展开发,目标器件无原生位带(bit-banding)支持,需要自定义实现原子读-改-写(RMW)位操作例程
  • 故障表现:使用-O0优化等级(关闭编译优化)编译代码时,编译器会在__LDREXW与__STREXW指令之间插入标准栈存储(STR)指令,导致STREX指令持续返回1(操作失败),最终触发无限重试死循环
  • 原始故障实现代码:
/* Atomic Bit Set using Exclusive Load/Store Primitives */
void bb_set_bit(volatile uint32_t *addr, uint32_t bit)
{
     uint32_t value;
     uint32_t status;
     do {
         value = __LDREXW(addr);
         value |= (1UL << bit);
         status = __STREXW(value, addr);
     } while (status != 0);
}
核心技术问题解答

STREX返回状态值1的行为逻辑

Cortex-M33的独占访问机制依赖本地独占监视器标记独占访问权限合法性:

  • 执行LDREX类独占加载指令时,硬件会将本地独占监视器置为有效状态,标记当前执行流持有对应地址区间的独占访问权限
  • 只要在LDREX和配对的STREX之间出现任意以下情况,独占监视器会被立刻清除为无效状态:
    • 执行了任意非独占的内存存储指令(包括对栈空间的STR写入、对其他任意地址的普通存储操作)
    • 触发异常进入中断服务流程,且中断上下文执行了存储操作或CLREX指令清除独占标记
    • 总线上其他主控设备对当前独占监控的地址区间执行了写入操作
  • 当STREX执行时检测到独占监视器为无效状态,将不会完成目标地址的写入操作,直接返回状态值1代表本次独占访问失败;只有独占标记有效时才会完成写入,返回0代表操作成功。

场景下的死循环判定

该场景下程序会永久卡在重试循环中,根因是-O0优化下编译器不会执行寄存器分配优化,默认将所有局部变量分配到栈空间存储,每次循环的执行流程完全固定:

  1. 执行__LDREXW加载目标地址值,置位本地独占监视器为有效状态
  2. 执行位或运算修改value后,通过STR指令将value写回栈内存,该操作直接清除独占监视器的有效状态
  3. 执行__STREXW尝试写回目标地址,此时已无合法独占权限,固定返回1
  4. 检测到返回值不为0,回到循环起始位置重复上述流程,永远无法满足退出循环的条件。
修复方案
  • 对独占访问区间内使用的局部变量添加register关键字修饰,强制编译器将这类变量分配到通用寄存器,从根源上避免在LDREX和STREX之间生成栈存储指令,修改后代码如下:
void bb_set_bit(volatile uint32_t *addr, uint32_t bit)
{
     register uint32_t value;
     register uint32_t status;
     do {
         value = __LDREXW(addr);
         value |= (1UL << bit);
         status = __STREXW(value, addr);
     } while (status != 0);
}
  • 添加编译器屏障约束,阻止编译器在独占加载和独占存储指令之间插入任意内存操作,GCC/Arm Compiler环境下可在LDREX调用前插入asm volatile("" ::: "memory")实现约束。
  • 注意:-O1及以上优化等级下,编译器默认会将短生命周期的局部变量分配到寄存器,不会触发该问题,但生产级代码不能依赖优化等级规避问题,必须显式添加变量修饰或编译屏障做强制约束。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:31:04