Electronic – Global Array Size Affects Clock Frequency Only On Linux (avr-gcc)

avravr-gccavrdude

I am having the most peculiar problem. When the size of a global array changes, it alters the clock frequency of the ATmega164a. This is on Linux. When compiled on Windows, this problem doesn't occur (irrespective of whether the .hex file is actually programmed onto the ATmega164a in Windows or Linux aka I don't suspect avrdude is contributing to this problem). I even ran on Linux the exact commands run by AVR Studio to build the target, and still encountered this problem.

The CLKDIV8 fuse is not set, and the Internal RC fuse is set, so the ATmega164a should be running at 8MHz nominal.

This is the minimum working example of the code that runs correctly:

#include <avr/io.h> 
uint8_t bytes[6]; 
int main(void){ 
    DDRB = (1<<PB5); 

    while(1){ 
        PORTB |= (1<<PB5); 
        PORTB &= ~(1<<PB5); 
    } 
}

An oscilloscope shows the resulting pulse is 250ns wide (2 cycles).

However, increasing the global array size by one results in odd behavioral.

#include <avr/io.h> 
uint8_t bytes[7]; 
int main(void){ 
    DDRB = (1<<PB5); 

    while(1){ 
        PORTB |= (1<<PB5); 
        PORTB &= ~(1<<PB5); 
    } 
}

An oscilloscope shows this pulse width as 444ns, and the time between pulses increases in the same ratio which indicates the clock frequency has decreased.

I have no clue where to go from here. It took me a very long time just to narrow it down to this minimum working example. I have pasted my Makefile to pastebin.

EDIT

Here are the listing files for the two cases.
bytes[6]: pastebin
bytes[7]: pastebin

I have verified with a 16bit timer that the clock frequency is indeed decreasing by the factor previously quoted (250ns -> 444ns).

Best Answer

Turns out this is a known bug with avr-gcc (PR50652), and was fixed in version 4.6.2. Unfortunately, Ubuntu repositories (which I was using) utilize version 4.5.3.