Where are the ports?!

Something that’s been on my mind for a while (and others, it seems) is to port LUFA. Where to port it to is a matter of great debate, but the concensus is generally towards both porting to other compilers and other microcontrollers.

So what is required for a port? LUFA uses a bunch of GCC-only features to keep the code simple and easy to use – like GCC weak function aliases so that user code can supply event handlers to the library in a similar way to ISRs in GCC. I’m still not certain if that was the right direction to go in (misspelling an event doesn’t cause an error, leading to compile time checks via the makefile – but on the other hand, you only need to define the events you’re going to use) but it’s now so intrenched that I wouldn’t dream of trying to change it to something different. A dynamic stack allocation (like the alloca() function) is also a must, so that the library can make dynamically sized buffers in the stack for use within a function without having to use malloc() and risk fragmenting the heap. Other language extensions such as C99 support are also a must.

On the hardware side, LUFA is pretty much designed for and around the specific USB controller used in most of Atmel’s USB microcontrollers. That means that ports to other architectures almost certainly require the microcontroller to have been made by Atmel, so that I don’t need to rewrite the entire library for a different underlying register system. That still leaves architectures like the AVR32 and Atmel 8051 or ARM based controllers as contenders.

These last few days I’ve actually tried to start some ports, with limited success. So that no one can accuse me of beinglazy (after all, no SVN commits were made during this process) I’ll go over them a little here.

PORTING TO THE ATMEL SAM7 (ARM):

This one’s been a bit of a non-starter. Thanks to Casainho’s generous donation a while back I have a SAM7 board and JTAG, but I haven’t even managed to load code onto it yet. This will require a lot of learning, since everything’s so different to what I already know. What gets me is the large amount of init code required to get the thing to even be *ready* to execute a user app. Beats me why ARM is so popular; while it may be in almost every damn controller made in the last decade, it’s a bugger to get going with. I’ll come back to this one once I’ve got at least one other architecture going.

PORTING TO THE IAR COMPILER

By all acounts, porting to another compiler for the same architecture should be the easiest task of all — after all, you really only need to account for different header files and minor syntax differences. Optimisic, I downloaded the free 4KB edition of IAR, and got to work. After a lot of typing, I managed to get most of it sorted — but then got hung up on the lack of an alloca() for IAR. In GCC, you can do things like:

uint8_t MyBuffer[MyVariable];

Or:

uint8_t* MyBuffer = alloca(MyVariable);

To allocate space for a variably sized buffer onto the stack. This avoids having to use a fixed size buffer (sometimes the size isn’t known at compile time, and I don’t want to (or in some cases, cannot) fix the buffer sizes. Of course, malloc() would work just as well if I added a free() after the buffer’s lifespan, but that would increase code size, have the possibility of heap fragmentation and is just an ugly solution when I just want to be able to reserve a bunch of stack space for tempoary use within a function. GCC can do it, but this $2000 heap of bits can’t, to the best of my knowedge and search abilities. If anyone knows of a way around this, send me a message and I’ll complete the port.

PORTING TO THE AVR32

This is what I’ve been focusing on over the last two days after my other porting attempts failed. I received an EVK1101 board as a donation gift from a pair of very nice LUFA users who appreciated my work, and like the SAM7 board, I’ve had it sit around while I finished my University studies for the year. Cracking it out now, I’m about ready to destroy something.

Atmel have released a great compliment to their AVR32 range of microcontrollers — AVR32Studio, based on Eclipse. That’s all well and good, except that I hate eclipse with a passion, and you are required (again, as far as I can tell) to import your code into a special “Projects” directory, and cannot just make a project reference your code stored elsewhere in your filesystem. Actually, I think I just hate Eclipse in general, since there’s about 9 trillion buttons, menus and shortcuts in a program so large, it threatens to implode under the weight of its ephemeral bits.

But that’s beside the point. The thing I like about the smaller microcontrollers (like AVR8) is that you are free to work how you choose; I can program in Notepad if I like, build from the command like and program/debug my AVR using the free AVRStudio4 software from Atmel. AVR32 chips seem to be so bloody complicated that you need to use the full IDE and Atmel software framework for everything. Seriously. I spent far longer than I care to admit just working out how to get a makefile going, so I could build from an editor of my choosing — it’s not as simple as it seems and apparently no one else does this. I ended up having to look at the AVR32Studio console output while building a sample project to find out which flags avr32-gcc needs to be able to produce something that is loadable into my UC3B micro.

Next, I was a happy chappy, adding a million #if defined(__AVR32__) everywhere to make alternate macros for the AVR32. The standard library for the 32-bit AVRs is different to avr-libc, but overall I think it’s reasonaly nice to have both bitfield and mask versions of everything at your fingertips, even if it is a little hard to work out at first. I now have the LUFA mouse demo compiling for the AVR32 UC3B. Except it doesn’t work.

I can’t figure out how to get the right clock source into the USB controller, and how to hook into the USB interrupts. I can see that there are seperate Interrupt Controller and Clock Controller modules, but I’m still trying to work out how to code them up into something usable. This is where Atmel’s framework comes in. They’ve managed to make a framework which makes the darn chip usable, in an Arduino-esque style of usability. I just want to be able to do the simple things, but even they seem to be too difficult to acomplish without using Atmel’s framework. Yes, I could use it myself — but then why port LUFA to it in the first place since the framework includes Atmel’s USB stack?

I might come back to it in a few days, but so far I’m a little disheartened by how difficult things have been already. Bah.

 

Comments: 3

Leave a reply »

 
 
 

Have you taken a look at the Atmel SAM3U series? I’ve been playing a bit with the SAM3U-EK board and it’s pretty fun. The SAM3s come in under the performance level of SAM7 and AVR32, but still have a ton more peripherals and performance than the AVR8s (including high speed usb!). I can’t compare the experience getting it going to the SAM7 since I haven’t played with those, but it was fairly painless. The lower power helps it stay out of that “you must use our environment” requirement of the AVR32s as well; I’m using my favorite OS X text editor, GCC and GDB to get the work done.

 

How about porting to the CodeVisionAVR compiler?

Why port to ARM7, when ARM7 is becoming obsolete and replaced by the more modern Arm Cortex-M3?
It would be better to port to Cortex-M3 (and Cortex-M0 and the Cortex-M1 FPGA implementation, simliar to Cortex-M3) than ARM7.
Big companies like TI (formerly Luminary Micro), ST Micro, NXP and Atmel has introduced Cortex-M3 MCUs. And NXP has also introduced the smaller and cheaper Cortex-M0. Companies will slowly migrate from ARM7 to Cortex-M3.

 

Anders,

How about porting to the CodeVisionAVR compiler?

I thought about porting to Codevision, but the fact is that most people are either GCC afficionados or people working at a company with a site IAR license – Codevision simply isn’t as popular and far fewer people would benefit from the port. I have serious doubts about it supporting all the required features as well; after all, if the $2000 commercial one doesn’t, the cheaper one probably doesn’t either.

Why port to ARM7, when ARM7 is becoming obsolete and replaced by the more modern Arm Cortex-M3?

Because I have the ARM7 hardware. The trick is to (eventually) get myself started in the world of ARMs, since there’s a fairly large learning curve just to load a program into the board. Once I work out how to get the ARM7 going it should be fairly trivial to port to other Atmel ARM chips. So far only the 8-bit 8051 USB chips are looking like a likely port in the near future.

Cheers!
– Dean

 

Leave a Reply

 
(will not be published)
 
 
Comment
 
 

 

Vital Stats

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

Latest Blog Posts

RSS