2012-07-05 7 views
9

Mam niektóre makra C, które wyłączają i włączają przerwań, dzięki czemu mogę zdefiniować krytyczne sekcje kodu. Chcę się upewnić, że optymalizator jest zgodny z operacjami i nie przenosi ich ani nie usuwa.Jak uniemożliwić kompilatorowi optymalizującemu przerwanie sekcji krytycznych bez przerw?

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

Użycie jest w następujący sposób:

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

Kod działa zgodnie z oczekiwaniami optymalizacji wyłączony, ale podejrzewam, że mogą być problemy z optymalizacją włączony.

Dodanie zmienności do instrukcji asm załatwi sprawę?

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

_suspect_ or _ found_? :) – sarnold

+0

Podejrzewam, że tak daleko. Zostałem ugryziony przez efekty uboczne optymalizacji w przeszłości, więc jestem ostrożny – CodePoet

+2

@sarnold Cóż, jest różnica między "zawsze działa" i "będzie pracować nad tym specyficznym kodem z tym konkretnym kompilatorem każdego wtorku", więc prosi o trochę Dokumentacja, która gwarantuje zachowanie, jest dobrym pomysłem na takie rzeczy. – Voo

Odpowiedz

7

Tak, asm volatile to poprawny sposób zapisu tego makra. Możesz łatwo sprawdzić zachowanie, przechodząc przez ten kod w debugerze i obserwując kolejność operacji na poziomie zespołu. Lub możesz po prostu wizualnie sprawdzić wyjście demontażu dla twojej funkcji.

Oto kilka przydatnych dokumentację gcc na inline asm

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

0

trzeba tylko ulotną atrybut zmiennej klucza.