2015-09-29 58 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;