This is the first of two posts about everything related to uploading, re-flashing, bootstraps, FTDI, and ISP.
First, our goal: what we want to do is get our software (“sketch”) from the PC/Mac into the AVR ATmega328 microcontroller on our Arduino or JeeNode. This is a fairly simple process once all the pieces are in place…
The effect is that the flash memory built into the ATmega is re-flashed. Being flash memory, your software will remain in the microcontroller even without power – ready to start again once power is applied.
There are two ways to get your software into the ATmega: In System Programming (ISP) and uploading. ISP will be described tomorrow, here we’re going to focus on uploading.
Uploading works with a “boot loader”. This is a small piece of software started after power-up (or a reset), which usually listens on the RX and TX pins of the serial interface for commands. These commands then tell it what data to store in which part of the flash memory:
The surprising thing is that the boot loader itself is also stored in flash memory. It’s stored in a small (1..4Kbyte) area in upper memory, and the data it writes always goes to the lower part of memory. That’s why it’s called a bootstrap or boot loader – imagine lifting yourself by pulling on the straps of your own boots. In this case the ATmega is lifting its own functionality up by reprogramming its flash memory via its own boot loader.
Once the boot loader finishes, but also if no commands come in, it jumps to lower memory and starts up whatever code happens to be stored there. The boot loader then stays inactive until the next power-up or reset. It never overwrites itself.
So what we need for this process is a properly installed bootstrap, and some “fuse” settings in the ATmega which tell it to always start up the bootstrap on power up or reset. How that is accomplished will be described in the next post. Arduinos and JeeNodes normally come with at ATmega microcontroller which has the boot loader pre-loaded and all the fuses properly configured.
It is not possible for code in lower memory to change fuses or any part of the flash memory. This is an important feature because it means that no matter what you upload to the ATmega, it won’t be able to mess up the bootstrap code. A pre-loaded bootstrap is essentially safe and permanent, no matter how bad or even malicious the code in lower memory is. If the sketch you uploaded doesn’t work and causes the ATmega chip to hang, you can simply reset the chip and reload an improved version via the boot loader, which will still work.
So how do we present our software / sketch to the boot loader?
The first part of the answer is software. On the PC/Mac, we usually do this with a program called “avrdude”. In the Arduino IDE, avrdude is launched when you press the “Upload” button.
Avrdude takes the code of a program as produced by the gcc compiler and linker, and tries to make contact with a boot loader via a serial or USB port. There are several types of connections, several different protocols, and several flavors of boot loaders, so avrdude also needs to be told which conventions and connection to use.
On the Arduino and the JeeNode USB, the connection takes place via USB:
USB is convenient because it can take care of three different things: powering the Arduino / JeeNode, resetting it to activate the boot loader, and sending commands to that same boot loader over a serial connection. In addition, once your code is running, the USB connection can be re-used as serial port to communicate whatever you like in either direction. That’s really a lot of functionality, just by hooking up a USB cable – and probably one of the major reasons why the Arduino has been so succesful.
The FTDI chip does the hard part of interfacing between a fairly complex USB system and the much simpler RX/TX serial communication pins. On an Arduino and a JeeNode USB, it’s all built onto the board itself.
On a standard JeeNode and on other similar boards such as the RBBB by Modern Device, the FTDI chip is assumed to be part of the USB cable hookup. This reduces cost when you have more than one board, because you can reuse the same FTDI hardware for different boards.
There are FTDI cables which have the FTDI chip built right into the USB connector plugged into the PC/Mac. But nowadays, it’s more common to use a small “FTDI adapter” board, such as these:
On the left is SparkFun’s FTDI Basic adapter, on the right Modern Device’s USB-BUB. Both take a regular USB cable with a mini-B connector (the same as used with most digital cameras, etc) and have a 6-pin FTDI header on the other end.
One detail remains, which makes the USB-BUB a slightly better choice for such an FTDI hookup: the interface needs to supply 5V to the attached JeeNode, but it also should use 3.3V logic levels for the RX/TX lines, because a JeeNode operates at 3.3V internally. If you look closely, you can see that the “Logic Lvl” on the BUB has been jumpered to 3.3V with a little wire.
The Sparkfun FTDI adaptor comes in two different versions for 3.3V and 5V, but they appear to use the same voltage for both power and logic levels. I’ve used the 3.3V version with a JeeNode with no ill effects so far, but it does mean the JeeNode is supplied with only 3.3V, i.e. less than the 3.4..3.5V it needs to make the on-board voltage regulator happy. It worked just fine for me, but it may not work for you, or not at all temperatures, or maybe not on days with full moon… “YMMV”, as they say.
There are many other similar adapters out there. As long as they use the same FTDI pinout on the header, and get the supply and logic voltage levels right, they should work fine.
But with the separate FTDI approach, you don’ have to use USB. This can also be used with an RS232 connection (i.e. a COM port on a PC) via a level converter to adjust between the different voltage levels:
Again, there are several adapters out there which can be used. I’ll not go into this – serial ports are becoming less common and you may need to fiddle around a bit more to get the auto-reset feature working.
One of the configuration settings to keep in mind with all this is tbe baud rate, since it’s all based on good ol’ asynchronous serial communication. With the standard Arduino/JeeNode boot loaders used on an ATmega328, the settings should be 57600N1.
Another gotcha is hardware handshaking. You may need to experiment a bit to make sure that hardware handshaking is turned off, and that the DTR/RTS lines are configured just right to cause a reset on connection open. If the bootstrap is not working, or if you can’t get serial communication to or from your sketch going reliably, then this would be the first thing to check.
At the end of the day, all this is about convenience. You can write a new sketch and then compile + store it in an Arduino or JeeNode with one simple upload action. If the code doesn’t work, or needs to be changed, just go back to the sketch, change it, and re-compile / upload again. Once everything is working, you can forget about all this, disconnect the board, hook it up to a battery or power supply instead, and it’ll continue doing whatever you told it to do.
That’s the world of embedded hardware. Exactly the same as in MP3 players, cell phones, microwave ovens, washing machines, and many other gadgets and appliances.
Tomorrow: Re-flashing and ISP.