PetitFatFs SD card bootloader for ATmega2560 / Arduino Mega 2560

ChaN’s PetitFatFs, is a pretty neat plain C library dealing with Fat file systems (like on SD cards) with as little code as possible. It even includes sample bootloader code for AVR, which tries to open a file on an SD card, and if it exists, write it to flash, before booting the user application.

It’s a pretty neat base, though you may/probably will want to add a little bit functionality. The directions that come with the code are pretty good for getting this working. [1] However, for boards based around the ATmega2560, or ATmega2561, which contain >128k program space, a couple of things just don’t work…

First, the code for jumping into the user code:

    ((void(*)(void))0)();

This is fairly commonly seen pattern, but least with GCC 4.3.3 (WinAVR 20100110) this generates incorrect code. It gets turned into an EICALL, but without setting EIND. This results in the bootloader continually resetting into itself. (And, if the file on the sd card exists, repeatedly overwriting flash as fast as possible, not really very good for your flash lifetime!)

The alternative, which correctly generates a jump to the real 0, (These big ATmega’s have a 22 bit Program Counter, not a 16 bit one) is simply:

    asm volatile("jmp 0000");

The other required piece of the puzzle, is actually an AVR-libc FAQ item. You need to add -mrelax to your linker options.

As best I can tell, both of these additions should actually “do no harm” for regular sized AVRs as well, but I don’t have any boards handy to try that out with.

By the way, if you’re using the SD card on an arduino ethernetshield, below is the the only change you need in asmfunc.S. Just to save you from working out what the real name for “digital pin 4” is C land.

#define	DDR_CS	_SFR_IO_ADDR(DDRG), 5	// MMC CS pin (DDR, PORT)
#define	PORT_CS	_SFR_IO_ADDR(PORTG), 5

Now, if only I could convince avrdude to erase all the flash, but only program the 4-8kb of bootloader, instead of insisting that it needs to program the entire 256k of flash each time I make a tweak to the bootloader. (139 seconds to program using a FabISP)

[1] The only thing I found unclear at first was setting up the “DI” and “DO” pins. Given that I was choosing pins that were on my mega2560, I assumed these were Data Out and Data In, when seen from the point of view of the mega2560. They are not, they are from the point of view of the SD card. (This is actually shown on the schematic image that comes with the PetitFatFs sample download)

  1. Just a note that AVRDUDE 5.11 (and I’m pretty sure a number of versions before that) do actually erase the entire chip and only write to the bootloader address range when using the AVR ISP mkII.

    However, AVRDUDE is also buggy with that programmer in a number of annoying ways (requiring at least one patch) that I won’t go into here.

    Also, after writing successfully to just the 4K boot loader block (very quickly I might add with -B0.25) it still insists on verifying against the entire Flash, which of course fails miserably.

    If I ignore the verify error though and then run again, specifying -D to write the application (my boot loader isn’t finished yet!) — then it all works just fine. I get the bootloader and the main application written, without having to combine them both into a single HEX file.

    Another bug with the AVR ISP mkII and possibly other stk500v2 USB based programmers is that, for some crazy reason, all kinds of things fail badly if you turn verify off with -V!! *shrug* Maybe it’s some crazy micro-second timing issue? Seems unlikely. I’ll get to the bottom of it one day.

    Oh and — thanks for the post above! Very useful.

  2. Would it be possible to get a working compiled version please? a Hex file maybe with the fuse settings you used please?
    I cannot get it to work :(

  3. Jonny, this was inside some private code. There’s plenty of working bootloaders out there now, this was a while ago.

  4. I am still yet to find anything I can get working unfortunately.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>