在gcc的CMSIS定义中,您可以找到以下内容:

static __INLINE void __DMB(void) { __ASM volatile ("dmb"); }

我的问题是:如果在障碍列表中未声明“内存”,则内存屏障有什么用?

是core_cm3.h中的错误,还是gcc在没有任何其他帮助的情况下应该正确运行的原因?

最佳答案

我使用gcc 4.5.2(使用LTO构建)进行了一些测试。如果我编译此代码:

static inline void __DMB(void) { asm volatile ("dmb"); }
static inline void __DMB2(void) { asm volatile ("dmb" ::: "memory"); }

char x;

char test1 (void)
{
  x = 15;
  return x;
}

char test2 (void)
{
  x = 15;
  __DMB();
  return x;
}

char test3 (void)
{
  x = 15;
  __DMB2();
  return x;
}

使用arm-none-eabi-gcc -Os -mcpu=cortex-m3 -mthumb -c dmb.c,然后从arm-none-eabi-objdump -d dmb.o我得到:
00000000 <test1>:
   0:   4b01        ldr r3, [pc, #4]    ; (8 <test1+0x8>)
   2:   200f        movs    r0, #15
   4:   7018        strb    r0, [r3, #0]
   6:   4770        bx  lr
   8:   00000000    .word   0x00000000

0000000c <test2>:
   c:   4b02        ldr r3, [pc, #8]    ; (18 <test2+0xc>)
   e:   200f        movs    r0, #15
  10:   7018        strb    r0, [r3, #0]
  12:   f3bf 8f5f   dmb sy
  16:   4770        bx  lr
  18:   00000000    .word   0x00000000

0000001c <test3>:
  1c:   4b03        ldr r3, [pc, #12]   ; (2c <test3+0x10>)
  1e:   220f        movs    r2, #15
  20:   701a        strb    r2, [r3, #0]
  22:   f3bf 8f5f   dmb sy
  26:   7818        ldrb    r0, [r3, #0]
  28:   4770        bx  lr
  2a:   bf00        nop
  2c:   00000000    .word   0x00000000

显然,__DBM()仅插入dmb指令,并且需要DMB2()才能实际迫使编译器刷新寄存器中缓存的值。

我想我发现了CMSIS错误。

关于gcc - CMSIS库中针对Cortex-M3的数据存储屏障(DMB),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6751605/

10-11 16:02