皮质M3、STM32、thumb2:我的inc和dec操作不是原子的,但应该是,怎么了?

0md85ypi  于 2023-08-03  发布在  其他
关注(0)|答案(2)|浏览(118)

我需要一个线程保存idx++和idx--操作。禁用中断,即使用临界区是一回事,但我想知道为什么我的操作不是原子的,正如我所期望的那样?下面是使用segger ozone显示的内联汇编代码的C代码:(另外请注意,变量的地址显示32位变量在内存中是32位对齐的,8位和16位变量都是16位对齐的)

volatile static U8 dbgIdx8 = 1000U;
volatile static U16 dbgIdx16 = 1000U;
volatile static U32 dbgIdx32 = 1000U;

个字符

ozxc1zmp

ozxc1zmp1#

不能保证++--是原子的。如果你需要保证原子性,你将不得不找到一些其他的方法。
正如@StaceyGirl在评论中指出的那样,您可能可以使用<stdatomic.h>的设施。例如,我看到定义了一个原子atomic_fetch_add函数,它的作用类似于您正在努力实现的后缀++。还有一个atomic_fetch_sub
或者,您可能有一些编译器内部函数可供您使用,以便以某种特定于处理器的方式执行原子增量。

k0pti3hp

k0pti3hp2#

  1. ARM Cortex内核不会修改内存。所有内存修改都作为RMW(读取-修改-写入)操作执行,默认情况下这些操作不是原子操作。
    但是Cortex M3有特殊的指令来锁定对内存位置的访问。LDREX和STREX。https://developer.arm.com/documentation/100235/0004/the-cortex-m33-instruction-set/memory-access-instructions/ldaex-and-stlex
    您可以直接在C代码中使用它们,而不需要使用intrinsic。
    1.不要在任何对性能敏感的程序中使用非32位数据类型(您希望锁定尽可能短的时间)。大多数较短的数据类型操作都会添加一些额外的代码。

相关问题