2011-07-19 20 views
5

ためのCMSISライブラリ内(DMB):データメモリバリアあなたはこのような何かを見つけることができますgccのためCMSIS定義でのCortex-M3S

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

私の質問です:それがない場合は、メモリバリア持っていないものを使用clobberリストに「メモリ」と宣言していないのですか?

core_cm3.hにはエラーがありますか、それともgccが何の助けもなく正しく動作する理由はありますか?

+1

良い質問です。 Linuxは 'memory'クローバーを使います:http://lxr.free-electrons.com/source/arch/arm/include/asm/system.h?v=2.6.39#L135 – ninjalj

+1

@ninjalj:ありがとうございますリンク。 (すばやいグーグルで登場しませんでした) – jpc

答えて

5

私はgcc 4.5.2(LTOを使用して構築)でいくつかのテストを行いました。私はこのコードをコンパイルする場合:arm-none-eabi-gcc -Os -mcpu=cortex-m3 -mthumb -c dmb.cを使用して

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-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のバグを発見したと思います。

2

IMHO CMSISのバージョンが正しいです。

「X」変数の前の書き込みがバッファリングされた、それがコミットされた場合:クロバーリスト中のメモリのないバリア命令を注入

は、行うことになっているまさに実現しています。これは、たとえば、 "x"アドレスをDMAアドレスとして渡す場合、またはMPUを設定する場合に便利です。

"x"を返しても効果はありません(メモリバリアを省略してもプログラムは正しいことが保証されています)。

一方、メモリをクローバーリストに挿入すると、以前の例(DMA、MPU ..)のような状況では何の効果もありません。

後者の唯一の違いは、たとえば "strb"の直後に "x"の値を変更するISRがある場合、返される値はISRによって変更された値です。コンパイラーがメモリから読み込んで再度登録するようになりました。 しかし、このことを知りたければ、 "volatile"変数を使うべきです。

つまり、メモリを変更するとコンパイラはメモリが変更されていないと仮定して停止し、ローカルレジスタで再度読み込みを行いますが、RAMメモリにアクセスする可能性のある他のHWリソースとの一貫性を保証するためには、異なる目的を持つ別のものです(メモリ変更がキャッシュに残っているか、RAM上ですでにコミットされているかどうかは関係ありません。なぜなら、最終的なasmロード操作は両方の場合にバリアなしで動作することが保証されるからです)。

+1

しかし、 "x"への書き込みが障壁が実行された時点でキャッシュに全く当たらないように、コンパイラは周囲の命令を自由に並べ替えることはできませんか?コンパイラがメモリに変数をコミット(強制的にキャッシュ)してから、キャッシュを強制的にフラッシュするようにバリアを強制するように、メモリクローバーが必要でした。 – jpc

関連する問題