2017-03-07 22 views
4

32ビットのCortex-M3 ARMコントローラ(STM32L1)に64ビットの整数変数があります。これは割り込みハンドラで非同期に変更できます。cortex-m3で64ビットの揮発性変数を読み取る

volatile uint64_t v; 
void some_interrupt_handler() { 
    v = v + something; 
} 

明らかに、途中で更新された値が矛盾しないようにアクセスする方法が必要です。

ここ

は最初の試み

static inline uint64_t read_volatile_uint64(volatile uint64_t *x) { 
    uint64_t y; 
    __disable_irq(); 
    y = *x; 
    __enable_irq(); 
    return y; 
} 

あるCMSISのインライン関数__disable_irq()__enable_irq()は、コンパイラのメモリバリアを強制的に、不幸な副作用を持っているので、私はより多くの微何かを思い付くしようとしましたきめ

static inline uint64_t read_volatile_uint64(volatile uint64_t *x) { 
    uint64_t y; 
    asm ( "cpsid i\n" 
      "ldrd %[value], %[addr]\n" 
      "cpsie i\n" 
      : [value]"=r"(y) : [addr]"m"(*x)); 
    return y; 
} 

それはまだ望ましくないとする、割り込みを無効にし、そのcpsidに頼らずにそれをやって仕方があります場合、私は思ったんだけど。プロセッサは、整数除算として、 複数サイクル命令を実行しているときに割り込み要求が到着した場合ジョセフ耀輝によって決定的ガイド ARMへのCortex-M3およびCortex-M4プロセッサ、第3版は

言います割り込みハンドラ が完了した後で、命令 を破棄して再起動することができます。この現象は、ロードダブルワード(LDRD)と ストアダブルワード(STRD)命令にも適用されます。

これは単にこれを書いてうまくいくということですか?

(ARMエラッタ602117を回避するために"=&r"を使用した)
static inline uint64_t read_volatile_uint64(volatile uint64_t *x) { 
    uint64_t y; 
    asm ( "ldrd %[value], %[addr]\n" 
      : [value]"=&r"(y) : [addr]"m"(*x)); 
    return y; 
} 

同じ移植性を行い、いくつかのライブラリや組み込み関数はありますか?私はstdatomic.hatomic_load()を試しましたが、それはundefined reference to '__atomic_load_8'で失敗します。

+1

、そしてちょうどLDRDを使用すると、yesと動作するはずです(割り込みの有効/無効を混乱させることなく)?一方の側がもう一方の側を使用するようにしてください。または、strd/ldrdを使いたくない場合は、strex/ldrexを試すこともできます。 –

+0

'strd'を使うと' ldrd'を中断できないので、別のセマフォが必要なので 'strex'のチェックで遅延や複雑さが増えます。 – berendi

+1

よくあなたはあなたが最後に読んだものを指示し、割り込みが他のものを変更してからスワップすることを指定するping/pongメールボックス取引の何らかの仕掛けをすることができます... –

答えて

1

ARMv7mリファレンスマニュアルに従って、アトミティはLDRDで保証されません。 (A3.5.1)

The only ARMv7-M explicit accesses made by the ARM processor which exhibit single-copy atomicity are: 

• All byte transactions 

• All halfword transactions to 16-bit aligned locations 

• All word transactions to 32-bit aligned locations 

LDM, LDC, LDRD, STM, STC, STRD, PUSH and POP operations are seen to be a sequence of 32-bit 
transactions aligned to 32 bits. Each of these 32-bit transactions are guaranteed to exhibit single-copy 
atomicity. Sub-sequences of two or more 32-bit transactions from the sequence also do not exhibit 
single-copy atomicity 

ISRに読んでいることを示すためにバイトを使用することができます。

non_isr(){ 
    do{ 
     flag = 1 
     foo = doubleword 
    while(flag > 1) 
    flag = 0 
} 

isr(){ 
    if(flag == 1) 
     flag++; 
    doubleword = foo 
} 

ソース(ログインが必要): http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0403e.b/index.html

必要はありませんログイン:これの反対側は、一度に64ビットを更新アクセスされた場合 http://www.telecom.uff.br/~marcos/uP/ARMv7_Ref.pdf

関連する問題