Visual State Machine Design for Embedded Systems using Flint IDE

Chellapandi N | 12. November 2026
Categories:RAPIDSEA, Flint IDE, state machine, HSM, embedded design

State machines are the natural model for a large proportion of embedded firmware logic. Device initialisation sequences that must execute steps in order with error handling at each step. Communication session management that tracks connection state, authentication state, and transaction state simultaneously. Operational mode management that transitions between normal operation, diagnostic mode, bootloader mode, and fault state with defined trigger conditions and recovery paths. These are all fundamentally state machine problems - and the most common way they are implemented in embedded C is as switch-case constructs inside main loops, growing in complexity with each new requirement until the code structure reflects the original design intent only faintly.


Flat vs Hierarchical State Machines

A flat state machine enumerates every possible state explicitly and defines every possible transition between them. As the number of states grows, the number of possible transitions grows combinatorially - a system with 20 states has up to 400 possible transitions to specify, most of which are duplicates of the same handling applied in many states. The result is code that is correct but unreadable, where a change to shared error handling requires modifying the same transition in dozens of places.

Hierarchical State Machines (HSMs) - also called statecharts, defined by David Harel and reflected in UML - solve this by allowing states to be nested. A substate inherits the transition behaviour of its parent state. An error event that causes a transition to the fault state in any operational substate is defined once on the parent operational state rather than on each individual substate. This dramatically reduces the number of explicitly defined transitions and makes the state machine's structure correspond clearly to the designer's intent.


Designing HSMs in Flint IDE

Flint IDE's HSM designer provides a graphical canvas where states, substates, transitions, guards, and actions are drawn visually. States are created as rectangular regions that can contain nested substates. Transitions are drawn as arrows between states, labelled with the triggering event, an optional guard condition that must evaluate true for the transition to fire, and an optional action that executes when the transition fires. Entry and exit actions for each state - code that executes whenever the state is entered or exited regardless of which transition caused the change - are attached to the state node itself.

Event sources are connected to the HSM from external inputs - CAN frame callbacks, timer events, MQTT message arrivals, GPIO change events, protocol stack callbacks. The connection is graphical: an event source node is drawn on the canvas and connected to the transition that it triggers. This makes the relationship between external hardware and communication events and the state machine's response immediately visible to anyone reading the design.


Code Generation from HSM Designs

Flint IDE generates MISRA-C compliant ANSI C code implementing the designed HSM directly. The generated code follows the Miro Samek HSM implementation pattern - a well-established, testable implementation of UML statechart semantics in C that is widely used in embedded safety-critical applications. Generated code includes the state enumeration type, the state handler function for each state, the event enumeration type, the HSM dispatch function that processes events and executes the current state handler, and the initialisation function that places the HSM in its initial state.

The generated code is portable - it contains no hardware dependencies and can be compiled and tested on a host PC before being deployed to the target MCU. This enables host-based unit testing of the state machine logic using standard C test frameworks, exercising all transitions and guard conditions systematically without requiring hardware.


State Machine Testing and Verification

A correctly designed HSM has a well-defined, testable structure. Every state must have an explicit response to every event - either a transition, a local reaction, or an explicitly handled ignore. Flint IDE validates this completeness at design time, flagging states where event handling is unspecified. This validation catches the most common state machine implementation error - an event arriving in an unexpected state and being silently ignored rather than handled gracefully.

Generated HSM code can be tested using the same unit testing infrastructure as any other embedded C module. A test harness creates an HSM instance, feeds it event sequences, and asserts that the resulting state sequence and action executions match the expected behaviour from the design. Because the generated code contains no hardware dependencies, these tests run on the host CI server without requiring embedded hardware.


Implementing Event-Driven Firmware with RAPIDSEA and Flint IDE

Event-Driven Firmware with RAPIDSEA and Flint IDE

RAPIDSEA protocol stack callbacks - UDS session state changes, CAN frame arrivals, MQTT message receipts, bootloader event notifications - serve directly as HSM event sources in Flint IDE designs. A UDS diagnostic session state change triggers a transition in the device's operational state machine that activates or deactivates specific diagnostic capabilities. A CAN frame arrival triggers a transition in a communication manager HSM that processes the received signal and updates the device's output state. The tight integration between RAPIDSEA callback interfaces and Flint IDE HSM event sources enables complete embedded application logic to be designed, generated, and validated graphically.


Conclusion

Visual HSM design in Flint IDE brings structure, maintainability, and testability to embedded application logic that grows increasingly complex in hand-coded C. The hierarchical structure eliminates redundancy in transition definitions, graphical design makes structure visible to the entire team, generated MISRA-C code is immediately testable on host systems, and Flint's completeness validation catches unhandled event scenarios before they become field defects. For RAPIDSEA-based embedded projects, Flint IDE HSM design closes the gap between protocol stack integration and application logic implementation.

Ready to explore visual state machine design for your next embedded project? Contact our team to request a Flint IDE demonstration.

Subscribe to our Blog


For further information on how your personal data is processed, please refer to the RAPIDSEA Privacy Policy.