Design Article

FLIRTing with 8-bit MCU OSes

Dave Armour

8/11/2009 6:00 AM EDT

I come from the 8080/8085 era. I used to hand write the code on paper then type the opcodes into an EPROM programmer. If that didn't work, I figured it out and did it again. I developed some pretty complex code that way. Since then, I've never lost sight of the fact that small is beautiful.

After reading Jack Ganssle's article "Small is Beautiful" (March 9, 2009, www.embedded.com/21580130), I felt like we were brothers from a different mother. In this world, the constant drumbeat of "more, more, more" is pounded into our heads so much that the concept of "simple is best" is lost. Everyone gets "creeping featuritis," and soon the whole place is infected with features no one wants or even needs. I'm here to tell you that it doesn't have to be that way.

The first time our hardware engineer brought a proposal to me and said it has an 8-bit processor, I said "are you nuts?" Yet, when all was said and done, I have to say I was impressed. The processor our hardware guy proposed was the Freescale MC9S08. Originally he wanted a simple super loop that he could write himself and not get the firmware guys involved. He was concerned about us catching creeping featuritis and turning the super loop into a huge 32-bit machine with way too many bells and whistles. I convinced him that that would not be the case and that I would write the firmware for it myself. My first concern was that the super loop starved other parts of the system, so I started researching what was out there that I could use.

I read Miro Samek and Robert Ward's great article in the July 2006 Embedded Systems Design magazine (www.embedded.com/190302110) on the simple task switcher because I have always preached that "good developers write good code, great developers steal." I didn't use this task switcher because I was also concerned with starvation. Their system had higher priority tasks run to completion and was based on state machines that are amazingly useful but limited when dealing with time constraints. Events get backed up waiting for other events to run to completion.

I then looked at Helium (http://helium.sourceforge.net). A great little tasker but too much overhead for what I was looking for and it was based on priorities as well. I needed something where every task has the same priority, gets its share of the CPU, and yet can have a different "weight" in the system. When I say weight, I mean a little bit more of the task's share of the CPU is going to that task. This is not to be confused with priority over the other tasks; instead, it's just that one task needs another tick or two, while all the other tasks are still geting their share. More on this later.

So after not finding anything I could (ahem) borrow, I set out to create a small multithreaded tasker that can run on an 8-bit MCU and lets every task have access to the CPU more or less when they needed it. Enter FLIRT (Friendly Little Interrupt Tasker). In the end my implementation consumed a whopping 144 bytes of flash.


Next: Enter FLIRT




Jurica

8/12/2009 3:17 AM EDT

Excellent hands-on article.

Sign in to Reply



raykeefe

8/12/2009 4:08 AM EDT

It is always good to get such a detailed description of an embedded software development like this so I really appreciate the detail you have gone into Dave.

I know they don't have a native port for the MC9S08 but did you have a look at Salvo http://www.pumpkininc.com/ when you were evaluating options?

We do a lot of 8 bit development I usually find some careful architectural design allows us to run with minimal OS features. And occasionally it makes more sense to divide the task among 2 microcontrollers than try and juggle hard real time latency requirements in a single chip. A bit like Jack's push to consider asymmetrical multiprocessor architectures.

Thanks again for a very detailed and useful article.

Ray Keefe
http://www.successful.com.au

Sign in to Reply



Ebike

8/13/2009 1:15 AM EDT

Great article. How do I get hold of Dave?

Sign in to Reply



SaurabhG

8/13/2009 4:25 AM EDT

Very insightful and intuitive, talking of small footprint RTOSes with round robin scheduling, have you checked out uC/OS-III...the other day I came across its press release (http://www.micrium.com/news/2009-03-24_Micrium-Expands-RTOS-Family.html) in which they claim that the new kernel would be supporting tasks of equal priority and moreover the system promises near zero interrupt disable time...surprising!!

Apart from the article what also caught my eye is the short biography at the end of it saying "recently laid off firmware engineer with 15+ years of experience with lots of time in hand"...just goes to show the kind of talent that is sitting idle...scary!!!

Regards,
Saurabh G.
Open up: http://code.google.com/p/uniboard

Sign in to Reply



NetJohn

8/13/2009 9:10 AM EDT

Great article that unfortunately suffers from bad editing. Could ESD please train their editors and typists that case matters, especially with code snippets? Every time I saw "Return;" in the code, I cringed.

Sign in to Reply



DaveArmour

8/13/2009 6:51 PM EDT

Looks like I got some 'splainin' to do.
Firstly, my contact info is at the end of the article.
Secondly, sorry about the "Return" statements. Word plays havoc on code. I thought I caught them all.
Thirdly, great points, thank you.
Finally, when I started the project that FLIRT came out of I tried to fulfill the requirements the best I could with what was "on the shelf". I looked at FreeRTOS, eCos, MicroCos, to name a few, but they did not suit my needs (key words here). In the end I had two strong contenders that I mentioned in the article and I tried to fulfill the requirements with them only to realize that they did not suit my needs. Getting short on time to get this done and not having found something yet I decided to see what I could put together on my own that suited my needs. I, for one, was pumped that what I came up with was so well suited to my needs and was so easily done. After reading Jack Ganssle’s article I realized here was an opportunity for me to give back to the community that I have taken from for so many years so I decided to share with the group.
FLIRT is not meant to be an “end all” for everyone just another solution to a problem; but the solution I chose nonetheless. Not perfect, thank you, never claimed it was. (what system is) But, it worked great for me even though in the end my group was laid off. Hopefully someone else can get some use from FLIRT like I did and it will be another option to choose from. Thanks to all in the community that I have (ehem) borrowed from over the years. FLIRT is my contribution back.

Sign in to Reply



Datwyler

8/17/2009 10:27 AM EDT

And, how does one get the code?

Sign in to Reply



DaveArmour

8/19/2009 9:37 PM EDT

The code is coming to a web near you.
http://www.friendlylittletasker.org
Standby until I get it hosted...

Sign in to Reply



DaveArmour

8/20/2009 6:35 PM EDT

Site is now active:

http://www.friendlylittletasker.org

Sign in to Reply



dbordwell

8/24/2009 10:57 AM EDT

How can you write about how you have burrowed ideas from everyone and then "give back" by releasing code under a highly restrictive license. You mentioned that this is another option but it cannot not be under your license. Why must someone ask for permission if it is free? The license sounds like you will charge down the road for this. If it is feedback you want or need then why not release it under GPL or LGPL and start a project. That way the community that you "gave" this to can build upon it and make it better. Will you please post why someone has to ask for permission to distribute compiler or uncompiled firmware?

Sign in to Reply



kbanks

8/24/2009 10:28 PM EDT

In your code snippets you put "placeholders" where the actual (probably assembly language)task switching code needs to go. Since you want to be able to use flirt on different CPUs, you may want to look into the setjmp/longjmp technique of task switching. Although I currently do not use threads at all (I instead use a 100% event driven/state machine style of programming), I have used setjmp/longjmp based thread switching successfully in the past (with only a single #define constant difference between platforms).

I cannot find the exact article I first saw the technique presented in (maybe C Users Journal, maybe Dr. Dobbs), but an article close to the one I'm remembering can be found at http://www.ddj.com/184409665?pgno=8.

Sign in to Reply



scalfee

8/27/2009 2:15 PM EDT

Interesting article.

Personally I hate globals, they cause problems.

1) I think you will leak tasks if you do 2 or more taskdestroy calls before in interrupt occurs.

The tasktobedeleted global will get overridden and the delete task will not happen.

2) head and tail could be replaced with one global called "current". Simple doubly linked list primitives could maintain the queues.

3) I see no reason to call processor time expensive routines like "free" in the isr. Why not free stuff immediately in the destroytask routine?

4) Since task swapping is only done on a timer tick, it looks like unused time in a task will just be wasted?

5) as mentioned elsewhere here having a separate stack for each task is expensive and very limiting. A run to completion (and then yield) scheme allows all tasks to share one stack.

I did enjoy the article and your explanations of the various tradeoffs and design decisions.


Regards, Steve

Sign in to Reply



Bluebee2007

8/27/2009 2:27 PM EDT

I started the same way.
I used to hand write the code on paper, then type the opcodes into RAM using a Monitor Program. If that didn't work, I figured it out and did it again. If it worked, I put it on a tape recorder using the Monitor Program and later made PROMs. I developed some pretty complex code that way, my biggest one was a Database Program with 12kBytes, very fast. To achieve this complexity, I wrote highly structural code and I checked every little module and every branch to be sure it always will work.
The Database Program was used to edit and show Data on a CRT, and because of all the many modules, I had to type a lot of "Jump to Subroutine"-Hexcodes, which bothered me. This brought the idea to me to number each module (nowadays called Pseudocode) and the whole CRT-Sequence was only a string of numbers, parsed by a little loop of less than ten Assembler-lines, using a Pseudocode for decision-jumps, too.
And then I discovered Forth. Everything I dreamed of was already there. I discarded further development of my Pseudocode-Program and switched to Forth. Since then, I've never lost sight of the fact that small is beautiful.

Sign in to Reply



DaveArmour

8/27/2009 6:55 PM EDT

I don't understand what the problem is with the license.
My nephew is an IP lawyer. I told him what I wanted in a license and this is what he gave me.
In a nutshell it says to use the source code as you want just do not try to sell the source code as yours or compile it into a library and sell it as yours (i.e. flirt.lib) without at least asking first. Copy it, use it in a product, throw it against the wall; I do not care. Just do not try to sell it (FLIRT) as your product. Simple enough. Actually it is less restrictive than GPL. The only reason #2 is in there is just to ensure that enhancements are fed back and everyone gets to utilize it. Isn't that the spirit of the open source community? I have not nor will I make money off FLIRT. In fact it has cost me money so far (web site, URL).

Sign in to Reply



DaveArmour

8/27/2009 7:34 PM EDT

scalfee,
Thanks for the good points.
#1 - Ouch! Correct. I never ran into that scenerio but good point taken. I will look at fixing this in a way that will keep FLIRT small.
#2 - My reasoning for this was to keep from "walking the list" too many times. Tail is where new tasks go and Head is where the base task resides.
#3 - Agreed. Miro pointed this out above. In the article I said "I could have written about how to add many different whistles or bells but that is not the purpose here." at the end. That statement was meant to cover all those cool little things like maintaining you own heap and etc. I wanted to stick to the bare bones of the idea to create a simple system from which to embelish if you wanted. Think of my use of free as a beauty mark. Well placed it looks great otherwise it is a mole. In the interest of keeping it simple I missed the mark.....it is a mole.
#4 - Correct. The ways to overcome this are very processor and system dependent so I did not mention it in the article.
#5 - My requirements stated were such that running to completion was NOT an option. I did mention that the seperate stacks we a necessary evil for this system and that if you wanted you could write a dynamic stack for your needs. I wanted to keep it very simple and my memory footprint was optimal for my needs.

Since I got laid off I have not been able to work on FLIRT because I do not have a development system for the Freescale MC9S08 at home.
Any one out there from Freescale want to pony up?

dave

Sign in to Reply



DaveArmour

8/28/2009 2:01 PM EDT

All this time off must be making my brain soft(er).
I got thinking about point #1 after I left the previous reply.
The scenerio of having multiple tasks being marked for deletion cannot happen the way I designed FLIRT. The way FLIRT is designed, only the task itself can delete itself. No other task is supposed to be deleting any other tasks. If you keep to this rule then #1 is not an issue. When a task deletes itself the very next thing to happen is a timer tick which will check for a task to be deleted. If so, remove it and move to the next task.
Everyone should keep in mind that like I said at the end of the article FLIRT is not the holy grail of taskers (or OSes for that matter). It is just a very simple way to solve a unique problem seen in MCU applications. I did not (and do not) want to make FLIRT something it is not. I do greatly appreciate any feedback aimed at helping to make FLIRT better while maintaining its simplicity.
thanks,
dave

Sign in to Reply



Please sign in to post comment

Navigate to related information

Datasheets.com Parts Search

185 million searchable parts
(please enter a part number or hit search to begin)