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

ARM Cortex-M 32位MCU无锁64位计数器实现问题咨询

ARM Cortex-M3 32位平台64位无锁计数器实现问题解答

1. atomic_uint_least64_t能否正常工作?

可以正常工作。C11标准的原子类型atomic_uint_least64_t会让编译器自动生成符合平台要求的原子操作代码——对于ARM Cortex-M3这类支持LDREX/STREX指令的32位架构,编译器会直接生成基于这组指令的64位原子读写、自增逻辑,完全避免你描述的那种高低位拆分更新导致的竞态问题。因为原子操作是针对完整64位值的,不会出现线程A更新低位后、线程B插入修改,再导致高位更新遗漏的情况。

2. 是不是最优方案?

是最优方案。相比手写LDREX/STREX汇编实现,标准C原子类型有两个核心优势:

  • 可移植性:代码不依赖特定平台的汇编指令,换其他支持C11原子的平台无需修改;
  • 可读性与维护性:用标准库函数(atomic_fetch_add、atomic_load)实现逻辑,比手写汇编更清晰,降低出错概率。
    从效率上看,编译器生成的原子操作代码和手写汇编几乎无差异,不会有性能损失。

3. 解决链接错误的方法

你遇到的undefined reference to '__atomic_load_8'和找不到-latomic的问题,根源是arm-none-eabi-gcc针对Cortex-M3这类硬件支持原子操作的平台,默认不需要链接libatomic库,且多数arm-none-eabi工具链也不提供这个库(libatomic主要给不支持硬件原子操作的平台用)。解决步骤:

  • 编译时添加-std=c11或-std=gnu11参数,启用C11标准的原子特性;
  • 明确指定目标架构:添加-march=armv7-m参数,让编译器确认目标是Cortex-M3,直接生成LDREX/STREX指令而非依赖库函数;
  • 不要加-latomic参数,这个库对Cortex-M3平台无效。

示例代码

#include <stdatomic.h>
#include <stdint.h>

// 初始化64位原子计数器
atomic_uint_least64_t counter = ATOMIC_VAR_INIT(0);

// 原子自增操作
void counter_increment(void) {
    atomic_fetch_add(&counter, 1);
}

// 原子读取操作
uint64_t counter_read(void) {
    return atomic_load(&counter);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 03:35:26