Recent LUFA changes

Yikes, time runeth away once again. Not much has happened in the last few weeks, except my probation period ending, making me an official full-time Atmel employee now, and my reluctant starring in a new set of pilot videos:

Since it’s been so darn long since I posted about something technical that I thought I’d try doing that today.

So, I’ll admit it, I’ve been putting off proper LUFA development over the past few weeks, since the next step in my quest to refactor things to the point where multi-architecture demos can become a reality requires an awful lot of work. And not fun work either, mechanical “I would script this if it was practical” type of mechanical work. That’s not to say I’ve been sitting around idle, it just means I’ve been focusing my time learning some fun new things and performing other refactoring tasks (in addition to support and bug fixing). So here’s what I’ve been up to.

The LUFA Board System:

A problem lies in the current board driver system: currently each board has a folder full of individual hardware driver header files, with the actual driver code implemented as inline C functions for speed and size reasons. in the user application, you set your BOARD={Something} value in your project makefile, include the relevant <LUFA/Drivers/Board/XXXX.h> driver in your code and away you go. If the application is recompiled with a different BOARD setting, the driver dispatch header automatically picks the appropriate driver, or defers to a <Board/XXXX.h> header in your application directory. Wonderful.

Or at least, wonderful if you are using a board that has the same features as the USBKEY board I develop with, since that’s how I design the UI for the demos that ship with LUFA. If you use a different board without a Joystick for example and try to compile the Keyboard demo, you’ll get an error about not being able to find a Buttons.h and Joystick.h driver. Fixing this requires manual tweaking of the demos, which isn’t very nice to newcomers.

So, the plan I’ve come up with is to replace the current board system, leading me into the gigantic ball of apathy that you’ve all seen over the last month. This requires the creation of a new per-board board.h header file to act as the new board driver header, which will be include in all user projects. This header file will in turn include all the board specific drivers, but also include a new Board_Init() function to automatically initialize all the board hardware.

Doing this will allow all the user applications to just include the one board driver header file, rather than having to pick-and-choose the individual driver headers. It will also mean cleaner initialization code, but most importantly it will mean compile time detection in the user code of the board driver features. With this new system I will be able to change the demos to detect if a joystick, buttons or other hardware is available and automatically provide some sort of demo UI to suit the board being targeted. No more compile errors.

I’m tossing up whether to press ahead with a new LUFA release in the meantime or to wait until I find enough time to undertake this – does anyone have any thoughts on this?

The LUFA Documentation:

So, with the new release of Doxygen 1.8.1 I’ve done a bit of spurcing up of the LUFA documentation. I’ve gone and re-tweaked my small customizations to the standard theme – I can’t do visual design at all, but I found something I liked a bit more than the defaults – and fixed up the documentation index. In the previous 120209 documentation a lot of the helpful pages were shoved in a “Related Pages” node due to a Doxygen bug, which is no more in the new release. To commemorate that, I’ve cleaned up the ordering and structure a bit to make things a bit easier to read. I’ve uploaded a temporary export of what the new documentation will look like, where you can see the new index page list.

In addition, I’ve added some new pages listing known issues I need to fix up, the new LUFA build system (more on that in a moment), added more information giving the prerequisites for building on both Windows and Linux platforms and showing one way that you can export the library core for importing and use in Atmel Studio 6 projects.

No groundbreaking changes, but any improvements are always a good thing, and I think this is one small step towards making the project as a whole a little more accessible to new developers.

The LUFA Build System:

I finally got completely fed up with the current build system – having a gigantic 600+ line makefile in every application directory was killing me due to the maintenance requirements, and frustrating users due to the apparent complexity. The LUFA makefiles were built from the public domain template found in the old obsolete MFile project subcomponent of the now obsolete WinAVR project with a few additional tweaks to make them useful for LUFA based projects. However, inside each of these giant makefiles was a huge amount of repeated “magic” rules that most people will never touch, and a select few variables that need to be adjusted for different build targets. Other problems were crazy error messages if things went wrong in some way, untracked dependencies causing odd build behaviours if multiple make targets were invoked at the same time, and output files generated from stale object files in some cases.

To combat this, I’ve created my own – yes, I’ll wait a moment for you to finish cringing – build system for LUFA. This is actually just a set of loosely coupled makefile modules, which can be included in the application makefile to obtain additional functionality. I think this is the best solution, as it allows me to edit the modules all in one place, and have the changes propagate automatically out to all the library applications. It also means I can fix up all the problems in the above, so the new modules have proper dependency tracking, and give sane error messages when things go wrong.

Here’s an example of what a typical project makefile looks like, contrasted to what we have in the current 120219 release. It’s a big change, and I really think it’s a great improvement. You can now get some nice build help by running make help from any makefile that uses the CORE LUFA build system module, listing all the available targets and other relevant information. There’s also the aforementioned new chapter of the manual with detailed documentation on how to use it. Of course, the manual has also been updated to give an application makefile template and explain the new makefile variables.

I’m quite proud of this, and I’ve learned an awful lot of the ins-and-outs of GNU Make while on my quest to build it. I’ve been considering opening up the build system into a separate public-domain project so that it can be adopted everywhere, rather than the crazy makefile template everyone is currently using.

New LUFA Git Mirror:

When I first made the LUFA Git repository mirror, I made a bit of a boo-boo, as I forgot the “--stdlayout” switch when creating the initial GIT-SVN import. That has resulted in the current GIT mirror containing a literal import of the LUFA SVN repository layout, with tags and branches being located in the sole master branch of the GIT tree, something I didn’t notice until it was too late to try to change it.

After a couple of different people emailed me about it over the last few months – including one very helpful one from a LUFA fan with some great insights into how best to fix it – I’ve gone ahead and made a second public Git mirror with the imported layout corrected. This new repository will be switched over to become the official mirror soon once I’m satisfied nothing has broken, with the existing mirror still being deprecated but still maintained for those who depend on it. The new GIT mirror has the tags properly added as read Git tags, and this now results in downloads of the current HEAD of LUFA being around 5mb rather than the >30mb it used to be.

So that’s the latest LUFA news.



No comments so far.

Leave a Reply

(will not be published)


Vital Stats

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

Latest Blog Posts