![](/img/trans.png)
[英]Need explanation of ARM Cortex-M3 assembly instruction in CMSIS to __set_PRIMASK
[英]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.