Note: This article is the 4th in a series of posts about electronics.
Once you have acquired the hardware: a breadboard, a programmer, a serial adapter, some wires, and a microcontroller, you’re ready to make it tick. For most future entries, if you’re following along, I will assume that you’re using an AVR Dragon, a Sparkfun FT232RL breakout, and an Atmel ATmega644PA in PDIP package.
Eclipse as an IDE for AVR programming
I personally have been using the Eclipse IDE for most of my AVR work. Eclipse has excellent C language support, and a pretty logical workflow. Its configuration can be a bit painful sometimes, but overall it works very well for AVR development. You’ll want to install at least the AVR Eclipse Plugin and support for your favorite source control (I use the SVN support).
GCC cross-compiler and avr-libc C library
Developing for a microcontroller is a bit different than developing for a PC, because the microcontroller and the PC can’t run each others’ code. Since you can’t exactly hook up a monitor, keyboard, and mouse to the microcontroller and write your code there, you must cross-compile it. Cross-compiling is really the only option you have when developing code for microcontrollers but it’s not an altogether uncommon technique to run into outside of microcontrollers, either. There are two very important terms when dealing with a cross-compiler:
- Build — The build system runs the compiler and usually the rest of the development suite, such as IDEs
- Target — The target system is the one the code is being written for. It’s usually not capable of doing the compiling itself because it’s either too new (the tools haven’t been ported), unsupported directly by the tools for one reason or another (a common reason is that it doesn’t have enough RAM), or is primitive enough that it could never actually run the compiler itself in the first place (microcontrollers especially).
Support for cross-compiling for AVR has been in main-line GCC for quite some time now, so it is available in a lot of different places. When GCC is built to cross-compile for AVR it is usually (but not always) named avr-gcc, and many Linux distributions—such as Fedora 12—have packages pre-built for it.
In addition to a C compiler, you will need a C library. The avr-libc project provides a version of libc suitable for the AVR, with much of the libc stuff you’re used to (a type library, malloc, strcpy, etc.), and a bunch of AVR-specific things (delay subroutines, defines for all kinds of microcontrollers, etc.). Again, on many Linux libc is quite easily provided by by the pre-built packages.
Compiling code for the AVR is much the same as you might be used to for the PC, with a few exceptions:
- You must always define which exact model of microcontroller your code is “targeted” at using -mmcu=atmega644pa for instance, for the ATmega644PA.
- It’s not strictly required, but is generally a good idea to tell the compiler (and thus your code) what frequency you expect the microcontroller to be running at using the F_CPU define; generally it’s best to define this on the gcc command line (rather than using #define) with -DF_CPU=8000000L for 8 MHz, as an example. If you don’t define F_CPU, you can’t use the delay functions (_delay_ms and _delay_us) and some others.
- There are substantive differences besides mere performance when running with optimizations off and on. For instance, the delay functions mentioned above require optimization to be enabled to work properly. Generally you should compile with -Os for optimization based on code size.
- You need to carefully watch the resultant code size with each compile. The AVR Eclipse plugin automatically runs avr-size with each compile to keep you apprised of the current code size, but if you’re writing your own makefiles you will want to do something like avr-size --format=avr --mcu=atmega644 foo.elf.
Getting the code onto the microcontroller
Once you have a working development environment and you’re able to compile code, you will need a program to transfer that compiled code to the microcontroller. The avrdude program does just that. There is built-in support for it from the AVR Eclipse plugin, which simplifies things a lot, but you can also use it from the command-line.
Communicating with the microcontroller
You will almost certainly want minicom, a serial terminal emulator, to communicate with the microcontroller over the serial port.
What if I use a Mac?
On Mac OS X, of course Apple doesn’t provide any pre-built packages for all of this, but Eclipse is readily available for Mac OS X, and the rest can be provided simply by CrossPack for AVR Development, which bundles avr-gcc, avr-libc, and avrdude into a nice pkg installer. You can get minicom through either Fink or MacPorts.