Summary: When building on linux contents of initialized variables are mangled, same code works perfect with avrstudio on windows.
Having a natural distrust to everything windows, i thought i'd set up a build environment on linux for my first endeavours in coding for MCU's.
It works pretty well, except when i use an initialized variable like
uint8_t = 2;
or
char *s = "string";
then i'll either get garbage or my atmega328p will keep resetting.
Here's the kicker: When i compile the same code with avrstudio/winavr everything works great. Naturally this really bugs me.
Example:
#include#include "pins.h" #include "hd44780.h" static void setup_pins() { DDRD = 0xFF; } // Not interesting static void setup_display() { hd44780_init(); hd44780_cmd( HD44780_SETUP | HD44780_4BIT | HD44780_2LINES | HD44780_5X8DOTS ); hd44780_cmd( HD44780_DISPLAY | HD44780_POWER_ON | HD44780_CURSOR_ON | HD44780_BLINK_ON ); hd44780_clear(); hd44780_home(); } int main() { setup_pins(); setup_display(); // This works every time hd44780_putc('c'); // This only seems to work with avrstudio char *s = "abc"; while(*s != '\0'){ hd44780_putc(*s); s++; } while(1); }
I don't think the hd44780.* files will be interesting.
Compiled with any of the 4 recent toolchains for linux i've tried, this will output something like
c@
Compiled with avrstudio, it produces the expected
cabc
In either case i compile it with:
avr-gcc -pipe -mmcu=atmega328p -Wall -Os -I/usr/avr/include -DF_CPU=20000000UL -MM testcase.c > testcase.dep avr-gcc -pipe -mmcu=atmega328p -Wall -Os -I/usr/avr/include -DF_CPU=20000000UL -o testcase.o -c testcase.c avr-gcc -pipe -mmcu=atmega328p -Wall -Os -I/usr/avr/include -DF_CPU=20000000UL -MM hd44780.c > hd44780.dep avr-gcc -pipe -mmcu=atmega328p -Wall -Os -I/usr/avr/include -DF_CPU=20000000UL -o hd44780.o -c hd44780.c avr-gcc -o testcase.elf testcase.o hd44780.o avr-objcopy -j .text -j .data -O ihex testcase.elf testcase.hex
No errors or warnings are produced.