c语言 - Cortex M3, STM32, thumb2: 我的 inc 和 dec 操作不是原子的,但应该是原子的。这是怎么回事?



我需要一个线程保存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;
dbgIdx8 ++;
080058BE   LDR            R3, [PC, #48]                 
080058C0   LDRB           R3, [R3]
080058C2   UXTB           R3, R3
080058C4   ADDS           R3, #1
080058C6   UXTB           R2, R3
080058C8   LDR            R3, [PC, #36]                 
080058CA   STRB           R2, [R3]
dbgIdx16 ++;
080058CC   LDR            R3, [PC, #36]                 
080058CE   LDRH           R3, [R3]
080058D0   UXTH           R3, R3
080058D2   ADDS           R3, #1
080058D4   UXTH           R2, R3
080058D6   LDR            R3, [PC, #28]                 
080058D8   STRH           R2, [R3]
dbgIdx32 ++;
080058DA   LDR            R3, [PC, #28]                 
080058DC   LDR            R3, [R3]
080058DE   ADDS           R3, #1
080058E0   LDR            R2, [PC, #20]                 
080058E2   STR            R3, [R2]

不能保证++--是原子的。如果你需要保证原子性,你将不得不寻找其他的方法。

正如@StaceyGirl在评论中指出的那样,你也许可以使用

  1. ARM皮质内核不修改内存。所有的内存修改都是作为RMW(读-修改-写)操作执行的,默认情况下,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位数据类型(您希望锁定尽可能短的时间)。大多数较短的数据类型操作都添加了一些额外的代码。

相关内容

  • 没有找到相关文章

最新更新