4
\$\begingroup\$

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).

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Post the assembly listing for both cases. \$\endgroup\$ Feb 23, 2013 at 11:19
  • \$\begingroup\$ This isn't a particularly reliable way of measuring clock frequency. Maybe use a timer with Max. Prescaler and set it to toggle at top or what have you and measure that. You're then not affected by compiler quirks. \$\endgroup\$ Feb 23, 2013 at 13:15
  • \$\begingroup\$ @ThePhoton points out the Assembler listing only substantively has 1 line difference. 0x66 -> 0x67 @ adress 0x92. That means that the output (i.e. the hex code) that goes to the programmer should be compared. THe object/assembly code shows no evidence of difference. \$\endgroup\$ Feb 23, 2013 at 20:50

2 Answers 2

4
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

The clock frequency very likely has not changed (unless you've wacked your set up registers). The loop time is what is changing for you, for some reason the one tool is inserting more instructions or longer executing instructions in that loop in the binary.

Since you have two versions you should be able to open them in the proper editor and do a A/B comparison and see where the two op-code sets are different.

It could be as simple as a compiler setting, a compiler version or any of a number of things.

And if you've wacked you setup registers that ALSO is probably a compiler setting which will manifest itself in the output binary.

\$\endgroup\$
1
  • \$\begingroup\$ He posted the assembly, and I don't see any change in the loop code. I was thinking something like the code ended up differently page-aligned in memory, but that's kind of a long shot... \$\endgroup\$
    – The Photon
    Feb 23, 2013 at 20:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.