2012-07-05 8 views
9

私は、コードのクリティカルセクションを定義できるように、割り込みを無効にして有効にするCマクロをいくつか持っています。オプティマイザが操作に準拠していることを確認し、そのオプティマイザを移動または削除しないようにします。次のように最適化コンパイラが割り込みのないクリティカルセクションを中断させないようにするにはどうすればよいですか?

#define ARM_INT_KEY_TYPE   unsigned int 
#define ARM_INT_LOCK(key_) ({ \ 
    asm("MRS %0,cpsr" : "=r" (key_)); \ 
    asm("MSR cpsr_c,#(0x1F | 0x80 | 0x40)"); \ 
}) 
#define ARM_INT_UNLOCK(key_) asm("MSR cpsr_c,%0" : : "r" (key_)) 

使用方法は次のとおりです。

int init_i2c(p_device_i2c dev){ 

// Interrupts are enabled 
doSomething(); 

ARM_INT_KEY_TYPE key; 
ARM_INT_LOCK(key); 

// Interrupts are disabled 
pMX27_GPIO i2c_clk = (pMX27_GPIO)(GPIO_BASE_ADDR | I2C_CLK_PORT); 
pMX27_GPIO i2c_sda = (pMX27_GPIO)(GPIO_BASE_ADDR | I2C_DATA_PORT); 

i2c_clk->GIUS &= ~(1 << I2C_CLK_PIN);   // I2C Signals 
i2c_sda->GIUS &= ~(1 << I2C_DATA_PIN);  // I2C Signals 

ARM_INT_UNLOCK(key); 
// Interrupts ON again 

// Wait for stable 
ARM_delay_clocks(5000); 

i2c_stop(dev); 

コードは、最適化をオフにして期待通りに動作しますが、私は最適化問題をONがあるかもしれないことを疑います。

asmステートメントにvolatileを追加すると、そのトリックは起こりますか?

#define ARM_INT_UNLOCK(key_) asm volatile ("MSR cpsr_c,%0" : : "r" (key_)) 
+0

_suspect_または_found_? :) – sarnold

+0

これまでのところ疑わしい。私は過去の最適化の副作用に噛まれてしまったので、慎重になっています。 – CodePoet

+2

@sarnold「常に動作します」と「毎回この特定のコンパイラでこの特定のコードで動作します」という違いがあります動作を保証するドキュメントは、そのようなもののための良いアイデアです。 – Voo

答えて

7

はい、asm volatileは、このマクロを書き込む正しい方法です。デバッガでこのコードを実行し、アセンブリレベルでの操作の順序を見ることで、動作を簡単に確認できます。または、関数の逆アセンブリ出力を視覚的に検査することもできます。

は、ここであなただけのキー変数にvolatile属性を必要とするインラインアセンブラ

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html#ss5.4

0

上のいくつかの有用なgccのドキュメントです。

関連する問題