2012-07-05 7 views
9

Tôi có một số macro C tắt và bật ngắt để tôi có thể xác định các phần quan trọng của mã. Tôi muốn đảm bảo rằng trình tối ưu hóa tuân thủ các thao tác và không di chuyển chúng hoặc xóa chúng.Làm cách nào để ngăn trình biên dịch tối ưu hóa làm gián đoạn các phần quan trọng gián đoạn miễn phí?

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

Việc sử dụng như sau:

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

Mã này hoạt động như mong đợi với tối ưu hóa tắt nhưng tôi nghi ngờ rằng có thể có vấn đề với tối ưu hóa BẬT.

Sẽ thêm biến động vào câu lệnh asm làm thủ thuật?

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

_suspect_ hoặc _found_? :) – sarnold

+0

Chỉ nghi ngờ cho đến nay. Tôi đã bị cắn bởi tối ưu hóa tác dụng phụ trong quá khứ vì vậy tôi đang cẩn thận – CodePoet

+2

@ sarnold Vâng có một sự khác biệt giữa "sẽ luôn luôn làm việc" và "sẽ làm việc trên mã cụ thể này với trình biên dịch cụ thể mỗi thứ ba", vì vậy yêu cầu một số tài liệu đảm bảo hành vi là một ý tưởng tốt cho những thứ như vậy. – Voo

Trả lời

7

Có đúng, asm volatile là cách chính xác để viết macro này. Bạn có thể dễ dàng kiểm tra hành vi bằng cách bước qua mã này trên trình gỡ rối và xem thứ tự các phép toán ở cấp độ lắp ráp. Hoặc, bạn chỉ có thể kiểm tra trực quan đầu ra tháo gỡ cho chức năng của bạn.

Dưới đây là một số tài liệu hữu ích về gcc asm inline

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

0

bạn chỉ cần thuộc tính không ổn định về biến quan trọng.