2015-09-29 93 views
1

當我爲我的STM32F429 CPU編譯我的代碼時,一切正常,當我使用-O0標誌時,但只要我使用更高優化(-O1, -O2, and -O3)代碼就會中斷。
我使用ST和一些基本代碼的CMSIS + HAL庫。編譯器arm-none-eabi-gcc v4.9.3優化對指針的操作

的問題是,即使*uart_irq被定義爲volatile在主迴路的if (uart_irq && uart_irq->SOURCE == IRQ_SOURCE_UART)不會求
我試圖將uart_irq定義爲volatile void *而沒有成功。
唯一的工作是如果uart_irq被定義爲volatile uint32_t並且整型被轉換爲irq_instance當用作編譯器將不會在優化期間刪除。

如果有人能解決這個問題,我會很高興。

  • 這應該是標準的行爲?
  • 這是編譯器中的一個已知錯誤嗎?

main.h

#define API_COMMAND_SIZE 6 
typedef struct irq_instance_s 
{ 
    uint8_t SOURCE; 
    uint8_t TYPE; 
    uint8_t *CONTEXT; 
    uint8_t SIZE; 
} irq_instance; 
extern volatile irq_instance *uart_irq; 

main.c中
receive指針被釋放內部hande_command

#include "main.h 
volatile irq_instance *uart_irq = 0; 

int main(void) 
{ 
    uint8_t *receive = 0; 
    <Initialize stuff> 

    /* Initialize first UART recieve */ 
    receive = malloc(API_COMMAND_SIZE); 
    while (HAL_UART_Receive_IT(&huart1, receive, API_COMMAND_SIZE) == HAL_BUSY); 
    /* Program Main loop */ 
    while(1) { 
     if (uart_irq && uart_irq->SOURCE == IRQ_SOURCE_UART) { /* <---- Problem is here */ 
      handle_interrupt(uart_irq); 
      free((void *)uart_irq); 
      uart_irq = 0; 
     } 
    } 
} 

stm32f4xx_it.c
HAL_UART_RxCpltCallback每次成功UART接收之後被調用。

#include "main.h" 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) 
{ 
    uint8_t *receive = 0; 
    uart_irq   = calloc(1, sizeof(irq_instance)); 
    uart_irq->SOURCE = IRQ_SOURCE_UART; 
    uart_irq->CONTEXT = huart->pRxBuffPtr - huart->RxXferSize; 
    uart_irq->SIZE = huart->RxXferSize; 
    uart_irq->TYPE = IRQ_TYPE_COMMAND; 

    receive = malloc(API_COMMAND_SIZE); 
    while (HAL_UART_Receive_IT(&huart1, receive, API_COMMAND_SIZE) == HAL_BUSY); 
} 
+0

我不知道我完全理解爲什麼你希望它是揮發性的。你想讓指針或指針變得易變嗎? – Aif

+0

'uart_irq'沒有被聲明爲'volatile',但它指向的對象! – Olaf

回答

1
volatile irq_instance *uart_irq 

說,事指向uart_irq是揮發性的。但是

if (uart_irq && uart_irq->SOURCE == IRQ_SOURCE_UART) 

正在看指針本身,而不是指向的東西。如果指針本身也是揮發性的,這看你的代碼是的話,聲明這樣說:

volatile irq_instance * volatile uart_irq 
+0

所以第一個volatile表示結構是易失性的,第二個表示指針本身是不穩定的。 如果你寫'volatile irq_instance volatile * uart_irq',會發生什麼? –

1

如果我讀這正確的,那麼你正在改變uart_irq的IRQ處理程序中,它的指針的這種變化優化器在常規程序流中看不到的值,因此正在優化。

易失性指針的正確聲明是irq_instance * volatile uart_irq。你聲明的方式告訴gcc指針指向的值是不穩定的。如果這也是這種情況,那麼你可以將它們與volatile irq_instance * volatile uart_irq結合起來。

0

變量uart_irqvolatile,而不僅是它指向...定義是這樣:

extern irq_instance * volatile uart_irq;