Multi-Target Architecture & Backend Roadmap¶
fsmc is designed from first principles as a format-agnostic compiler and code generator, not a C++-only library.
Its architecture strictly decouples model ingestion and formal verification from target code emission using a canonical Intermediate Representation (FsmIr). While C++ serves as the initial reference production backend, the metamodel natively maps to diverse programming languages and safety-critical execution runtimes.
[!IMPORTANT] Active Production Target vs. Roadmap Previews: The C++ Reference Backend (
C++17/C++20) is the active production-ready code generation target. The Rust (no_std) and C (Embedded C) backends described in this roadmap represent preview specifications and RFC designs.
1. Universal Target Support Matrix¶
| Target Language | Minimum Standard | Concurrency Models | Safety & Standards Compliance | Ecosystem Status |
|---|---|---|---|---|
| C++ Target | C++17 / C++20 | Synchronous stack, Lock-Free SPSC, Active Object | Zero heap, zero vtable, \(O(1)\) WCET | Production Target |
| Rust Target | Rust 2021 (no_std) |
Typestate transitions, lock-free static channels | Compile-time memory safety, zero panic | Preview / In Development |
| C Target | ISO C99 / C11 | Static transition table, switch-case dispatch | Embedded C, zero malloc | Preview / Planned RFC |
2. The Universal 4-Domain Datapath Across Languages¶
The fsmc 4-domain memory segregation model is language-agnostic. It guarantees mathematical determinism, absence of data races, and clear ownership semantics across all target architectures:
graph TD
subgraph Inputs["1. InPorts (Read-Only Per-Cycle Snapshot)"]
InCpp["C++: const InPorts&"]
InRs["Rust: &InPorts"]
InC["C: const in_ports_t*"]
end
subgraph Outputs["2. OutPorts (Write-Only Latched Actuators)"]
OutCpp["C++: OutPorts&"]
OutRs["Rust: &mut OutPorts"]
OutC["C: out_ports_t*"]
end
subgraph Registers["3. Registers (Encapsulated Internal State)"]
RegCpp["C++: Registers& (sm.with_registers)"]
RegRs["Rust: &mut Registers (Cell / Mutex)"]
RegC["C: registers_t* (encapsulated struct)"]
end
subgraph Services["4. Services (Injected Environment Drivers)"]
SrvCpp["C++: Services&"]
SrvRs["Rust: &dyn ServiceTrait / Generic"]
SrvC["C: const service_vtable_t*"]
end
Architectural Mapping Table¶
| Domain | Semantic Intent | C++ Reference Implementation | Planned Rust Implementation | Planned C99 Implementation |
|---|---|---|---|---|
InPorts |
External sampled sensor values | const InPorts& |
&InPorts |
const in_ports_t* const in |
OutPorts |
Commanded actuator outputs | OutPorts& |
&mut OutPorts |
out_ports_t* const out |
Registers |
\(z^{-1}\) internal memory | Encapsulated value | Struct with ownership / borrow | registers_t memory block |
Services |
Non-deterministic hardware drivers | Reference / Dependency Injection | Trait object / Generic bound | Function pointer structure |
3. Rust Backend (no_std) — Design Specification¶
The Rust target emitter produces idiomatic, high-performance, and provably memory-safe state machine implementations targeting embedded firmware and systems programming.
Core Tenets¶
#![no_std]First: 100% compatible with bare-metal microcontrollers (ARM Cortex-M, RISC-V, ESP32) without dynamic memory allocation (allocnot required).- Compile-Time Typestate Validation: Invalid state transitions are caught at compile-time using the Rust type system.
- Thread Safety Guarantees: State machines implement
SendandSyncconditionally based on the thread safety of internal registers. - Lock-Free Concurrency: Asynchronous queues map to static ring buffers (e.g.
heapless::spsc::Queue).
Syntax Preview¶
// Generated Rust State Machine (Preview)
use fsmc_runtime::prelude::*;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum State { Off, On }
pub struct LampFsm {
state: State,
registers: LampRegisters,
}
impl LampFsm {
pub const fn new(registers: LampRegisters) -> Self {
Self { state: State::Off, registers }
}
pub fn dispatch(&mut self, event: &Event, in_ports: &InPorts, out_ports: &mut OutPorts) -> DispatchResult {
match (self.state, event) {
(State::Off, Event::Toggle) => {
self.state = State::On;
out_ports.lamp_active = true;
DispatchResult::Transitioned
}
(State::On, Event::Toggle) => {
self.state = State::Off;
out_ports.lamp_active = false;
DispatchResult::Transitioned
}
_ => DispatchResult::Ignored,
}
}
}
4. ISO C99 / C11 Backend — Embedded C & High-Integrity Systems¶
The C target generator is engineered specifically for mission-critical and resource-constrained embedded systems (automotive, aerospace, medical).
Core Tenets¶
- Deterministic Embedded C: Zero dynamic allocations (
malloc/free), zero recursive calls, bounded loops, and strict type conversions. - Compact Binary Footprint: Encoded as flat switch-case or compact read-only ROM lookup tables.
- Deterministic WCET: Bounded worst-case execution time with zero dynamic dispatch overhead.
- Clean Integration: Simple C headers compatible with legacy codebases and automotive AUTOSAR Classic runtimes.
Syntax Preview¶
/* Generated C99 State Machine Header (Preview) */
#ifndef LAMP_FSM_H
#define LAMP_FSM_H
#include <stdbool.h>
#include <stdint.h>
typedef enum {
LAMP_STATE_OFF = 0,
LAMP_STATE_ON = 1
} lamp_state_t;
typedef struct {
lamp_state_t current_state;
lamp_registers_t registers;
} lamp_fsm_t;
void lamp_fsm_init(lamp_fsm_t* const self, const lamp_registers_t* const initial_regs);
bool lamp_fsm_dispatch(lamp_fsm_t* const self, lamp_event_t event, const lamp_in_ports_t* const in, lamp_out_ports_t* const out);
#endif /* LAMP_FSM_H */
5. Summary & Contribution¶
The canonical IR compiler pipeline guarantees that a model specified in OMG SysML v2, Cameo / MagicDraw XMI, or W3C SCXML can be formally verified once with nuXmv and then emitted with identical behavioral semantics in C++, Rust, or C.
For discussions on backend RFCs or to contribute target emitters, refer to the Compiler Architecture Specification.