1

I need to make a state machine for a hardware device. It will have more than 25 states and I am not sure what design to apply.

Because I am using C++11 I thought of using OOP and implementing it using the State Pattern, but I don't think it is appropriate for the embedded system.

Should it be more like a C style design ? I haven't code it one before. Can someone give me some pointers on what is the best suited design ?

System information:

ARM Cortex-M4  
1 MB Flash  
196 KB Ram

I also saw this question, the accepted answers points to a table design, the other answer to a State pattern design.

Community
  • 1
  • 1
Adrian
  • 19,440
  • 34
  • 112
  • 219
  • This really depends on the environment. If you already have a C++ environment and you are comfortable with C++, why would you not use it. However, C++ often requires more support; setting up C++ support may take more time than coding a state machine in any language. A state machine can be data driven or it can be done with function pointers (code driven). Many 'C' systems use a simple variable in a structure and `switch/case` to implement *state*. A state is typically just an `enum` and permitted transitions; how to implement the transitions is often the difficult part. – artless noise May 15 '14 at 20:11
  • See also: [Petri Nets](http://en.wikipedia.org/wiki/Petri_net) which may apply if you are *embedded* in the interrupt sense. C++ has very nice syntax for implementing [*function pointers* with state](http://www.oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/functor/functor.html) that are often useful, depending on how *heavy* you want your state machine to be. – artless noise May 15 '14 at 20:24
  • state machines are somewhat trivial I dont understand this question, any and all languages will work just fine. For an arm cortex-m4 C or C++ whichever you prefer are your best candidates simply from a what are good languages/tools for that platform perspective. – old_timer May 16 '14 at 00:42

3 Answers3

3

The State Pattern is not very efficient, because any function call goes at least through a pointer and vtable lookup but as long as you don't update your state every 2 or 3 clock cycles or call a state machine function inside a time critical loop you should be fine. After all the M4 is a quite powerful microcontroller.

The question is, whether you need it or not. In my opinion, the state pattern makes only sense, if in each state, the behavior of an object significantly differs (with the need for different internal variables in each state) and if you don't want to carry over variable values during state transitions.

If your TS is only about taking the transition from A to B when reading event alpha and emitting signal beta in the process, then the classic table or switch based approach is much more sensible.

EDIT:

I just want to clarify that my answer wasn't meant as a statement against c++ or OOP, which I would definitly use here (mostly out of personal preference). I only wanted to point out that the State Pattern might be an overkill and just because one is using c++ doesn't mean he/she has to use class hierarchies, polymorphism and special design patterns everywhere.

MikeMB
  • 20,029
  • 9
  • 57
  • 102
1

Consider the QP active object framework, a framework for implementing hierarchical state machines in embedded systems. It's described in the book, Practical UML Statecharts in C/C++: Event Driven Programming for Embedded Systems by Miro Samek. Also, Chapter 3 of the book describes more traditional ways of implementing state machines in C and C++.

kkrambo
  • 6,643
  • 1
  • 17
  • 30
0

Nothing wrong with a class. You could define a 'State' enum and pass, or queue, in events, using a case switch on State to access the corect action code/function. I prefer that for simpler hardware-control state engines than the classic 'State-Machine 101' table-driven approach. Table-driven engines are awesomely flexible, but can get a bit convoluted for complex functionality and somewhat more difficult to debug.

Should it be more like a C style design ?

Gawd, NO!

Martin James
  • 24,453
  • 3
  • 36
  • 60