Embedded Rust or C Firmware? Lessons from an Industrial Microcontroller Use Case with Ariel OS
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.
Paper Prompts
Sign up for free to create and run prompts on this paper using GPT-5.
Top Community Prompts
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, andheaplessto 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
serdefor 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+heaplessto 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; minimizeasyncawait 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."
Collections
Sign up for free to add this paper to one or more collections.