LUFA and the Arduino Leonardo

Just a quick update, because I know I’m going to get email on this otherwise. If you’re looking to use LUFA on the Arduino Leonardo board, here’s what you have to do.

Firstly, you need the current trunk version of LUFA – not the latest release. Not only does the latest trunk have board hardware definitions that the current release lacks, but it also contains a (preliminary) compatibility fix to the core to make it work with the Leonardo bootloader. Special thanks to Simon Inns for both his debugging help and the donation of an Arduino Leonardo board so that I can continue my development efforts with it. You can download the latest LUFA trunk here.

Secondly (Windows only), you’ll need to have downloaded the Arduino 1.0 IDE from the Arduino website. You’ll need this for two reasons; firstly, you’ll need the driver INF file it contains in the arduino-1.0\drivers directory, and secondly, you’ll need the Windows build of the AVRDUDE application that it includes in the arduino-1.0\hardware\tools\avr\bin. You need to add the latter to your system PATH variable so that you can run it from any folder from the command line. You can download the Arduino 1.0 IDE from here.

Thirdly, you’ll need to alter the project makefile that you want to compile. The relevant makefile magic here is:

MCU          = atmega32u4 # Change this
BOARD        = LEONARDO # And this
F_CPU        = 16000000 # And finally this
AVRDUDE_PROGRAMMER = avr109 # Add this
AVRDUDE_PORT = COM32 # And this too (use your correct COM port)

Those are the only lines that need to be changed from the standard LUFA makefile template. Note that on my system the bootloader appears as COM32, but on your system this will no doubt be different, so alter the AVRDUDE_PORT line to suit your own environment. If you use Linux, this line will most likely be /dev/ttyACM0 or another similarly named virtual USB TTY device.

That’s it – with the small changes to the project makefiles, you can then download a new application by pressing the reset button on the board, and running make avrdude from the command line shortly afterwards (while the L LED is still fading in an out to signal the bootloader is running).


Comments: 41

Leave a reply »


I’m working with Leonardo and am trying to get the bootloader to NOT flash the L-LED while the bootloader is active. I built your bootloader and loaded it onto a atmega32u4 but I cannot get the driver to install to recognize it.

The device is showing up in the Windows device manager as “LUFA CDC Bootloader”.




Which driver are you using, the Leonardo INF, or the one with LUFA? If the latter, you will need to grab an updated copy of the driver INF from here: as there was a missing section that would cause it to fail under 32-bit Windows installations. If you want to use the Leonardo driver and the Arduino IDE, you will need to modify the Descriptor.c file so that the VID and PID values match those in the official Arduino INF file.

– Dean


The updated INF did the trick. Excellent work and thanks for the quick response.




Sorry, one more question… The boot loader runs on power up and the board shows up as the LUFA CDC bootloader in device manager. I uploaded a sketch and it works fine.

However, when I power the board down and back up, it appears to be stuck in the bootloader until I upload a sketch.

What am I missing?



You’ll need to use the modified CDC bootloader code straight from the Arduino project:

Which has some slight changes to the stock LUFA version – the addition of the LED pulsing (which you can remove) and the automatic timeout and jump to the user application. The original LUFA CDC bootloader does not have a timeout and jump, which is why you are seeing your board stuck in the bootloader which is the first thing run on power up as the Arudino board has the BOOTRST device fuse set.

– Dean



Yes, I haven’t been able to get that code to compile and run against your new code for Leonardo. And when I compile it against the LUFA-111009 code, the drivers don’t seem to work.

I have to say, the Arduino project sure hasn’t made it very easy to work with the bootloader code for Leonardo (maybe too new?) but I certainly appreciate the clear way you have set up your bootloader code and the methods to modify it.

Anyway, I go back to trying to get the caterina code to compile correctly.



Hi, great work! I wonder if it would be possible to run LUFA as RNDIS Device on LEONARDO?


The raw RNDIS class driver will work on it, but the demos currently in LUFA consume too much RAM as they need to buffer full Ethernet packets in both directions. If you design it to consume packets with some sort of external buffering or if you simply discard too-large packets you might be able to get it to work.

– Dean



First, let me say: great work. I’m a programmer turned student doctor and have been very interested in moving toward medical device design, and as a result have started trying to link the two through embedded tech. –Your articles are very well written and incredibly helpful. —

Second: help, please.

I’m working on an EEG I designed and chose to use the atmega32u4 for the go between (e.g. between the analog side and SciPy in Python). I bought a promicro 3.3v from for the breadboarding, and I’m trying to load the LUFA bootloader. I hate posting for help, but medical school is really busy, and this (probably easy) issue is dragging on.

Im on a Mac. Using Crosspack. I checked the fuses, the bootloader is 4K bytes, 2K words. I continue to get the following:

/usr/local/CrossPack-AVR-20120217/lib/gcc/avr/4.5.1/../../../../avr/bin/ld: section .apitable_trampolines loaded at [00007fa0,00007fb7] overlaps section .data loaded at [00007f36,00007fc7]
collect2: ld returned 1 exit status
make: *** [BootloaderCDC.elf] Error 1

I’m trying to think of other relavent technical information… I abstracted what I could from this article, and Im compiling from the latest release you linked out to on this page.

Any advice would be much appreciated.




Looks like your version of GCC is building the bootloader too large for 4KB of FLASH space – the bootloader has a set of API functions location at the very end, so that the user application can perform self-programming. The error you are seeing is telling you that the regular bootloader program code (.data section) is so large it is conflicting with the special API section I create (.apitable_trampolines section). You can either remove the BootloaderAPI.S source file from the makefile to remove the API functions and give your compile a bit more space to work with, or upgrade your compiler version. I build with the latest Atmel Toolchain, which has GCC version 4.6 in it which managed to compile in under 4KB.

The other alternatives if you can’t find a newer compiler and need the API functions would be to either a) list your hardware so I can build it for you or b) switch to an 8KB bootloader section size.

– Dean


Thank you Dean.

A few follow up questions, if you dont mind:

1) So, rather than remove the BootloaderAPI.S, can I just extend the size of the bootloader section to 8KB, 4Kwords?

2) Downloading 4.6+ and compiling it: I assume this means that the later versions write more optimized translations of the C to asm?

3) Im still new to avr-gcc,libc, etc. How would I have known (this may not be an easy question to answer) that this was what was happening?

Thank you,


> 1) So, rather than remove the BootloaderAPI.S, can I just extend the size of the bootloader section to 8KB, 4Kwords?

Yes, just change BOOT_SECTION_SIZE_KB = 8 in the bootloader makefile, and recompile. Make sure your device fuses are set for a bootloader of 4096 Words (one AVR8 “word” is two bytes).

> 2) Downloading 4.6+ and compiling it: I assume this means that the later versions write more optimized translations of the C to asm?

In general, yes. There are always some regressions in some small areas and the 4.x series of GCC produce larger code than the old 3.x series for AVR8 devices, but the latter contains so many bug fixes and new features that using the very old compilers isn’t worth it. Atmel provides an official Toolchain for Windows and Linux on their site that I test my code with, and which I recommend.

> 3) Im still new to avr-gcc,libc, etc. How would I have known (this may not be an easy question to answer) that this was what was happening?

The key is the “section [xxx] overlaps section [yyy]” in the error output. The device data is split into a number of different virtual sections during compilation, which group together data loaded into flash (.data), EEPROM data (.eeprom) and a few others (.bss and some others). If two section’s data overlap, it means one is too large for the address space it is given, thus, there is too much data in that section for the destination to handle.

For the bootloaders, I make a special custom memory section and fill it with the API functions and data, and use some command line trickery to map it at the right place of FLASH. That means that the last part of the memory space used by the normal program data can overlap with the special section I set aside, causing the linker to fail.

All this is fairly advanced stuff, and something I’d recommend not looking too deeply into until you have a basic handle on the toolchain. Custom sections, linker scripts, and other advanced features are fascinating to me and useful in a limited range of circumstances, but you would be much better off working out the basic toolchain for now and research the funky extra features when you are in a situation that requires them (such as when writing a bootloder).

– Dean


Thank you for the continued help. Noted on the advanced stuff. Yes, getting the basics with the atmega32u4’s datasheet, and avr-libc are my top priorities.

I have not looked into the “why” yet, but I compiled and installed avr-gcc 4.70 and ran make clean; make avrdude from the CDC dir of the bootloader and received the following:

[LNK] : Linking object files into “BootloaderCDC.elf”
avr-gcc -lm -Wl,,–cref -Wl,–gc-sections -Wl,–relax -mmcu=atmega32u4 -Wl,–section-start=.text=0x7000 -Wl,–section-start=.apitable_trampolines=0x7FA0 -Wl,–undefined=BootloaderAPI_Trampolines -Wl,–section-start=.apitable_jumptable=0x7FE0 -Wl,–undefined=BootloaderAPI_JumpTable -Wl,–section-start=.apitable_signatures=0x7FF8 -Wl,–undefined=BootloaderAPI_Signatures BootloaderCDC.o Descriptors.o BootloaderAPI.o BootloaderAPITable.o ../../LUFA/Drivers/USB/Core/AVR8/Device_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/Host_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.o ../../LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.o ../../LUFA/Drivers/USB/Core/ConfigDescriptors.o ../../LUFA/Drivers/USB/Core/DeviceStandardReq.o ../../LUFA/Drivers/USB/Core/Events.o ../../LUFA/Drivers/USB/Core/HostStandardReq.o ../../LUFA/Drivers/USB/Core/USBTask.o ../../LUFA/Drivers/USB/Class/Common/HIDParser.o -o BootloaderCDC.elf
collect2: error: ld terminated with signal 11 [Segmentation fault: 11]
make: *** [BootloaderCDC.elf] Error 1



Sadly I can’t help you there – a segmentation fault in the linker means there’s a bug in binutils somewhere which will need to be patched. Segfaults should never, ever occur – please file a bug with the binutils team so they can look into this. Without a normal link failure error message I can’t even begin to work out what is causing it to fail, so my only advice for now would be to use the current stable Atmel Toolchain release over the newer version.

– Dean


OK. Ill try another version of binutils and see.

How would I go about getting a compiled version from you, per your offer?



Precompiled versions of the bootloaders are available at Note that each bootloader class have multiple versions available depending on the board hardware, crystal frequency and bootloader section size. Most of them are compiled with BOARD=NONE which means your board’s LEDs wont flash when it’s running, but it will otherwise work just fine.

– Dean


Hi Dean,

Sorry for the delay, I had an endocrinology final and had no room for anything but reading medical textbooks.

I downloaded the appropriate precompiled bootloader. It seems to work, however I get:

avrdude: verifying …
avrdude: verification error, first mismatch at byte 0x7004
0x8b != 0x6e
avrdude: verification error; content mismatch

A simple test hello_world blink.hex works, but the device stops enumerating after uploading the program and then will only enumerate for the 8 seconds or so the bootloader is up after a reset. E.g., if I run a slightly more complicated program that seeks to communicate over the bus, it cant – there is no device.

I found this thread:

where this seemed to be a known issue with a similar setup (you were involved in the dialogue).

I guess at this stage my question is: am I missing something silly, or is this the same bug? If the latter, then obviously I can’t fiddle with the bootloader as its precompiled.

For anyone else in the future reading this blog/solution: this is the I am working with.

Thanks as always for your help,



That thread was discussing a different issue – this is a new one, I’m afraid. It looks like you are trying to program in a bootloader and not a normal application, is that correct? If so, you can’t overwrite the bootloader section using the bootloader that is already installed, you need to use an external programmer instead. If you are trying to write a normal user application, then it is most likely too large for the device (minus the space occupied by the bootloader section).

– Dean


Sorry, I figured it was still relevant as it had todo with getting the bootloader onto a Leonardo style board (the 3.3V promicro from SF is a Leonardo-ish).


For the record: I did load it with the avrispmkII. Bootloader went on OK, then, as I stated in my previous post, failing to enumerate.


In this case it’s most likely the device fuses then – you need to make sure they are set for the correct bootloader section size. Note that the datasheet lists the bootloader size in 16-bit words while I (and GCC) use bytes, so if you use the 4KB section size you need to set the device fuses for 2K words.

– Dean


Any further help would be much appreciated. I have moved the thread to:

out of respect for this threads integrity.

Thanks again for all your work/help,


Hello, i have tried to run some programs from the archive in an Leonardo clone from olimex, i changed the board to OLIMEX32U4, OLIMEXT32U4 and LEONARDO but no one works, i have put code to toggle a led but the firmware doesnt run, it is necessary to change the bootloader?


Did you also change the makefile F_CPU value to match the crystal on the board? I seem to remember the Arduino boards using a 16MHz crystal and not the 8MHz crystal the demos are pre-configured for. If you make a simple LED flasher, does that run (without LUFA)?

– Dean


Hello, thanks for your answer. Now the thing works, i dont know why but i was using avrdude compiled from source to upload the LUFA firmware, when i used the avrdude that comes with the arduino package everything works fine. you know why?


I’d have to see a log of AVRDude, generated with -vvvv option to be able to narrow down the possibilities.

– Dean


here is the output of avrdude svn:

here from avrdude arduino 1.0.1:

the only difference i see is at the end, the “skipping page…” lines


I just did a comparison between the two; the major difference between the two is that the precompiled version sets up the flash destination block address once, then relies on autoincrement within the device, while your SVN version sends a new SET ADDRESS command after every block. The odd thing here is that the address is supposed to be a flash WORD address and not a byte address, but your SVN version of AVRDUDE is sending a block address increment of 128 for every 128 byte blocks it writes. Either the version of AVRDUDE you are compiling with is buggy, or the reference bootloader from Atmel is.

– Dean


I think that the svn version is buggy, i have downloaded a tar.gz from previous version and worked ok


Just a quick note about the ld segv, it’s caused by using the -relax option and is fixed in the binutils development repo – see


Any more in-depth instructions on doing this ?.

‘make is not recognized as an internal or external command’

My ultimate goal is to upload a hex file using the CDC bootloader (as is used on leonardo arduino by default).

However, I need to know the commands to type in-order to make avrdude upload the HEX file.

And the settings/steps required to prepare the HEX file for boot-load-ability when building it in AtmelStudio.



Hi Richard,

That looks like you either haven’t got the AVR toolchain/MSYS utilities installed, or they’re not added to your system PATH. See the “Windows Prerequisites” section of the manual .

– Dean


[…] the source and made a copy of the DemosDeviceClassDriverMouse directory. Then I followed Dean’s instructions to edit Makefile to match Arduino Leonardo. You only need to change the MCU, BOARD and F_CPU […]


Thank you for this post, I had originally used a custom configuration for a Chinese clone of Sparkfun Pro Micro (which is Leonardo compatible), but your instructions saved me several tweaks and It Just Works.

I wrote a small tutorial for the Pro Micro and LUFA, adapting your Mouse example:


Where can I find makefile in atmel studio 6.1 ? thanks
I’m using arduino leonardo ….


Hi Rick,

There’s no makefiles (directly) in Atmel Studio when using the LUFA extension via ASF, the internal build system of Atmel Studio does the build management. Technically this build system is feeding an auto-generated makefile into GNU Make behind the scenes as far as I remember, but ultimately you will need to adjust the Toolchain settings in the GUI rather than try to directly edit any makefile. From inside Atmel Studio go to `Help->LUFA->Getting Started` and expand out the sections on the help page that shows up to get instructions on editing the toolchain settings.

– Dean


Hi Dean,
Thank you a lot for your library. I tried example project Generic HID device demo/AVR8/Class driver API in AtmelStudio7 and the board is not recognized by PC anymore, just bootloader appears for a couple of seconds in device manager. What could I have done wrong?

In project setting I changed BOARD in Toolchain->Symbols to BOARD_LEONARDO, added headers Board and LEDs taken from GitHub to the folder LUFA expects them to be and flashed using slightly modified python script from ( My PC runs Win7, USB port is 2.0


Hi Gryphon,

Did you also change the project device to the ATMEGA32U4?

– Dean


Thank you, Dean. I’ve forgot to do so. After changing the device to 32u4 everything worked OK.


Firstly, some very good information on here.

I have a question and I am hoping someone can shed some light on it.

I have a product running an Atmega32u with Caterina-Leonardo board definition in the Arduino IDE. I wish to change the COMM&LTP Listing to something other than Arduino Leonardo.

I have my own custom PID/VID which I included in the boards.txt under the correct board listing. I then generate the compiled binary using the arduino ide (Sketch -> Export Compiled Binary). I then flash the non bootloader version of the .hex to my product using a USBTiny.

I modified the inf file of the driver to include my company and product name. Everything works.

The problem is when I first connect the usb cable, device manager shows “Arduino Leonardo” before I get a chance to load my driver. I have tried this on multiple clean computers WIN 7,8,10. Even though the driver shows unloaded and the device is missing a driver the description is still being transmitted as “Arduino Leonardo”.

Does the makefile need to be changed or do I need to recompile the bootloader?

Thanks in advance


Hi Matt,

From what I remember, Windows will choose the embedded strings in the device during initial enumeration, before replacing them in the Device Manager with the ones from the driver INF file. That means that if your board is running the official Arduino bootloader (which it might, if you only flashed the app portion of the device without modifying the bootloader region) it will first enumerate with their VID/PID and descriptor strings, before jumping to your application (which presumably has your own custom USB strings embedded in it). The way to fix this would be to recompile the official Arduino bootloader from source with your own descriptor strings — and VID/PID too, which you’re at it — so that the host shows the strings you want regardless of where it is sourcing them from.

– Dean


Leave a Reply

(will not be published)


Vital Stats

  • 35 Years Old
  • Australian
  • Lover of embedded systems
  • Firmware engineer
  • Self-Proclaimed Geek

Latest Blog Posts