Papers
Topics
Authors
Recent
Search
2000 character limit reached

Embedded Rust or C Firmware? Lessons from an Industrial Microcontroller Use Case with Ariel OS

Published 28 Apr 2026 in cs.OS | (2604.25679v1)

Abstract: As Rust gains traction for developing safer systems software, a reality check for the microcontroller hardware segment becomes necessary. How ready is the Rust ecosystem for this segment? Can Rust compete with C in practice? This paper reports on an IoT industrial case study that contributes to answering these questions. Two teams concurrently developing the same functionality (one in C, one in Rust) are analyzed over a period of several months. A comparative analysis of their approaches, results, and iterative efforts is provided. The analysis and measurements on hardware indicate no strong reason to prefer C over Rust for microcontroller firmware on the basis of memory footprint or execution speed. Furthermore, Ariel OS is shown to provide an efficient and portable system runtime in Rust whose footprint is smaller than that of the state-of-the-art bare-metal C stack traditionally used in this context. It is concluded that Rust is a sound choice today for firmware development in this domain.

Summary

  • The paper demonstrates Rust firmware using Ariel OS achieves a 45% RAM reduction compared to C implementations.
  • It details systematic benchmarking that shows both firmware versions meet high-frequency sensor interrupt and real-time constraints.
  • The study advances firmware portability with async Rust and outlines best practices for minimizing code bloat and scheduling latency.

Comparative Evaluation of Rust and C Firmware Development for Industrial Microcontrollers with Ariel OS

Overview

This study presents a rigorous industrial case analysis comparing Rust and C firmware development for heterogeneous microcontroller platforms in the context of STMicroelectronics' STAIoTCraft toolkit. The investigation centers on parallel teams implementing identical sensor data logging functionality—one in C (VDL-C), the other in Rust (VDL-Rust), utilizing Ariel OS as a portable runtime. The work scrutinizes architectural paradigms, portability, resource consumption, real-time performance, and practical considerations relevant for firmware deployment in commercial IoT edge devices.

Architecture and Methodology

Both VDL-C and VDL-Rust implement the Vanilla Datalog Protocol (VDP) for sensor data streaming, supporting real-time acquisition from MEMS IMUs on ARM Cortex-M33 hardware. VDL-C leverages conventional STM32CubeMX tooling for board abstraction, with an event-driven FSM managed by manually controlled IRQs. Dynamic memory allocation is present via Parson for JSON handling.

VDL-Rust builds atop Ariel OS, inheriting Embassy’s async/await-based HAL and OS abstractions featuring static memory allocation (no_heap), and integrates heapless and serde-json-core for strictly bounded serialization. The Ariel OS approach enhances runtime composability and portability across heterogeneous boards, providing IPC and synchronization based on Rust’s type system, enabling modular firmware with strong safety guarantees.

Memory Footprint and Code Size

Detailed measurement reveals VDL-Rust exhibits a smaller overall RAM footprint (24,640 B vs. 44,656 B for VDL-C, a 45% reduction), attributed to statically bound heapless memory and avoidance of fragmentation risks. Contrary to expectations, Ariel OS’s portable runtime yields a system code size ~10% smaller than the bare-metal C stack, due to the elimination of runtime overhead from newlib and more efficient HAL abstractions.

The major source of Rust binary inflation is monomorphization and async state machine bloat; these were addressed iteratively by minimizing heapless types, enum usage, and reducing retained state across await points. By optimizing buffer sizes and replacing async drivers with synchronous equivalents, VDL-Rust’s flash requirements converged to within 10% of VDL-C's statically optimized baseline.

Execution Speed and Real-Time Performance

Both implementations reliably service maximum ODR sensor interrupts (7680 Hz) on Cortex-M33, with negligible latency deviations dominated by the sensor, not firmware. VDL-Rust’s async/await model introduces measurable scheduling latency (~1.7–4.0 μs per task switch), impacting cumulative execution margin. However, practical benchmarks confirm no compromise to real-time deadline adherence; after architectural refinements, both firmware stacks achieve identical throughput at the hardware ceiling.

Initial discrepancies in throughput were traced to architectural differences and peripheral configuration defaults—Rust's Embassy prioritizes wide compatibility, whereas STM32CubeMX generates optimized MCU-specific settings. Adjusting timing registers, enabling instruction cache, and disabling UART FIFO delivered parity in streaming task duration (~120 μs), underscoring the necessity for platform-specific tuning in performance-critical deployments.

Portability, Maintainability, and Workflow Impact

VDL-Rust, using Ariel OS and Embassy, demonstrated superior project portability: board-specific re-targeting required only configuration gate changes and build command updates, contrasting with labor-intensive setup and manual copying for STM32CubeMX-based C implementations. This high portability is not accompanied by significant binary or performance penalties.

Async/await, while simplifying concurrency semantics, can incur excessive stack usage and code bloat if not carefully architected. Best practices include minimizing live variables across suspension points, using StaticCell for large structures, and favoring synchronous API pathways where true concurrency is not required.

Practical and Theoretical Implications

The study validates the technical readiness of embedded Rust for industrial microcontroller firmware. Rust’s strict static memory management, strong type guarantees, and modular crate ecosystem (with Ariel OS as RTOS abstraction) match C firmware in execution speed and footprint, while offering vastly improved maintainability and code safety. The findings contradict the historical assumption that higher-level abstractions and portable runtimes cause prohibitive resource overheads for deeply embedded systems; careful design and ecosystem maturity have closed this gap.

Practically, this positions Rust (especially with Ariel OS or Embassy) as a viable, safer, and maintainable alternative for mission-critical firmware under emerging regulatory pressures (e.g., Cyber Resilience Act). Theoretically, the work suggests async Rust is suitable for constrained hard real-time systems given judicious architectural choices and hardware-aware tuning.

Future Directions

Continued maturation of embedded Rust, with further optimization of async state machines and compile-time memory management, will likely expand adoption in the microcontroller and edge AI segments. Cross-domain reuse of crates and host-side testing, combined with ecosystem improvements in peripheral configuration automation, will further streamline workflows. The study sets a precedent for empirical evaluation, advocating more systematic comparative analyses across diverse hardware and use cases, including more advanced concurrency models and security evaluations.

Conclusion

The presented comparative industrial case demonstrates Rust's efficacy and readiness for microcontroller firmware development, with Ariel OS enabling efficient, portable, and maintainable deployments matching the performance and resource overhead of traditional C approaches. The detailed lessons on architectural pitfalls and optimization strategies provide actionable guidance for transitioning to Rust—concluding that embedded Rust is a sound, safe, and practical choice for contemporary edge firmware applications (2604.25679).

Whiteboard

There was an error generating the whiteboard.

Explain it Like I'm 14

What this paper is about (big picture)

This paper asks a simple question: for tiny computers inside devices (microcontrollers), is writing the software (“firmware”) in Rust as good as writing it in C? To find out, two teams built the same sensor-logging program twice—once in C and once in Rust—and then compared how big and fast each version was on real hardware. The short answer: Rust holds up very well, and in some ways does better.

What the researchers wanted to find out

They set out to answer, in plain terms:

  • Is the Rust ecosystem ready for writing firmware on small, resource‑limited microcontrollers?
  • How do Rust and C compare in memory use (how much space they take) and speed (how quickly they run) for the same job?
  • Is Rust practical to use and portable across different boards and sensors in real projects?

How they tested it (methods, explained simply)

Think of a microcontroller as a tiny, low‑power computer inside gadgets like wearables or smart sensors. Firmware is the permanent program that tells it what to do. The team used an industrial toolkit called STAIoTCraft to build a “vanilla data logger” (VDL) that reads motion sensors and streams the data to a PC.

  • Two teams worked in parallel for 6 weeks: one wrote the firmware in C (VDL‑C), the other in Rust (VDL‑Rust). Then they spent 4 more weeks comparing and improving both.
  • Both versions followed the same data format and “conversation rules” so a PC could talk to the device and receive sensor data. You can think of this protocol as a shared language both sides agree on.
  • Hardware: They used a SensorTile.box Pro board (a tiny device with an Arm Cortex‑M33 microcontroller and a motion sensor).
  • C version basics: built with ST’s STM32Cube tools, used a classic event loop and interrupts (like a doorbell that notifies the program when new sensor data is ready). It used a JSON library that allocates memory on the fly (dynamic memory).
  • Rust version basics: built with Ariel OS (a small, lightweight Rust “library operating system”) and the Embassy framework. It used async/await (a way to write code that waits for events without blocking) and “static” memory only (fixed‑size buffers decided ahead of time). For JSON, it used serde and “heapless” tools that avoid dynamic memory.
  • Measurements: They checked
    • Code size in flash (ROM) and data in RAM (how much memory each used).
    • Speed: could each version keep up when the sensor produced data at its fastest rate?

Quick glossary with everyday analogies:

  • Interrupts: like a doorbell—when data is ready, the sensor “rings,” and the program answers.
  • Static vs dynamic memory: static is like packing exactly the containers you’ll need in your backpack before a trip; dynamic is borrowing extra boxes during the trip as needed. Dynamic is flexible but can get messy; static is predictable.
  • Async/await: writing instructions that say, “Start this task, and while we wait for the next ‘doorbell,’ do other useful things.” It can make code simpler, but the “traffic controller” that switches tasks adds a tiny delay.

What they found and why it matters

Here are the key results and their meaning:

  • Memory footprint: close overall, with some surprises
    • Code size (flash/ROM): the Rust version was only about 10% larger than the C version. That’s small enough to be a non‑issue on the tested hardware.
    • RAM: the Rust version actually used much less total RAM in practice because it avoided dynamic memory (no heap). The C version’s JSON library used the heap and peaked higher in RAM use. Predictable memory is a big deal on tiny devices because it reduces the risk of memory bugs.
    • System runtime size: the Rust stack (using Ariel OS) was smaller than the C runtime stack that included the C standard library. That’s surprising, because you might expect an “OS” to cost more space—but here it didn’t.
  • Speed: both were fast enough—even at the sensor’s max rate
    • Both versions handled the sensor’s top data rate (around 7.7 thousand samples per second).
    • The Rust async/await approach added a small scheduling delay (microseconds), but not enough to miss deadlines. Both kept up fine.
  • Portability and developer experience:
    • Rust + Ariel OS made it straightforward to move the code to a different board, thanks to reusable crates (packages) and build features.
    • The C approach, using vendor tools, worked well but required per‑board projects and more manual setup.
    • The Rust team was less experienced and still finished in the same timeframe, suggesting the tooling and ecosystem are mature enough for real work.
  • Lessons learned (what to watch for):
    • Rust async/await can make binaries bigger and add small delays if not used carefully. The team trimmed size by restructuring code, passing large buffers by reference, and making some parts synchronous.
    • Tuning hardware settings (caches, I2C timing, UART options) matters just as much in Rust as in C. With proper tuning, both reached the same “speed ceiling.”

Why this matters:

  • Safety and reliability: Rust tends to prevent entire categories of memory bugs that are common in C. On devices that need to be dependable (and secure), that’s a big advantage.
  • Predictability: No heap in Rust means more predictable RAM use—important for avoiding crashes and security issues on small devices.
  • Practicality: If Rust can match C on size and speed while improving safety and portability, it’s a strong option for industry.

What this could change going forward

  • For companies building firmware on microcontrollers, Rust is already a sensible choice. It can deliver similar performance and memory use to C while offering better safety guarantees and easier portability across boards.
  • Teams adopting Rust should:
    • Plan how they use async/await to avoid unnecessary bloat and latency.
    • Check and fine‑tune hardware settings (just like they would in C).
    • Leverage the Rust ecosystem (crates like serde, heapless, Embassy, Ariel OS) to reduce custom code and improve testing.
  • Big picture: As devices get more connected and regulations tighten (e.g., on cybersecurity and resilience), safer languages like Rust can help reduce bugs and maintenance costs without sacrificing performance.

In short, this study shows that, today, Rust is not just “promising”—it’s ready for real microcontroller firmware work.

Knowledge Gaps

Below is a consolidated list of concrete knowledge gaps, limitations, and open questions left unresolved by the paper, intended to guide future research and replication efforts.

  • Generalizability across MCUs: Results are measured only on an STM32U585 (Cortex-M33); it remains unknown how conclusions hold on lower-end MCUs (e.g., Cortex-M0/M0+ with 32–64 KB Flash and 8–16 KB RAM), higher-end Cortex-M7/M55/M85, or non-Arm (e.g., RISC-V) platforms.
  • Breadth of hardware targets: Apart from a brief portability note to an STM32F401RE, no performance/footprint measurements are provided on other boards or vendors (NXP, Nordic, TI, Microchip), leaving portability/performance trade-offs unquantified outside STM32.
  • Sensor and peripheral diversity: Experiments focus on a single IMU (LSM6DSV16X) and UART; performance with other sensors, buses (SPI/I2C variants), and higher-throughput links (USB CDC, SDIO) is not evaluated.
  • Networking and radio stacks: The study omits BLE/Wi‑Fi/Sub‑GHz/LoRaWAN stacks, leaving open the code-size, RAM, timing, and energy impact of adding real networking to Rust vs C firmware.
  • DMA utilization: No comparison of blocking, interrupt-driven, and DMA-driven I/O is provided (UART, I2C, SPI); it is unclear how DMA influences latency, jitter, CPU utilization, and energy in Rust vs C.
  • Real-time jitter and worst-case latency: Only average-cycle timing is shown; worst-case ISR latency, jitter distributions, and deadline miss rates under interrupt contention or background workload are unreported.
  • Concurrency scalability: The design handles a simple pipeline; behavior under multiple concurrent sensors/channels, higher ISR rates, nested interrupts, and priority inversion scenarios is not quantified.
  • Async/await bounds: While async overhead is noted, there is no systematic methodology to bound worst-case async task-switch latency across MCUs and clock frequencies, nor guidance on when to prefer sync over async.
  • Alternative Rust concurrency models: The paper does not evaluate RTIC or a purely synchronous Rust design; the trade-offs vs Embassy/Ariel OS for code size, timing, and complexity remain open.
  • Ariel OS vs bare-metal C/RTOS: The overhead and features of Ariel OS are compared only on one metric set; no comparison is made against widely used RTOSes (FreeRTOS, Zephyr) or event frameworks in C for fairness.
  • Energy and power: No power/energy measurements are reported; the impact of async overhead, cache/prefetch settings, and UART FIFO tuning on energy per sample is unknown.
  • Cache/prefetch portability: Optimizations (I‑Cache, flash prefetch, UART FIFO tweaks) used to close gaps may not be available on lower-end MCUs; the portability of these gains is untested.
  • Memory safety and reliability: Claims of Rust safety are not supported by empirical evidence (e.g., defect rates, fault-injection, long-run stress tests); runtime robustness under sensor/I2C/UART faults and recovery behavior are not evaluated.
  • C heap fragmentation risk: The risk of heap fragmentation and denial-of-service due to malformed JSON is highlighted but not experimentally studied (e.g., with adversarial inputs and multi-hour runs).
  • Fairness of JSON choice: VDL‑C uses Parson (heap-allocating); alternatives like jsmn/frozen parsers or CBOR/FlatBuffers could change RAM and timing; a fair C baseline without heap allocations is not evaluated.
  • Protocol alternatives: The choice of JSON/VDP is taken as given; binary formats (CBOR, protobuf-nano) and their effect on code size, RAM, latency, and robustness in Rust vs C are not compared.
  • Static memory limits: The maximum supported JSON complexity and payload size with serde‑json‑core and heapless (e.g., deep nesting, large strings) are not characterized; failure modes and back-pressure behavior are unknown.
  • CPU utilization and slack: The study reaches sensor ODR ceilings but does not report CPU load, available slack, or headroom for additional tasks (e.g., feature extraction, crypto).
  • Multi-hour stability: No extended endurance tests (e.g., 24–72 hour runs) are reported to assess drift in timing, memory, and error rates in both implementations.
  • Error handling and recovery: Behavior under bus errors, dropped frames, UART noise, and sensor misconfiguration (and the comparative robustness of Rust vs C handlers) is not tested.
  • Build and tooling maturity: Developer productivity, build times, debug/trace experience, and IDE/toolchain stability for embedded Rust vs STM32Cube workflows are not measured.
  • Supply-chain and compliance: The security posture of crates (audits, SBOMs, CVE tracking), licensing, and compliance (e.g., CRA) for a production firmware workflow are not addressed.
  • Reproducibility details: Precise toolchain versions, compiler flags, Ariel/Embassy crate versions, and full build recipes needed for exact replication are not provided; code is promised but not yet available.
  • Porting effort metrics: Anecdotal portability claims are made; quantitative data on porting time, defect density introduced during ports, and maintenance burden across many targets are missing.
  • Cryptography and secure transport: The code-size, RAM, and timing impact of adding TLS/DTLS or authenticated transport (and availability of no_std crypto crates) are not evaluated.
  • Bootloaders and OTA: Integration with bootloaders, update size/delta strategies, and Rust vs C implications for secure OTA updates are unaddressed.
  • Extreme constraints: It is unknown whether Rust + Ariel OS can fit ultra-constrained MCUs (e.g., 32 KB Flash, 8 KB RAM) without sacrificing functionality; minimum viable configurations are not mapped.
  • Peripheral abstraction overhead: The runtime and size cost of embedded‑hal/trait-based abstractions vs direct register access in C is not quantified.
  • Monomorphization control: While binary bloat sources are discussed, there is no generalizable recipe or automated tooling to constrain monomorphization and async state growth across projects.
  • Determinism under optimization: The interaction of LTO, panic strategies (abort vs unwind), and link-time options with real-time determinism and code size is not systematically explored.
  • Multi-core applicability: Ariel OS claims multi-core support, but no measurements or case studies assess Rust vs C behavior on dual-core MCUs (e.g., M7+M4) or multi-core scheduling overhead.
  • Broader functional scope: The study focuses on datalogging; it does not test edge AI workloads (feature extraction, MLC interaction at scale) or pipeline contention when inference runs in-sensor vs on MCU.

Practical Applications

Immediate Applications

The paper’s results show that embedded Rust (with Ariel OS/Embassy and the Rust crate ecosystem) achieves practical parity with C for microcontroller firmware on ARM Cortex‑M MCUs, enabling several deployable use cases today. The following list highlights concrete, real‑world applications, sectors, and workflows, including dependencies that may affect feasibility.

  • Firmware modernization pilots for IoT devices
    • Sectors: industrial IoT, consumer IoT, wearables, smart home, robotics
    • What to do: Port existing C data loggers and sensor agents to Rust using Ariel OS + Embassy, serde-json-core, and heapless to eliminate dynamic allocation and reduce RAM footprint while retaining performance.
    • Tools/workflows:
    • Reuse VDP-style protocols or Azure IoT Plug and Play (PnP) models with Rust serde for strongly typed JSON.
    • Factor device-protocol logic into reusable crates for embedded and host-side testing.
    • Use logic analyzer traces to profile ISR-to-stream latencies and verify ODR deadlines.
    • Assumptions/dependencies:
    • Target MCUs supported by Embassy/Ariel OS and available Rust drivers (e.g., ST MEMS crates).
    • Teams with basic Rust/no_std skills; availability of the forthcoming open-source repo.
    • Results are established on Cortex‑M33 and STM32F4; validate on other MCUs.
  • Safer, heapless command/telemetry paths for fielded devices
    • Sectors: healthcare (wearables), industrial monitoring, energy (smart meters), building automation
    • What to do: Replace C JSON parsers that use heap allocation (e.g., Parson+newlib) with Rust serde-json-core + heapless to deserialize into static, typed structs, removing fragmentation risk and bounding memory at compile time.
    • Tools/workflows: Static memory budgeting; compile-time sizing of buffers; CI tests for JSON robustness.
    • Assumptions/dependencies:
    • JSON schema stability; DTDL models known at build time.
    • Constrained devices still able to host statically sized buffers sized for worst‑case messages.
  • Portable multi-board firmware baselines
    • Sectors: device OEMs, ODMs, module vendors
    • What to do: Create a single Rust codebase with board/MCU differences managed via #[cfg] features and Ariel OS board definitions, rather than maintaining many CubeMX projects.
    • Tools/workflows: Ariel OS portable build system; feature-gated HAL initialization; driver crates from crates.io.
    • Assumptions/dependencies:
    • Ariel OS support for chosen boards; escape hatches for custom init where needed.
  • Host-side testing and cross-domain reuse of protocol logic
    • Sectors: software tooling, QA, cloud/edge integration
    • What to do: Factor PnP/VDP protocol into a shared Rust crate used by firmware and by host-side (desktop/WebAssembly) tools for simulation, fuzzing, and regression testing.
    • Tools/workflows: Shared crates, unit tests, WASM demos; Azure IoT PnP integration tests.
    • Assumptions/dependencies:
    • Protocol boundaries cleanly separable from hardware-specific code.
  • Performance-tuning playbooks for real-time sensor stacks
    • Sectors: robotics, drones, industrial controls, AR/VR sensing
    • What to do: Apply the paper’s measured tuning sequence to hit high ODRs: use interrupt-driven streaming; tighten I2C TIMINGR; enable I-Cache/prefetch; evaluate UART FIFO; remove unneeded logging; minimize async await points or adopt sync code where concurrency isn’t needed.
    • Tools/workflows: Logic analyzer benchmarks; per-target overhead budgets for async; side-by-side C vs. Rust traces.
    • Assumptions/dependencies:
    • Access to hardware measurement tools; knowledge of MCU cache/clock settings.
  • Procurement and cybersecurity policy updates favoring memory-safe firmware where feasible
    • Sectors: procurement, compliance, critical infrastructure
    • What to do: Update RFPs and internal guidelines to prioritize memory-safe languages for new MCU firmware, referencing parity findings and EU CRA motivations; begin with lower-risk SKUs (data loggers, gateways) as adoption footholds.
    • Tools/workflows: Policy templates citing CRA and this evidence; staged adoption plans; exception processes for ultra-tiny MCUs.
    • Assumptions/dependencies:
    • Organizational buy-in; allowance for ramp-up/training; validated performance on target MCUs.
  • Education and training modules for embedded Rust
    • Sectors: academia, corporate training, bootcamps
    • What to do: Build lab exercises that reproduce the C vs. Rust implementations, including heapless JSON, async pitfalls, monomorphization effects, and optimization steps seen in the paper.
    • Tools/workflows: NUCLEO + sensor expansion boards (e.g., IKS4A1), SensorTile.box Pro, Ariel OS templates.
    • Assumptions/dependencies:
    • Hardware availability; instructors comfortable with no_std and async Rust patterns.
  • Maker/DIY dataloggers with robust cloud integration
    • Sectors: daily life, hobbyist communities, education
    • What to do: Use the Rust example stack (Ariel OS + ST drivers) to assemble plug-and-play sensor loggers that stream to Azure IoT PnP without dynamic allocation or unsafe code.
    • Tools/workflows: Cargo templates; preconfigured board feature flags; simple UART/I2C examples.
    • Assumptions/dependencies:
    • Community docs and examples; available Rust toolchains for host OSes.

Long-Term Applications

The study’s methods and findings suggest several larger-scale or research-driven opportunities that require additional maturity of tooling, broader hardware support, or further validation.

  • Vendor-grade Rust SDKs and code generators
    • Sectors: semiconductor vendors, tool vendors
    • Opportunity: Rust-native equivalents to CubeMX that emit optimized, board-specific init (clocks, caches, I2C timings) and HAL configuration, closing the gap between generic defaults and per‑MCU optimal settings.
    • Potential products: GUI codegen for Ariel/Embassy configs; timing calculators; board packs.
    • Dependencies/risks:
    • Sustained vendor investment; alignment with Rust embedded working groups; long-tail MCU support.
  • Certified safety and security profiles for MCU Rust runtimes
    • Sectors: medical devices, automotive, industrial safety
    • Opportunity: Define certified profiles of Ariel OS/Embassy (or variants) with proven real-time behavior, deterministic memory usage, and documented async overhead bounds for safety standards.
    • Potential products: Pre-certified runtime distributions; compliance kits aligned with CRA/IEC 61508/ISO 26262.
    • Dependencies/risks:
    • Formal analyses, sustained maintenance, and auditor acceptance; evidence across multiple MCUs.
  • Automated size/performance autotuners for async Rust on MCUs
    • Sectors: software tooling, performance engineering
    • Opportunity: Tools that analyze generated async state machines, detect enum/monomorphization bloat, and recommend rewrites or parameter changes (buffer sizes, await boundaries) to meet ROM/RAM budgets and latency targets.
    • Potential products: Cargo plugins; code-linter rulesets; CI-integrated profilers.
    • Dependencies/risks:
    • Stable compiler introspection APIs; representative benchmark suites; developer education.
  • Cross-domain digital twin workflows using shared Rust crates
    • Sectors: cloud/edge IoT platforms, enterprise software
    • Opportunity: Standardize protocol and device model crates that compile to embedded, desktop, and WASM targets, unifying device simulation, fleet testing, and firmware.
    • Potential products: DTDL-to-Rust code generators; PnP conformance testers; cloud “device twins in a crate.”
    • Dependencies/risks:
    • Evolving DTDL and PnP standards; keeping schemas in sync across targets.
  • Energy-aware firmware design via faster ISR servicing and idle budgeting
    • Sectors: battery-powered IoT, wearables, environmental sensors
    • Opportunity: Systematically correlate reduced stream latency and increased idle windows with energy usage, leading to Rust-based patterns that optimize power at target ODRs.
    • Potential products: Energy profilers integrated with logic analyzers; power-optimized async executors.
    • Dependencies/risks:
    • Hardware energy measurement setups; results may vary by sensor/MCU; async overhead can shrink idle windows if not tuned.
  • Large-scale migration frameworks from C to Rust for embedded fleets
    • Sectors: industrial IoT operators, OEMs with many SKUs
    • Opportunity: Methodologies and tools that run dual-track C/Rust implementations, measure parity (ROM/RAM/latency), and orchestrate gradual replacement with fallbacks and mixed-language crates.
    • Potential products: Migration playbooks; FFI bridges; binary diff/telemetry dashboards; fleet rollout tooling.
    • Dependencies/risks:
    • Organizational complexity; mixed-skill teams; maintaining dual stacks during transition.
  • Formal verification and analysis of embedded async runtimes
    • Sectors: research, high-assurance systems
    • Opportunity: Models and proofs that bound async executor latency under ISR load, proving deadlines at specified ODRs and MCU clocks.
    • Potential products: Verified subsets of Embassy/Ariel; model-checkers and schedulability analyzers for async Rust.
    • Dependencies/risks:
    • Significant research effort; aligning language/runtime evolution with proofs.
  • Broader MCU and sensor ecosystem coverage
    • Sectors: agriculture, logistics, energy, smart cities
    • Opportunity: Expand Rust driver crates and Ariel OS ports across non-ST MCUs and diverse sensors (ToF, environmental, GNSS), enabling portable, memory-safe firmware at scale.
    • Potential products: Community-maintained driver registries; HAL conformance tests; sensor “driver packs.”
    • Dependencies/risks:
    • Community maintenance; vendor collaboration; handling proprietary interfaces.
  • Curriculum and certification tracks for embedded Rust
    • Sectors: academia, training providers, professional certification
    • Opportunity: Standardized courses and certifications that cover no_std, heapless design, async tradeoffs, and performance tuning on MCUs.
    • Potential products: MOOCs, lab kits, certification exams, industry-recognized badges.
    • Dependencies/risks:
    • Coordinated ecosystem materials; hardware access at scale.
  • Policy frameworks that recognize memory-safe MCU firmware as a risk reducer
    • Sectors: regulators, public procurement
    • Opportunity: Guidance that quantifies risk reduction from memory-safe firmware (e.g., fewer memory safety bugs) and ties it to CRA-aligned assurance levels for microcontroller-based products.
    • Potential products: Best-practice documents; procurement checklists; maturity models.
    • Dependencies/risks:
    • More empirical data across diverse devices; stakeholder consensus.

Notes on general feasibility

  • Evidence base: The parity claims are demonstrated on STM32U585 (Cortex‑M33) and validated on an STM32F4 board. Similar results are likely on other Cortex‑M families but must be re-verified, especially where clocks, cache, and peripheral timing differ.
  • Async overhead: The paper shows measurable but manageable async overhead (few microseconds per switch) that can accumulate. Designs with tight deadlines may prefer synchronous code or carefully minimized await points.
  • Toolchain maturity: Success depends on Ariel OS/Embassy and driver crate coverage for target hardware. For ultra‑constrained MCUs or unusual peripherals, support may lag.
  • Team skills: Rust/no_std experience is a practical dependency. Training and pilot projects mitigate ramp-up risk.

Glossary

  • .bss: A memory section for statically allocated, zero-initialized data in embedded binaries. "placed in .bss"
  • .text section: The executable code section of a binary where compiled instructions reside. "the .text section totals 66,240 bytes"
  • AIoT: Artificial Intelligence of Things; integrating AI into IoT devices and systems. "artificial intelligence of things (AIoT)"
  • Ariel OS: A lightweight Rust library operating system providing portable HAL, runtime, and scheduler for MCUs. "Ariel OS provides a hardware abstraction layer (HAL) built on Embassy [8]"
  • Arm Cortex-M33: A 32-bit ARM microcontroller core with TrustZone and DSP features for embedded systems. "based on Arm Cortex-M33 core"
  • Asymmetric Serial Packet Exchange Protocol (ASPEP): A packet-level protocol defining header semantics/syntax for serial exchanges in VDP. "Asymmetric Serial Packet Exchange Protocol (ASPEP): Layer specifying semantics and syntax of packets headers;"
  • async/await: Rust’s asynchronous programming feature that compiles into state machines to manage concurrency. "leverages the async/await functionality [15] offered by Rust."
  • async executor model: The runtime mechanism that schedules and polls async tasks, introducing some latency. "stems from the async executor model"
  • atomic types: Low-level types guaranteeing atomic memory operations for safe concurrent access on MCUs. "atomic types are used instead"
  • Azure IoT Plug and Play (PnP): An Azure framework that uses device models to simplify IoT device integration. "Azure IoT Plug and Play (PnP) framework [11]"
  • bare-metal: Firmware running directly on hardware without an OS, often with manual interrupt handling. "bare-metal C"
  • bloaty: A binary size profiler used to break down ROM usage in compiled artifacts. "Measured using bloaty [25] and cargo-bloat [26]"
  • cargo-bloat: A Rust tool to analyze crate and function-level code size contributions. "Measured using bloaty [25] and cargo-bloat [26]"
  • CMSIS X-CUBE-MEMS1: An STM32 function pack providing drivers and examples for MEMS sensors. "the CMSIS X-CUBE-MEMS1 function pack for sensor support and drivers [19]"
  • crates.io: The Rust community package registry where embedded driver crates are published. "VDL-Rust imports the required ST sensor drivers [9] from crates.io."
  • Digital Twins Definition Language (DTDLv2): A JSON-based language for describing IoT device capabilities and telemetry schemas. "DTDLv2 [10], a JSON-based language for describing digital twins."
  • Embassy: An async Rust framework for embedded systems providing HALs, executors, and timers. "built on Embassy [8]"
  • embassy-sync: An Embassy crate offering thread-safe synchronization primitives (signals, channels) for async tasks. "VDL-Rust leverages the embassy-sync crate for inter-task communication"
  • EXTI: External interrupt interface on STM32 MCUs used to handle pin-change interrupts. "wakes the EXTI handler task"
  • flash prefetch: A CPU feature that preloads instructions from flash to reduce fetch stalls. "Enabling I-Cache and flash prefetch then eliminated instruction fetch stalls"
  • Hardware Abstraction Layer (HAL): A portability layer that provides high-level APIs over MCU peripherals. "hardware abstraction layer (HAL)"
  • heapless (crate): A Rust crate offering fixed-capacity, statically allocated data structures for no-heap environments. "the heapless crate [23], which provides types that mirror dynamic memory equivalents"
  • I-Cache: Instruction cache that speeds instruction fetches by storing recently used code. "Enabling I-Cache and flash prefetch then eliminated instruction fetch stalls"
  • I2C: A two-wire serial bus used to connect sensors and peripherals to MCUs. "sensor hardware interrupts trigger I2C reads."
  • IMU: Inertial Measurement Unit; a multi-axis motion sensor (e.g., accelerometer + gyroscope). "inertial measurement unit (IMU)"
  • Interrupt Service Routine (ISR): A function invoked by hardware interrupts to handle events immediately. "the hardware interrupt pin is monitored by an Embassy ISR"
  • Link-Time Optimization (LTO): A compiler optimization that performs whole-program analysis at link time to reduce size and improve speed. "compiled with LTO and -Os"
  • LSM6DSV16X: An ST 6-axis IMU sensor with embedded ML capabilities used in the case study. "we used the LSM6DSV16X accelerometer"
  • Machine Learning Core (MLC): On-sensor ML engine for local inference/classification within the IMU. "machine learning core (MLC) components."
  • MEMS: Micro-Electro-Mechanical Systems; tiny mechanical devices built into sensors like accelerometers and gyroscopes. "MEMS inertial measurement unit (IMU)"
  • microcontroller unit (MCU): A compact integrated circuit with a processor, memory, and peripherals for embedded control. "microcontroller unit (MCU)"
  • monomorphization: Rust’s process of generating specialized code for each concrete type used with generics, impacting code size. "monomorphization overhead"
  • no_alloc: A Rust environment constraint disallowing dynamic heap allocation. "no_std and no_alloc constraints"
  • no_std: A Rust environment that builds without the standard library, typical for bare-metal MCUs. "under no_std and no_alloc constraints"
  • Output Data Rate (ODR): The frequency at which a sensor produces samples. "Output Data Rate (ODR)"
  • Parson: A lightweight C JSON library used for parsing/serialization in the C firmware. "VDL-C bundles the open-source Parson library [12]"
  • PNPL: ST’s Plug-and-Play-related code generation and API layer used with device models. "the JSON parser used by the PNPL code generator by default"
  • rodata: Read-only data section of a binary where constants and literals are stored. "Total ROM (including rodata)"
  • RTIC: A Rust framework for real-time, interrupt-driven concurrency on MCUs. "Another example is RTIC [16], a real-time interrupt-driven concurrency framework."
  • serde: Rust’s ubiquitous framework for data serialization/deserialization across formats like JSON. "the serde crate [20], which provides a serialization/deserialization framework"
  • serde-json-core: A no-std JSON crate enabling zero-heap deserialization into fixed-size Rust types. "the serde-json-core crate [28] is used."
  • SensorTile.box Pro: An ST development board with sensors and an STM32 MCU used as the reference hardware. "the SensorTile.box Pro [5]"
  • SPI: A full-duplex serial communication bus often used for high-speed sensor interfaces. "communication buses (UART, I2C, SPI, etc.)"
  • StaticCell: A Rust utility for safely creating static, in-place-initialized objects without heap allocation. "using StaticCell [27]"
  • STM32CubeIDE: ST’s integrated development environment for STM32 projects. "due to the proliferation of distinct STM32CubeIDE projects required."
  • STM32CubeMX: ST’s code generator and configuration tool for STM32 HAL/BSP initialization. "STM32CubeMX [7], a de facto standard tool"
  • TIMINGR: STM32 I2C timing configuration register tuned for bus performance. "STM32CubeMX-computed TIMINGR values"
  • TockOS: An embedded Rust operating system that pioneered safety and isolation on microcontrollers. "TockOS [17] pioneered bare-metal, self-contained embedded Rust programming efforts."
  • UART FIFO: A buffer in the UART peripheral that can be enabled/disabled to affect latency/throughput. "Disabling the UART FIFO reduced UART latency"
  • Vanilla Datalog Protocol (VDP): The serial protocol stack used for command/response and sensor data streaming in STAIoTCraft. "The Vanilla Datalog Protocol serves as the de facto common denominator"
  • WebAssembly: A portable binary instruction format enabling Rust code reuse in browsers and desktop apps. "including embedded, WebAssembly, and desktop."

Open Problems

We haven't generated a list of open problems mentioned in this paper yet.

Collections

Sign up for free to add this paper to one or more collections.

Tweets

Sign up for free to view the 3 tweets with 133 likes about this paper.