On avr-gcc and compiling USBtinyISP with Ubuntu Linux

USB AVR Programmer and SPI interface. Adafruit's USBtinyISP.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
timv
 
Posts: 82
Joined: Thu Nov 01, 2007 4:13 pm

On avr-gcc and compiling USBtinyISP with Ubuntu Linux

Post by timv »

I've been curious about USBtinyISP and usb hacking generally and this afternoon I thought I'd poke around in the code some, then maybe proto up a circuit and see if my computer would actually recognize it as a valid device.

I'm currently running Ubuntu 6.10, named (unfortunately) "Edgy Eft," and I had installed the Ubuntu package "avr-gcc" which is version 4.1.0 of the compiler. Attempting to compile usbtinyisp gave the error message:

"ERROR: Flash size limit exceeded by 50 bytes."

That's been mentioned several places on the site. In fact, it's a documented bug in gcc:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30908

According to the developers, it isn't just a matter of size optimization "not working as well" in newer versions. It's actually known to be making wrong decisions about when to inline functions versus calling them in place. It is still an open bug as of writing and it looks like it's been observed in all 4.x.x versions.

So I de-install my avr-gcc package and download the gcc-3.4.6, gcc-core-3.4.6, and gcc-g++-3.4.6 source packages from http://gcc.gnu.org/mirrors.html. I un-tar them into a single directory, create another directory called "build-gcc" and cd into it (per the instructions in the INSTALL file) and execute:

Code: Select all

../gcc-3.4.6/configure --target=avr --program-prefix="avr-" --enable-languages=c,c++
(Note that last "--enable-languages=c,c++" flag. Without this flag, the build will fail when it gets to parts having to do with Fortran, ADA, Java, etc., if you haven't downloaded the gcc source packages for those languages. Some sets of instructions leave this out.)

One other Ubuntu hitch: The build failed with an error that it couldn't find the header file "sys/types.h". This seems to result from Ubuntu putting AVR-related files in /usr/avr, while I wanted to use the more common location /usr/local/avr. The solution was to add (as superuser) a symbolic link to make everyone happy:

Code: Select all

ln -s /usr/avr /usr/local/avr
After the usual amount of fuss, it compiles successfully and I run "make install" as superuser, then try it out. It tells me:

"unknown MCU `attiny2313' specified"

It's not a case of my gcc version being so incredibly old that ATTiny2313 chips didn't even exist yet, because version 3.4.6 wasn't released all that long ago.

A long and involved thrash follows. If no 3.x.x version supports ATTiny2313 then I thought that maybe the bug report was wrong and a newer version had fixed it. So I downloaded and built the most recent posted version, which is gcc-4.2.2. (Gotta add "--disable-libssp" to the configure command line now. Another 15 or 20 minutes gone finding that one.)

I build, install, and test, and the size margin was a few bytes different, but the code is still too big for the chip.

I figure that Ladyada must have used some release of WinAVR, so perhaps some of their 3.x.x releases had patches applied to add ATTiny2313 support. (Getting warmer here!) I made several attempts at trying to run WinAVR using the Wine MSWindows emulator, but I could never convince avr-gcc to run on top of Wine.

But I found some patch files in the CVS archive on the WinAVR SourceForge site. Only the most recent ones were available there, none applying to pre-4 gcc versions, but they put me on the right track. Via exhaustive googling, I eventually found a FreeBSD site with all of their avr-gcc patches, including one that adds support for more recent devices to version 3.4.6 by changing the files "avr.c", "avr.h", and "t-avr" in the directory "gcc/config/avr". Bingo.

That patch is described here:
http://www.freebsd.org/cgi/cvsweb.cgi/p ... es#rev1.10
and I got the actual file from here:
http://www.freebsd.org/cgi/cvsweb.cgi/~ ... xt%2Fplain

I emptied out my "build-gcc" directory, re-ran the "configure", "make", and "make install" commands, and voila all was right in the world again. Usbtinyisp v.2 built successfully:

Code: Select all

timv@zabel:~/ladyada/usbtinyisp/spi$ make
avr-gcc -Os -g -Wall -I. -I../usbtiny  -mmcu=attiny2313 -c ../usbtiny/crc.S
avr-gcc -Os -g -Wall -I. -I../usbtiny  -mmcu=attiny2313 -c ../usbtiny/int.S
avr-gcc -Os -g -Wall -I. -I../usbtiny  -mmcu=attiny2313 -c ../usbtiny/usb.c
avr-gcc -Os -g -Wall -I. -I../usbtiny  -mmcu=attiny2313 -c -o main.o main.c
avr-gcc -g -mmcu=attiny2313 -o main.elf crc.o int.o usb.o main.o
text: 2044, data: 2, bss: 60
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
Only burned six hours or so figuring this one out. I'd rather have been hacking away trying to come up with more nifty usb tricks. But someone really needed to document this situation and I guess it fell to me.

I hope this helps someone else avoid having to go through all of this again.

User avatar
rglenn
 
Posts: 20
Joined: Thu Oct 04, 2007 10:36 pm

Post by rglenn »

I'd read something about that over at Objective Development's site (GCC 3 being currently far more code space efficient than GCC 4)

From the look of the install on my hard drive, the latest WinAVR doesn't include AVR-GCC 3 at all. Perhaps there's a way to copy over parts of an older version to get code efficiency along with the newer features (like AVRDude 5.5)

I know that Objective Development's AVR MacPack includes both versions of AVR-GCC along with a script to switch between them, and the new device support compiled in:
http://www.obdev.at/products/avrmacpack/index.html

I'll give both routes a shot within the next few days to make sure that they work.

-Randy

rickyrockrat
 
Posts: 11
Joined: Sun Jan 06, 2008 8:43 am

Post by rickyrockrat »

TimV,
I am surprised you did not have to patch binutils as well. I added support for these to 4.1.0 a long time ago, but I had to patch binutils(2.16.1) - the /gas/config/tc-avr.c file to add the machine types.

I'll have to build using the gcc you have. I've got the whole cross-compile in a script so it's easy to rebuild/patch for me.

Also, all I needed to download was gcc-core, not the other two. Are you actually using C++ on the AVRs???

timv
 
Posts: 82
Joined: Thu Nov 01, 2007 4:13 pm

Post by timv »

I kept the standard Ubuntu avr-binutils package that I'd already installed. I haven't checked the version (and I'm at work now) but it probably matched the compiler, so I think I had 4.1.0 with the patches applied already.
Are you actually using C++ on the AVRs???
I don't expect to have big class hierarchies going, but I like some of the things C++ lets me do--such as declaring variables anyplace in the program I care to. I wanted to give myself the option of using the "c++" suffix, if only to loosen up the syntax.

I haven't gotten as far as trying to do much with it, so maybe there's no point or some good reason not to. But I'm certainly not cramped for space w/ regard to the cross-compiler executable and I like options.

Looking forward to hearing how your build goes if you get around to it.

timv
 
Posts: 82
Joined: Thu Nov 01, 2007 4:13 pm

Post by timv »

rickyrockrat: I was looking at the files generated when the Arduino app complies a sketch and your post came back to me. I see that my .pde file is converted to a .cpp file when it's compiled. It also links in HardwareSerial.cpp for comm operations, and the header for this includes some definitely non-C stuff like:

Code: Select all

class HardwareSerial
{
  private:
    //uint8_t _uart;
    void printNumber(unsigned long, uint8_t);
  public:
    HardwareSerial(uint8_t);
Are you sure that the compiler will handle this without including C++ support when building it?

rickyrockrat
 
Posts: 11
Joined: Sun Jan 06, 2008 8:43 am

Post by rickyrockrat »

timv: The C compiler should choke on the C++ stuff. I was just surpised in a small embedded device like this anyone would attempt C++, since it adds a bit of overhead, but what would be especially disturbing would be the behind-the-scenes garbage collection.

But hey, I'm just an old embedded hardware guy that is now an embedded Linux consultant. At least I never bought into the whole "use assembly - C's too bloated" idea.

I have the patches for most the the new devices using BANNED 1.6.1, gcc-4.1.0, and binutils 2.16.1, with patches and build script that auto magically downloads, patches, and installs these cross compilers. It also does gcc3.4.6+libc1.6.1+binutils2.16.1.

I've tried gcc4.2.2+binutils2.18+libc1.6.1, but It doesn't work too well. The patches (easily removed) also remove the bss copy (so vars are not automatically initialized) and stack setup to save a few bytes on these tiny avrs. You're welcome to the build stuff

Locked
Please be positive and constructive with your questions and comments.

Return to “USBtinyISP”