编译器arm-none-eabi-gcc v4.9.3优化了对指针的操作

时间:2015-09-29 14:40:49

标签: c gcc optimization volatile

当我为STM32F429 CPU编译代码时,当我使用-O0标志时,一切正常,但只要我使用更高优化(-O1, -O2, and -O3),代码就会中断。
我使用ST的CMSIS + HAL库和一些基本代码。

问题是即使*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
每次成功接收UART后都会调用HAL_UART_RxCpltCallback

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

3 个答案:

答案 0 :(得分:1)

volatile irq_instance *uart_irq

说uart_irq指向的东西是不稳定的。但是

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

正在查看指针本身,而不是指向的东西。如果指针本身也是volatile,它看着你的代码,那么就像这样声明:

volatile irq_instance * volatile uart_irq

答案 1 :(得分:1)

如果我正确读取了这个,那么你正在改变IRQ处理程序中的uart_irq,这是优化器在常规程序流中看不到的指针值的这种变化,因此正在优化。

易失性指针的正确声明是irq_instance * volatile uart_irq。你声明它的方式告诉gcc指针指向的值是volatile。如果情况也是如此,那么您可以将两者合并为volatile irq_instance * volatile uart_irq

答案 2 :(得分:0)

变量uart_irqvolatile,而不仅仅是它所指向的......以这种方式定义:

extern irq_instance * volatile uart_irq;