hsmcpp Documentation
Note
This project is under active development.
Releases
hsmcpp — Hierarchical State Machines for Embedded & Event-Driven C++
A C++ library for building scalable, maintainable hierarchical state machines for embedded and event-driven systems.
Embedded-ready (Linux, QNX, FreeRTOS, Arduino)
SCXML-based code generation + visual tooling
Thread-safe, async/sync execution
MISRA C++ checks enforced in CI
Eliminate fragile switch-case FSMs and replace them with scalable, testable state machines that work across embedded and multi-threaded systems.
Why hsmcpp for embedded systems?
Manage complex state logic without spaghetti code
Model behavior visually with SCXML and keep it in sync with implementation
Debug transitions and state flow with built-in tooling
Designed for high-performance and real-time workflows
Integrate easily with your runtime (RTOS, Qt, STD, etc.)
Is this library a good fit for your project?
Good fit for:
C++ engineers building event-driven and embedded systems
Teams needing maintainable state logic at scale and architecture-as-code
May be overkill for:
trivial FSMs
ultra-constrained environments with no dynamic memory
Quick Start
hsmcpp supports two workflows:
Model-driven (recommended): SCXML + code generation + visual tooling
Code-first: define state machines directly in C++
Visual Workflow (SCXML-based)
flowchart LR
subgraph Modeling
REQ[Requirements]
SCXML[SCXML Definition]
IDE[Visual Editor]
end
subgraph Generation
GEN[Code Generator]
UML[PlantUML Diagram]
end
subgraph Runtime
HSM[C++ HSM]
DISP[Dispatcher]
APP[Application]
end
subgraph Analysis
DBG[hsmdebugger]
end
subgraph Artifacts
DESIGN[Design Documentation]
EXE[Binaries]
end
REQ --> IDE
IDE --> SCXML
SCXML --> GEN
SCXML --> UML
UML --> DESIGN
GEN --> HSM
HSM --> DISP
DISP --> APP
APP --> EXE
EXE --> DBG
DBG -. inspect / refine .-> SCXML
Minimal code-only example
#include <chrono>
#include <thread>
#include <memory>
#include <hsmcpp/hsm.hpp>
#include <hsmcpp/HsmEventDispatcherSTD.hpp>
enum class States { OFF, ON };
enum class Events { SWITCH };
int main(const int argc, const char**argv)
{
std::shared_ptr<hsmcpp::HsmEventDispatcherSTD> dispatcher = hsmcpp::HsmEventDispatcherSTD::create();
hsmcpp::HierarchicalStateMachine<States, Events> hsm(States::OFF);
// Register states
hsm.registerState(States::OFF, [&hsm](const VariantList_t& args) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
hsm.transition(Events::SWITCH);
});
hsm.registerState(States::ON, [&hsm](const VariantList_t& args) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
hsm.transition(Events::SWITCH);
});
// Register transitions
hsm.registerTransition(States::OFF, States::ON, Events::SWITCH);
hsm.registerTransition(States::ON, States::OFF, Events::SWITCH);
// Initialize HSM
hsm.initialize(dispatcher);
// Start dispatcher and block
dispatcher->join();
return 0;
}
For complete code see examples/00_helloworld/00_helloworld_std.cpp.
Minimal SCXML-based example
blink.scxml:
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="OFF">
<state id="OFF">
<invoke srcexpr="onOff"/>
<transition event="SWITCH" target="ON"/>
</state>
<state id="ON">
<invoke srcexpr="onOn"/>
<transition event="SWITCH" target="OFF"/>
</state>
</scxml>
Minimal C++ code to use the generated BlinkHsmBase:
#include "gen/BlinkHsmBase.hpp"
class BlinkHsm : public BlinkHsmBase {
protected:
void onOff(const hsmcpp::VariantVector_t&) override {
transition(BlinkHsmEvents::SWITCH);
}
void onOn(const hsmcpp::VariantVector_t&) override {
transition(BlinkHsmEvents::SWITCH);
}
};
int main(const int argc, const char** argv) {
std::shared_ptr<HsmEventDispatcherSTD> dispatcher = HsmEventDispatcherSTD::create();
BlinkHsm hsm;
if (true == hsm.initialize(dispatcher)) {
dispatcher->join();
Content