簡體   English   中英

用於 Cortex-M3 的 CMSIS 庫中的數據 Memory 屏障 (DMB)

[英]Data Memory Barrier (DMB) in CMSIS libraries for Cortex-M3s

在 gcc 的 CMSIS 定義中,您可以找到如下內容:

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

我的問題是:如果 memory 屏障沒有在 clobber 列表中聲明“內存”,它有什么用?

是 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 錯誤。

恕我直言,CMSIS 版本是正確的。

在 clobber 列表中注入沒有 memory 的屏障指令可以完全實現它應該做的事情:

如果先前對“x”變量的寫入被緩沖,則它被提交。 這很有用,例如,如果您要將“x”地址作為 DMA 地址傳遞,或者如果您要設置 MPU。

它對返回“x”沒有影響(即使您省略 memory 屏障,您的程序也保證是正確的)。

另一方面,通過在 clobber 列表中插入 memory ,在前面的示例(DMA,MPU ..)這樣的情況下,您沒有任何效果。

后一種情況的唯一區別是,如果你有一個 ISR 在 "strb" 之后修改 "x" 的值,那么將返回的值是 ISR 修改的值,因為 clobber 導致編譯器從 memory 讀取以再次注冊。 但是如果你想獲得這個東西,那么你應該使用“易失性”變量。

In other words: the barrier forces cache vs memory commit in order to guarantee consistency with other HW resources that might access RAM memory, while clobbering memory causes compiler to stop assuming the memory has not changed and to read again in local registers, that is another具有不同目的的東西(memory 更改是否仍在緩存中或已經提交到 RAM 中並不重要,因為最終的 asm 加載操作保證在兩種情況下都可以正常工作)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM