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);

コードは最適化をオフにすると期待どおりに動作しますが、最適化をオンにすると問題が発生する可能性があると思われます。

asm ステートメントに volatile を追加するとうまくいきますか?

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

2 に答える 2

7

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

インライン asm に関する便利な gcc ドキュメントを次に示します。

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

于 2012-07-05T23:23:53.233 に答える
0

キー変数の揮発性属性のみが必要です。

于 2012-07-06T05:39:08.663 に答える