2012-07-05 11 views
9

Tengo algunas macros C que desactivan y activan interrupciones para que pueda definir secciones críticas de código. Quiero asegurarme de que el optimizador cumpla con las operaciones y no las mueva ni las elimine.¿Cómo evito que un compilador de optimización interrumpa las secciones críticas sin interrupción?

#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_)) 

El uso es el siguiente: trabaja

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

El código como se esperaba con la optimización de apagado pero sospecho que puede haber problemas con la optimización activada.

¿Va a sumar el volátil a las declaraciones de asm el truco?

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

_suspect_ o _found_? :) – sarnold

+0

Solo sospeche hasta ahora. Me han picado los efectos secundarios de la optimización en el pasado, así que estoy siendo cuidadoso – CodePoet

+2

@sarnold Bueno, hay una diferencia entre "siempre funcionará" y "funcionará en este código específico con este compilador específico cada martes", por lo que piden algunos La documentación que garantiza el comportamiento es una buena idea para tales cosas. – Voo

Respuesta

7

Sí, asm volatile es la forma correcta de escribir esta macro. Puede verificar fácilmente el comportamiento al recorrer este código en el depurador y observar el orden de las operaciones en el nivel de ensamblaje. O bien, puede inspeccionar visualmente la salida de desensamblaje para su función.

Aquí hay alguna documentación útil sobre gcc asm en línea

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

0

sólo necesita atributo volátil en la variable clave.

Cuestiones relacionadas