2012-07-05 84 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); 

的代碼按預期工作與優化關閉的,但我懷疑有可能是優化問題接通。

將添加揮發性的彙編語句做的伎倆?

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

_suspect_或_found_? :) – sarnold 2012-07-05 23:22:28

+0

到目前爲止只是嫌疑犯。過去我被優化的副作用咬了一口,所以我很小心 – CodePoet 2012-07-05 23:28:38

+2

@sarnold那麼「永遠工作」和「每個星期二都會使用這個特定的編譯器工作在這個特定的代碼上」是有區別的,所以需要一些保證行爲的文檔對於這些事情來說是個好主意。 – Voo 2012-07-06 11:50:28

回答

7

是的,asm volatile是寫這個宏的正確方法。您可以通過在調試器上逐步執行此代碼並查看組件級別的操作順序來輕鬆檢查行爲。或者,您可以直觀地檢查功能的反彙編輸出。

這裏有一個關於內聯彙編了一些有用的GCC文檔

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

0

你只需要在關鍵變量波動屬性。