hsmcpp Documentation
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 editor
Thread-safe, async/sync execution
Built for reliability — requirements, traceability & tests to support safety-critical use
Eliminate fragile switch-case FSMs and replace them with scalable, testable state machines that work across embedded and multi-threaded systems.
Design visually, generate production C++. Draw your hierarchical state machine in hsm-ide — the dedicated open-source editor — and generate production-grade C++. It’s text-based and git-friendly: the SCXML lives in your repo, not in a binary model file.
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[hsm-ide]
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 <cstdio>
#include <memory>
#include <thread>
#include <hsmcpp/HsmEventDispatcherSTD.hpp>
#include <hsmcpp/hsm.hpp>
enum States { OFF, ON };
enum Events { SWITCH };
int main(const int argc, const char** argv) {
std::shared_ptr<hsmcpp::HsmEventDispatcherSTD> dispatcher = hsmcpp::HsmEventDispatcherSTD::create();
hsmcpp::HierarchicalStateMachine hsm(States::OFF);
// Register states
hsm.registerState(States::OFF, [&hsm](const hsmcpp::VariantVector_t& args) {
std::printf("Off\n");
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
hsm.transition(Events::SWITCH);
});
hsm.registerState(States::ON, [&hsm](const hsmcpp::VariantVector_t& args) {
std::printf("On\n");
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 and block until dispatcher stops
if (true == hsm.initialize(dispatcher)) {
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 <hsmcpp/HsmEventDispatcherSTD.hpp>
#include "gen/BlinkHsmBase.hpp"
using namespace hsmcpp;
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();
}
return 0;
}
For complete workflows and editor integration, see Code generation docs and /examples/02_generated.
Get Started in 60 Seconds
git clone https://github.com/igor-krechetov/hsmcpp.git
cd ./hsmcpp
mkdir ./build
cd ./build
cmake ..
make -j4
Content