Dear all experts
I have to implement a state machine on my project using switch case statement look like this.
//----------------------------------------- switch(state) { case STATE1: ... state=STATE2; break; case STATE2: ... state=STATE4; break; case STATE3: ... state=STATE1; break; case STATE4: ... state=STATE3; break; }
Later I would like to add some conditions to change direction of the way it goes by omitting 'break' and adding some 'if' statements to take effect, then the code will look like this.
//----------------------------------------- switch(state) { case STATE1: ... if(condition 1) { state=STATE2; case STATE2: } ... state=STATE4; case STATE3: ... if(condition 2) { state=STATE1; case STATE4: } ... state=STATE3; }
If any of you have ever coded up a state machine in C before. Can you suggest me whether it will given a result in compilation error or run time error or not?
Another question is how is the different between the state machine using function pointer and this ordinary switch case statement in term of performance, amount of code, access time latency...etc? : )
Many thanks.
"Can you suggest me whether it will given a result in compilation error or run time error or not?"
It will not result in a compilation error. The switch/case construct is a bit like a programmable goto. Using it like you have proposed is precisely what goes on "under the covers" in some state machine implementations and, in fact, is exemplified by the likes of FreeRTOS (using coroutines) and Protothreads.
As for the run-time error aspect of it all, the switch/case combined with if/else, looping constructs, or anything else for that matter, has no run time error reporting mechanism. Any errors would be entirely yours to make.
"Another question is how is the different between the state machine using function pointer and this ordinary switch case statement in term of performance, amount of code, access time latency...etc?"
That, I think, is best for you to prototype and measure for yourself in a setting relevant to your target objective.
"exemplified by the likes of FreeRTOS (using coroutines) and Protothreads."
I was interested, so I did some googling - and found this:
www.chiark.greenend.org.uk/.../coroutines.html
I think it might've saved me a lot of work if I'd read it a couple of months ago...
That (using the static version) and http://www.sics.se/~adam/pt/ (Protothreads) are are almost identical and probably best suited to the 8051 architecture (compared to FreeRTOS coroutines) because of their simple implementation and by not using function pointers. I have used Protothreads on a number of projects that fit the main-loop model recently discussed here. Protothreads includes a rudimentary counting semaphore mechanism. For architectures like the 8051 and PIC which have very a efficient 'bit' data type, I have extended Protothreads to include a binary semaphore mechanism.
I have not yet used FreeRTOS or its coroutines option, but am considering it for a current non-8051 project because it does offer a priority mechanism (among other things) and by keeping threads in ready/blocked lists, doesn't burn cycles continuously entering thread functions, chasing down the switch to a case only to find that the awaited for condition isn't satisfied. One could, of course, extend the Simon Tatham coroutines or Protothreads coroutines to use priorities, lists, etc.
Andy, Interesting article. Thanks for sharing it.
No problem!
Note that Adam Dunkels cites it as his inspiration for his Protothreads in the link that Dan provided.
(he also quotes a post of Dan's at 8052.com)