Monday, June 13, 2011

A somewhat half-baked embedded OS idea

I mentioned in my previous post that I had spent some time porting FreeRTOS to the SAM7 architecture before realizing my purpose was better served by looking for an existing port. But in the process I gave some thought to what kind of alternative to FreeRTOS I might cook up, if somehow the porting exercise didn't go well. I haven't thought through every detail completely, and I wouldn't trust myself to anticipate every issue until I'd actually coded the thing, which I haven't yet. My sketchy design is based on two ideas.

An aspect of JavaScript that fascinates me is that everything runs in a single thread (an idea nicely described here). Each function is the sole owner of the processor (at least as concerns the JavaScript world) until it completes, and there will be no unexpected modification of variables or data structures. No locks or mutexes or semaphores or "synchronized" keywords, no threading headaches. The price of this simplicity is that functions often are event handlers and must be written to do their work quickly and get out of the way so other events can be handled.

The second idea is something I've seen when coding applications for both Android and iOS. Communication between threads is carefully controlled. Slow operations are begun by event handlers in a UI thread, and when the work is done, another handler runs in the UI thread, supplied with any relevant results from the slow operation. Within the handler thread, JavaScript's protocol of running only one handler at a time to completion is observed. Where in Android one would invoke a Runnable object using a View.post() call, I would be inclined to create a postEvent(event,arg) function since I'd plan on doing things in C, and where presumably "arg" is pointing to a struct containing whatever information needs to be retrieved from the slow operation. That way, there is never a point in time where the slow operation and the completion handler are running concurrently, and again there is no need for arbitration of data access.

Flinging structs around requires malloc and free. That worries me a little because fragmentation, memory leaks, and low memory are all likely to be more troublesome on an embedded microcontroller than a desktop computer, and I'm not a memory allocation guru. Maybe there's some way to avoid memory allocation altogether, or maybe it will be less of a problem than I fear.

The general idea would be to implement a single handler thread and a fixed pool of worker threads. Worker threads idle until assigned a task; a handler can post a task to the worker thread pool where it will be picked up as soon as a worker thread is available. There might be an event fired when the number of available worker threads went from zero to non-zero; I haven't decided yet whether that's useful.

There would be events for various hardware stimuli: pushbuttons pressed, UART character received, Ethernet byte received, timer gone off, things like that. There would also be user-definable events which would include task completions. There would be some simple way to associate handler functions with events.

That's basically as far as I've gotten with it. Obviously there's a good deal left to do, and I won't really feel good about it until I see it doing something interesting and useful on a real microcontroller.

1 comment:

Will Ware said...

After writing that blog post, I spent some time thinking about how to do garbage collection so as to minimize fragmentation, and came up with this improvement on one of the garbage collectors packaged with FreeRTOS.

So having a decent solution to the fragmentation issue, I should get back to this project. As I think about it further, I'm more intrigued by the idea of porting an existing JavaScript engine to a microcontroller. It would likely be V8 since Google has put a lot of work into it, and has a deep understanding of JavaScript and performance in general.