程序在不同的优化级别上表现不同

问题描述 投票:0回答:1

我有一个简单的 C 程序,用于熟悉我将使用的新(对我而言)MCU (ATmega32M1)。但是,我的程序在 -O3 优化级别无法正确运行。

我正在使用 Microchip Studio(版本 7.0.2594)(以前称为 Atmel Studio)。我正在使用 avr-gcc 5.4.0

在除 -O3 之外的所有编译级别,连接到输出 PB5 和 PD6 的 LED 均以 8 秒的周期闪烁。这是正确的行为。然而,在优化级别 -O3 下,只有连接到输出 PB5 的 LED 闪烁,而输出 PD6 保持低电平。

这对我来说是一个明显的错误,还是某种编译器错误(喘气!)?

如果它编译器错误,如果您能给我指出一些有关如何更新 Microchip (née Atmel) Studio 7 使用的编译器的说明,我将非常感激 - 我对此真的很陌生,但我强烈怀疑v5.4.0不是avr-gcc的最新版本。

我的代码转载如下:

#include <avr/io.h>
#include <avr/interrupt.h>

static uint64_t execution_time;

////////////////////////////////////////////////////////////////////////////////
// Setup functions

static inline void SetClock(void) {
    //Set clock to external crystal highest speed (8MHz):  
    //(These instructions must be completed in 4 clock cycles or less)
    CLKPR = 0x80;   //set CLKPCE, clear all else.
    CLKPR = 0x00;   //Clear CLKPCE, set CLKPS[3:0] to 0. (Smallest prescale - fastest speed.)
}

static inline void SetTimer1(void) {
    //set up timer/counter 1 (CTC mode, TOP = OCR1A)
    TCCR1A = 0;             //WGM0 & WGM1 = 0
    TCCR1B = 0x0D;          //set WGM[3:0] = 0,1,0,0 (CTC with OCR1A as TOP); CS1[2:0] = 1,0,1 (internal timer, prescale 1024)
    OCR1A = 0x7A12;         //TOP = 31250; 4000.0 ms - This means an accurate count can be kept as well as the faster count.
    TIMSK1 = 1<<OCIE1A;     //Interrupt on Timer 1 reaching OCR1A.
    //The Timer will run at 7.8125 ticks per ms.
}

void InitOutputs(void) {
    DDRB |= 0x7 << DDB5;    //SPARE6, 7, 10
    DDRC |= 0x3 << DDC6;    //SPARE8, 9
    DDRD |= 0x7 << DDD5 | 0x3 << DDD0;  //SPARE11, 12, 13 && RELAY H & L
}

void Setup(void) {
    //Set up the various parts of the hardware.
    SetClock();
    
    SetTimer1();
    
    InitOutputs();

    sei();
}

////////////////////////////////////////////////////////////////////////////////
// Functional... functions

void TestISR(void) {
    static uint64_t last_time;
    if (execution_time > last_time) {
        PIND = 1 << PORTD6;
        last_time = execution_time;
    }
}

int main(void) {
    Setup();
    
    while (1) {
        TestISR();
    }
}

ISR(TIMER1_COMPA_vect) {
    execution_time += 4000;
    PINB = 1 << PORTB5;
}

c embedded avr avr-gcc
1个回答
1
投票

你的变量需要是

volatile

static volatile uint64_t execution_time;

否则,当您启用优化时,从中读取的内容将被优化,因为编译器看不到任何可能修改此变量的程序路径(ISR 不会从您的代码中调用)

© www.soinside.com 2019 - 2024. All rights reserved.