Skip to content

Running Firmware Images

LabWired executes standard ELF binaries compiled for ARM Cortex-M targets. The simulation environment requires two components: a valid firmware image and a declarative system configuration.

1. Compatible Firmware

LabWired loads ELF files generated by standard toolchains (Rust rustc, GCC arm-none-eabi-gcc).

Requirements

  • Format: ELF (Executable and Linkable Format).
  • Architecture: ARMv7-M (Cortex-M3) or compatible.
  • Memory Layout: Sections must be linked to valid addresses defined in the Chip Descriptor.
  • Entry Point: The Vector Table must be placed at the Flash base address (typically 0x0800_0000).

Compilation Example (Rust)

Ensure the target is installed and build in release mode for performance:

rustup target add thumbv7m-none-eabi
cargo build --release --target thumbv7m-none-eabi

2. System Definition

The simulation hardware is defined via two YAML configuration files: 1. Chip Descriptor: Defines the internal memory map and peripheral base addresses. 2. System Manifest: Defines the board-level configuration and instantiates the chip.

Chip Descriptor (chip.yaml)

Defines the MCU's physical memory layout.

name: "STM32F103"
flash:
  base: 0x08000000
  size: "64KB"
ram:
  base: 0x20000000
  size: "20KB"
peripherals:
  - id: "rcc"
    type: "rcc"
    base_address: 0x40021000

System Manifest (system.yaml)

Instantiates the chip and configures external connections.

name: "bluepill-board"
chip: "../chips/stm32f103.yaml"

3. Simulation Execution

Invoke the labwired-cli with the firmware path and system configuration:

labwired --firmware firmware.elf --system system.yaml

Loading Process

  1. Segment Loading: The loader creates a virtual memory space based on the Chip Descriptor. PT_LOAD segments from the ELF are copied to their respective addresses (Flash/RAM).
  2. Vector Table Initialization: The initial Stack Pointer (SP) is loaded from FlashBase + 0x00. The Reset Vector (PC) is loaded from FlashBase + 0x04.
  3. Execution Loop: The CPU begins fetching and executing instructions from the Reset Vector.

4. Common Runtime Issues

Invalid Memory Access (BusFault)

Symptom: Simulation terminates with MemoryAccessViolation. Cause: The firmware attempted to read/write an address not mapped in chip.yaml. Resolution: Verify linker script memory regions match the Chip Descriptor.

Vector Table Mismatch

Symptom: HardFault immediately upon start. Cause: The Vector Table is not located at the Flash Base Address. Resolution: inspected the ELF headers (objdump -h) to confirm .vector_table placement.

Peripheral Stalls

Symptom: Firmware hangs in a polling loop (e.g., waiting for RCC_CR_HSIRDY). Cause: The peripheral model does not fully implement the status flag logic required by the HAL. Resolution: Run with --trace to identify the spinning loop. Use a StubPeripheral to mock the expected status bit if a full model is unavailable.