在 ARM 文档中,提到了
Cortex-M4 处理器支持 ARMv7 未对齐访问,并且 将所有访问作为单个、未对齐的访问来执行。他们是 由 DCode 和系统转换为两个或多个对齐的访问 总线接口。
我不清楚这是否意味着数据访问对于程序员来说是原子的。然后我发现 StackOverflow comment 将文档解释为:
实际上一些 ARM 处理器(例如 Cortex-M3)支持未对齐 在硬件中访问,因此即使未对齐的读/写也是原子的。访问权限 可能跨越多个总线周期到达内存,但没有机会 用于在两者之间跳转的另一条指令,因此它对于 程序员。
然而,我又环顾四周,发现声明与之前的声明相矛盾:
另一个事实是,在 ARMv6 及更高版本的内核上, 为了让硬件“修复”未对齐的访问,它会将其拆分 分成多个较小的字节负载。然而,这些不是原子的!.
那么,我该相信谁呢?对于某些上下文,我的项目中的 packed 结构中的每个元素都有 setter/getter。换句话说,某些结构体元素可能未对齐。我想知道在 Cortex-M4 上访问结构元素是否始终保证是原子的。如果不是,我想我将不得不手动启用/禁用中断或添加一些互斥体,但如果 ARM Cortex M4 可以保证数据访问是原子的,我宁愿不这样做。
不,不是。
请参阅ARMv7-M架构参考手册的A3.5.3节:
在 ARMv7-M 中,单副本原子处理器访问是:
- 所有字节访问。
- 所有半字访问半字对齐位置。
- 所有字访问字对齐位置
因此,如果您复制的 uint32 未与 32 位边界对齐(v7-M 中允许),则该副本不是原子的。
还引用:
当访问不是单副本原子时,它将作为一系列较小的访问执行,每个访问都是单副本原子的,至少在字节级别是这样。