Archive for July, 2008

Thoughts on C++ in small memory footprint embedded development

Background

During my senior year I took on an ECE491 Independent Project course to follow up on a ECE476 Microcontrollers project. On the completion of ECE491 we had created a Low Speed USB 2.0 stack library for the Atmel Mega32 Microcontroller using ~$6 worth of hardware and ~6000 standard lines of C.

Everybody in ECE476 used the CodeVisionAVR IDE, but we were a unique group in using avr-gcc. Though most students were okay with it, there were some minor features missing from the CodeVision compiler at the time, such as the ability to allocate objects on the heap. ;)

We rewrote the ECE476 code base in ECE491, again using avr-gcc, because we realized that the USB protocol was a lot more complex than the stack we had originally written. One of my main gripes in ECE491 was that I was writing highly object oriented code in a language which didn't support any of the syntax. I'm starting to hack on the code base again, and a port to C++ seems like a good idea (since avr-g++ is also available), but there are some significant trade-offs running through my mind.

The Trade-offs

Things I want from C++ in the project:

  • Namespaces — I hate worrying about global namespace issues. Though I'm not a huge fan of C++'s namespacing implementation, I'll sure take it over no namespaces. :)

  • Templates — Casting to and from void *s in "containers" and haphazardly faking (efficient) tuples with void **s is extremely dangerous and causes really annoying bugs.

  • Class syntax — It's ugly faking object orientation in C. Supported syntax is important to me because writing object oriented code in C "requires" you to prefix every function with a class name, like so:

    void data_packet_recalculate_crc16(data_packet_t self) { ... }
    

    Plus, cool tools like doxygen don't pick up on the fact you're writing in an object oriented style and adjust output accordingly (not that I'd expect them to).

  • Exceptions — If you've ever written a large amount of C code, you learn how precious basic exceptions are. gotos and cleanup code tend to get old after a short period of time.

  • Default arguments — I'm a fan of default arguments since it cuts down on the number of wrapper functions you have to write and maintain (though keyword arguments are even cooler :).

Things I don't want from C++ in the project:

  • Larger binaries — The Atmel ATMega32 has 32KB of memory to fit my entire software stack, which I've found to be extremely confining, even with my C implementation (which manages reuse through void *s). The fact that templates cause the compiler to replicate code makes me worry.

  • Don't really care, but maybe worth mentioning: vtables — I want inheritance with vptrs because it makes maintenance significantly easier for the straightforward class hierarchies; however, 16MHz chips are slow. Damn slow. Having vtables for some of the most primitive data structures seems ominous; however, I'm pretty sure that performance is a lot lower on the totem pole than maintainability in this instance.

The First Google Hit Says...

I've read through Reducing C++ Code Bloat and found it thought provoking. Though the article writes about gcc 3.4 and I'm using gcc 4.2, I can't imagine that the underlying code-bloat concepts have changed much. I'm betting a lot of the compiler directive advice is taken care of by gcc's -Os, but I'll make a note to check it out.

It seems sensible to give up on exceptions ahead of time, but there seems to be some hope that the compiler can figure out good code reuse for the templates. I'm compiling to ELF, then performing and objcopy to turn it into Intel Hex object format — I'm hoping that the conversion is trivial and the good ELF compilation referenced in the article will stick.

In the end it seems like I'm just gambling on how much template reuse will occur. I sure hope that if I do all the porting-to-C++ work it optimizes well — template hoisting looks like one of those idioms I'd prefer to leave alone. :(

From Blogger to Wordpress

I've decided to move my blog from my Blogger cdleary.blogger.com account to a Wordpress install on my personal blog.cdleary.com domain. Once I took a gander at all the new features and capabilities of Wordpress, the choice wasn't very difficult.

Issues with Blogger

Posting mixed text and code over the course of my blogging history presented interesting problems. From what I could tell, each blog on Blogger seems to have a global "interpret newline as <br />" setting, which prevented me from switching styles (to use <br /> explicitly) without editing all of my previous posts. When you mix this with the fact I was using Vim's "generate highlighted syntax as HTML" feature in lieu of searching for a proper way to post source code in Blogger (which I found far too late in the game :), the GeSHi Syntax Highlighter plugin for Wordpress was looking mighty fine. I haven't pinpointed any exact reasons, but the line breaks and HTML equivalents feel a lot more natural in Wordpress than they did in Blogger.

The blogger backlinks ("Links to this post") capability wasn't cutting it for me. Due to either to the infrequency of my posting, the irrelevance of my posts, or my (heretofore) unwillingness to advertise my blog, I couldn't find backlinks via the Blogger service that I knew to exist. The ping system that Wordpress employs seems a lot more enabling for a low-profile blogger like myself. It's possible that my previous blog never received a ping and that Blogger actually has this feature as well; however, I knew of a few other blogs that linked to my Blogger blog that didn't show up (comments were disabled — maybe that was a problem?).

Easy Feed Migration, Evil URI Migration

Thanks to FeedBurner decoupling my feed URI from my blog URI, the feed migration process was easy as pie. It makes me think that everybody should use FeedBurner, if only for an extra level of indirection between the blog hosting and the RSS pollers.

I was evil, however, and totally dropped my old URIs. My Blogger blog wasn't very highly read or recognized, so I figured rather than go through some painful URI redirection process via <meta> tag manipulation in the blogger template, I'd just delete my old blog. Slightly evil, but significantly productive. I'll just cross my fingers and hope that the people who cared were subscribed to my RSS feed as well. :/

Trying out Comments

I did not enable comments on my Blogger account. I theoretically don't like blog comments — they provide inadequate space for a conversation and proper synthesis of ideas surrounding a conversation. I'm fairly convinced that commenting systems are flawed in low-traffic blogs like my own, and that blog-entry-to-blog-entry responses are much more maintainable, scalable, and helpful for bloggers without thousands of readers; however, I'm willing to give comments another short test period before turning them off.

Categories and Tags?

One of the most foreign things in the Wordpress installation is the category-tag-duality. It seems that these two things are distinct, as explained in the Wordpress Glossary:

Think of it like a Category, but smaller in scope. A post may have several tags, many of which relate to it only peripherally.

For the time being, I've only promoted a few of the most-used labels from tags to categories, which I figure I'll continue to do once the tags cross some arbitrary threshold of posts. It sounds kind of neat to have two tiers of categorization — you can go a little wild in the lower tier while keeping the upper tier simple and clean.

Experimenting with C++ inheritance diamonds and method resolution order

It seems like g++ uses the order indicated in the class' derivation list over the order indicated in the base specifier list, as in the below example:

#include <iostream>

using namespace std;

class Animal {
public:
    Animal() {
        cout < < "Animal!" << endl;
    }
};

class Man : public virtual Animal {
public:
    Man(string exclamation) {
        cout << "Man " << exclamation << "!" << endl;
    }
};

class Bear : public virtual Animal {
public:
    Bear(string exclamation) {
        cout << "Bear " << exclamation << "!" << endl;
    }
};

class Pig : public virtual Animal {
public:
    Pig(string exclamation) {
        cout << "Pig " << exclamation << "!" << endl;
    }
};

class ManBearPig : public Man, public Bear, public Pig {
public:
    ManBearPig(string exclamation)
        : Pig(exclamation), Bear(exclamation), Man(exclamation)
    {
        cout << "ManBearPig " << exclamation << "!" << endl;
    }
};

int main() {
    ManBearPig mbp("away");
    return 0;
}
cdleary@gamma:~/projects/sandbox/sandbox_cpp$ g++ diamond.cpp && ./a.out
Animal!
Man away!
Bear away!
Pig away!
ManBearPig away!

Note that this experiment is a pretty (very) weak basis for the conclusion — it could be using lexicographic order, order based on the day of month, or any number of other unlikely heuristics :) A lot more experimentation is necessary before getting a discernible pattern, but I just felt like messing around.

Edit (07/27/08): Using correct "base specifier list" terminology instead of my made-up "class initializer list" terminology.

Do permalinks change when blogger posts change title?

This is a test post to figure out whether or not permalinks change when you change the title of a post on blogger. The problem is that cool URIs don't change, but sometimes I want my titles to.

A permanent HTTP redirect would probably be ideal since the slug could be correctly indexed in the future, but I wouldn't mind settling for the new content being served from the old URI.

Let's see what happens...

Update: Permalinks are indeed permanent and the new content is served from the old URI on a title change.

Problems with Python __version__ parsing

As stated by Armin and commenters [*] the change from 0.9 to 0.10 is a convention in open source versioning, and the fault seems to lie more on the version-parsers than the version-suppliers. [†] Armin also notes that the appropriate solution is to use:

from pkg_resources import parse_version

Despite it not being the fault of the version supplier, we've recognized that this can be an issue and can certainly take precautions against letting client code interpret __version__ as a float. Right now there are two ways that I can think of doing this:

  1. Keep __version__ as a tuple. If you keep __version__ in tuple form you don't need to worry about client code forgetting to use the parse_version method.

  2. Use version numbers with more than one decimal. This prohibits the version from being parsed as a float because it's not the correct format — taking the current Linux kernel version as an example:

    >>> __version__ = '2.6.26'
    >>> float(__version__)
    Traceback (most recent call last):
    ...
    ValueError: invalid literal for float(): 2.6.26
    >>> tuple(int(i) for i in __version__.split('.'))
    (2, 6, 26)
    

    This ensures that the client code will think about a more appropriate way to parse the version number than using the float builtin; however, it doesn't prevent people from performing an inappropriate string comparison like the tuple does.

Footnotes

[*]

In … and 0.10 follows 0.9

[†]

Which seems to invalidate the implied conclusion of my title How not to do software version numbers, which I now realize was stupidly named.