Do you use FSMs or HSMs?

I often encounter many problems when I have to implement a "behaviour" in a microcontrollor. For example, I have some analog/digital inputs and some user commands. Based on that, the logic should set some outputs (digital or analog).

Most of the time you (the developer) must understand what is the good behaviour of the machine, because noone is able to describe it in a good way. I usually heard the sentence: when the user presses the ON button, you switch on the engine. After some short implementation, you understand that the engine should be on only if the interlock input is closed. And so on...

I think the best method to describe a machine behaviour is a state-machine, mainly a hierarchically state-machine (HSM). Do you agree?

My post here is to understand if you really use HSMs to describe the beahviour of the system you are coding and how do you implement them in C or C++ (or whatever).

Reply to
pozz
Loading thread data ...

I often use FSMs but not formal HSMs. Make sure you read Miro Samek's "Practical Statecharts in C/C++" Never found a framework that fit nicely with my projects though I read about lots of them, so seems like I keep redoing this. Probably I should look at Miro Samek's latest open source offerings...

Let us know what you end up using this round, Best Regards, Dave

Reply to
Dave Nadler

Let me start with the full disclosure: I'm the author of the book "Practical UML Statecharts in C/C++, 2nd Edition" and I run a company called Quantum Leaps that makes open-source state machine software frameworks and a free state machine modeling tool. The company website is:

formatting link

So, yes, I also strongly believe that hierarchical state machines (a.k.a. UML statecharts) combined with event-driven programming are the best way to go when it comes to developing real-time embedded software.

From my two decades of experience, however, I see that the biggest obstacle in adopting state machines is the required paradigm shift from sequential programming based on blocking (like blocking on a semaphore or a time delay in a traditional RTOS or a "superloop") and the event-driven programming based on run-to-completion event processing without blocking (like in a state machine).

Anyway, if you are seriously interested in (hierarchical) state machines for embedded real-time systems I would recommend to start with the key concepts:

formatting link

You might also wish to try the free state machine modeling tool called QM, which allows you to draw hierarchical state machine diagrams and automatically generate production-quality C or C++ code from them:

formatting link

Miro Samek

formatting link

--------------------------------------- Posted through

formatting link

Reply to
QL

FSM models are my #1 considered method for documenting required behavior. But it's not always the best way. Some requirements sets just don't lend themselves well to FSM diagrams. I find that sometimes I'll sketch a FSM and then find out it's just too simple or too linear. ON the flip side, I've had project for which I'd have an extremely simple FSM documented and later it's starts to get elaborate and useful as new requirements emerge.

JJS

Reply to
John Speth

Precisely.

A good engineer knows which tools to use/avoid for each job.

Precisely.

A large part of engineering is being able to demonstrate which part of an design implements each part of the specification.

A good implementation of an FSM enables you to easily see exactly what will happen when any event occurs in any state. That can be very difficult with if-then-else clauses.

Reply to
Tom Gardner

]> Anyway, if you are seriously interested in (hierarchical) state machines ]> for embedded real-time systems I would recommend to start with the key ]> concepts:

Not entirely enlightened on hierarchical state machines. Gather that the lower level state "inherits" from the higher level state. E.g., unless over-ridden, the lower level state defaults to the actions of the higher level state?

Side issue: in communications many states use a timer to have a time-out action, and the methodology/diagrams accommodate this?

Reply to
jim.brakefield

In my implementations, you can "call" (bad choice of terms but it is something to which a programmer can easily relate!) a "state table" as if it had been inserted into the current state table, "in line" (though it doesn't incur the expected space penalty).

[likewise, common data entry FSMs "shared" in a larger UI FSM]

So, you take these common things and wrap them in a "pseudo state (table)" and then reference (CALL) it from every state in which it should apply (which might not be ALL states!)

E.g., I will embed power fail handling in such a pseudo table and add it to every state that CAN support power fail handling (some might not be designed to tolerate that exception). Likewise, power *recovery* in the same pseudo table (each maintaining a separate FSM orthogonal to the FSM in question and interacting with it in the applicable "transition routines")

Reply to
Don Y

I looked up HSM in Wikipedia and see it's UML-speak for nested state machines. I don't see exactly how it applies to the calculator example but I've preferred to use multiple communicating processes with the appearance blocking operations, rather than explicit state machines. Of course you can simulate that with an event dispatcher and coroutines, or alternatively do it with an RTOS and tasks. I suppose there is overhead compared to a FSM or HSM approach, but on the big processors I use, it hasn't been an issue.

Reply to
Paul Rubin

It all depends. This being said, I do like state machines, mainly because they lend well to comprehensive unit/regression test suites and have some advantage in coverage measurement.

Hierarchical may or may not help that much.

I have implemented them in multiple languages and programing paradigms.

--
Les Cargill
Reply to
Les Cargill

A state of the higher level state can be another state machine.

Probably, but events may resolve to the higher level state machine. I am biased by the way ObjecTime/Rational did this.

To my knowledge they all do.

--
Les Cargill
Reply to
Les Cargill

It's always dangerous to generalize, but anything I can easily make non-blocking I will.

Some FSM oriented systems use an "actor" model where actors can be threads or even pseudothreads[1], communicating with sequential message passing.

[1] looks like a thread, but may not map to an O/S thread.
--
Les Cargill
Reply to
Les Cargill

Ok, you prefer to handle the event dispatch manually, with callbacks or a switch around the protocol state. I know some people find that intuitive but I've never gotten the hang of it.

Yes, that's what I'm used to doing under the covers. Each thread waits for some action while appearing to block, and moves forward when the action occurs. Erlang is designed for programming in this style and some very complex, highly reliable systems (phone switches) have been programmed in it.

Reply to
Paul Rubin

Il 06/02/2017 15:56, QL ha scritto:

Yes, I know your book and your QP/C implementation, mainly your QEP processor (the implementation of state machines).

I think it's the only well-designed HSM implementation in C.

Yes, I agree with you. I always try to reduce all my project to a fully event-driven machine, but it's very difficult.

Many parts of the project can be represented and implemented in a simple and efficient way with an HSM. However for me it's difficult to implement other parts with an HSM with an event-driven only paradigm.

Example. If the engine must be off when an interlock is open, I put the following code in the superloop: if (interlock_is_open()) engine_off(); In this way I am *sure* this happens. With an event-driven approach, I have to create two different signals: INTERLOCK_OPEN, INTERLOCK_CLOSED. I have to be sure the INTERLOCK_OPEN signal is processed and lead to the switching off of the engine.

I usually tend to avoid blocking tasks. When I face it, I try to split it in sub-tasks... a state-machine. However it's difficult for communication protocols (I2C, RS485, ...) and/or third-parties libraries (GUI).

Reply to
pozz

There are a small legion of approaches. It depends on the problem domain.

But yeah - you dispatch event messages to a machine of some sort.

Most/many of the protocols for circuit switched phone systems have explicit FSM drawn in the standards.

It's possible to have "pseudothreads", where the event sink dispatches based on event type to whoever is waiting on that event. This does not require a separate, O/S thread each. You maintain the advantages of run-to-completion and in cases, can be done on something which is too small for an O/S.

--
Les Cargill
Reply to
Les Cargill

Yes, this is what the Erlang runtime does under the hood. From the user program's perspective it looks like OS processes, but they are very lightweight--you can have many 1000s of them on a small computer, or millions on a big one.

Reply to
Paul Rubin

ObjecTime did the same, as did Rational Rose.

--
Les Cargill
Reply to
Les Cargill

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.