This week I surveyed the various ways you can program an embedded device housing an AVR microcontroller. The AVR architecture
has programs written in a different address space than the execution memory, in our case the flash memory. In order to program
the microcontroller you need to download the program to the flash memory, using a programmer i.e. a chip designed to put a
microcontroller into programming mode and run the commands needed to write the program. We actually built such a chip in the first electronic's
week : the FabISP. My aim this week was to establish a smooth programming workflow, so that
I minimize the time between writing and testing a program.
Step 1: Exploring Tool Options
The language that the microcontroller understands is called the machine code, i.e. blocks of 0's and 1's corresponding to
different states of its internal ASM or memory addresses. To be able to write programs in more human-friendly languages
you have to use a compiler, which will translate it to machine code.
The choice of the language usually depends on the level of abstraction you want to work. If you are farther away from the
machine code (i.e. the more work your compiler does) you can have complex data types and commands but you sacrifice speed, as
if you use a languege that speaks directly to the microcontroller you can optimize the way a command is executed.
In the case of AVR's there a exists a very interesting and well documented C library,
avr-libc and given my expertise in C language, I decided to follow this path instead of using assembly language. If I ever need
more control, I can write assembly code snippets to execute them inbetween C code. As far as a workspace is concerned, I was using so far Eclipse Luna
which was happy with projects including big libraries like SDL, so I will give it a try with avr-libc. There exists also
an Eclipse AVR plugin to facilitate the generation of device specific makefiles, setting up the toolchain etc.
Step 2: Setting up a workflow
After installing the plugin, it was time to create my first project, with an aim to program the LED+button
board to blink the Morse code for "SOS". Creating an AVR project inside eclipse is quite straightforward. The plugin
has imported the options "Avr Cross target application" and "Avr Cross target static library" of which I choose the first
as I want to run the code in the device. There is a default toolchain included and I was prompted to select the type
of microcontroller I was using and the frequency I am running it. In my case it's an ATTiny44 with an external 20MHz
crystal. Eclipse will generate the correct make command to burn the fuses (switches inside the microcontroller used for core
settings such as the clock) for the indicated clock frequency.
Step 3: Programming LED_Morse
Once the project is created, the resulting workspace looks like the image on the right (without the Debug/Release folders, created
only after building it). Eclipse with the AVR plugin placed all the necessary libraries in the current workspace, so I can include
them directly in my code.
The window is split in 3 parts: a. the flat files of in the workspace in the left, the code in the middle and the elements section in the
right. In the element section, Eclipse parses the code and presents the different variables/classes/functions that were declared in the
current scope.
The LED blinking code is very simple. In the beginning I define names for the ports and pins that I have connected the LED
and the Button for easier reference. Then I set the state of the pins to input or output altering the content of the DDR (data direction
register) of the corresponding port.
The main program is a loop where I alternate the value of the output pin from 0 to 1 (0V -> 5V) with the correct
timing to produce the Morse code for "SOS", i.e. three long, followed by three short, in turn followed by three long blinks.
In each iteration I check the state of the button, and if it's pushed I generate a break to stop the loop.
The interface that downloads the program to the microcontroller is avrdude
a command-line in-system programmer. The Eclipse plugin has integrated an interface for the various parameters of the downloading
commands. At first you select the programmer you want to use, which in my case is the FabISP. The profile for FabISP is "tinyusb", a generic
default for custom made usb programmers.
**UPDATE: In the pictures below you can see that for the LED_Morse program I used a different programmer, the AVRispMK2, as my FabISP was accidentally destroyed. Later created a new
FabISP with LED indicators (see week 10).
Step 4: Downloading the program
To generate the machine code from the C code, I had to "build" the program. To say to the compiler specifications about the building
procedure, like optimizations for speed or memory, you use a "makefile", i.e. a batch of commands and directives for the compiler.
In my makefile, (which you can see on the right) I included not only the commands for the compiler, but also for avrdude in order to
download the program. I found a nice overview of the avrdude commands
here.
Below you can see the LED blinking as well as my programmer setup.
UPDATE: Do I really need an IDE ?
Towards the end of the week, I realized that the IDE was more confusing, than actually writing your make and avrdude
commands in the commad line. Thus, I made a notepad archive with the different commands I used for reference, and since then started
to write my programs in Sublime text editor and then compile/download them using the commmand line. It certainly feels more
"hacker-ish" !