probe-rs

website·Indexed 34 days ago

https://probe.rs/

An embedded debugging and target interaction toolkit used to program and debug microcontrollers. It includes a library for attaching to targets, a CLI utility, and tools such as cargo-flash and cargo-embed. The toolkit supports various probes and targets, including JTAG debugging for Raspberry Pi 4B, and provides integration with VS Code via a Debug Adapter Protocol (DAP) server.

Tokens
14.3K
Snippets
70
Records
110
Agent score
69%

What's inside probe-rs

  1. Overview of cargo-flash

    cargo-flash is a cargo extension and drop-in replacement for cargo run. Instead of executing the binary on the host machine, cargo-flash downloads the binary to the target embedded device and runs it. It accepts any configuration flags that are normally accepted by cargo run.
  2. Overview of probe-rs embedded debugging toolkit

    probe-rs is an embedded debugging and target interaction toolkit used to program and debug microcontrollers via a debug probe. It supports ARM and RISC-V architectures (with more in development) and works for both Rust and C programming.

    Key capabilities include:

    • Flashing firmware to targets.
    • Target control via SWD and JTAG: reading/writing memory, running, halting, resetting, and managing breakpoints.
    • Log retrieval via RTT and defmt, including stacktrace printing on panic.
    • Integration with VS Code for memory inspection and real-time RTT logs.
  3. Overview of cargo-embed

    cargo-embed is a tool for flashing targets, opening an RTT (Real Time Transfer) terminal, and starting a GDB server. It is installed as part of the probe-rs tool suite.
  4. Overview of probe-rs embedded debugging toolkit

    probe-rs is an embedded debugging and target interaction toolkit used to program and debug microcontrollers via a debug probe. It supports ARM and RISC-V architectures and is compatible with firmware written in both Rust and C. Key capabilities include:

    • Flashing firmware to targets.
    • Target control via SWD and JTAG (reading/writing memory, running, halting, resetting, and managing breakpoints).
    • Log retrieval via RTT and defmt, including stacktrace printing on panic.
    • Integration with VS Code for memory inspection and real-time RTT logs.
  5. Overview of probe-rs capabilities

    probe-rs is an embedded debugging and target interaction toolkit that allows users to program and debug microcontrollers via a debug probe. It supports ARM and RISC-V architectures and is compatible with firmware written in both Rust and C. Key capabilities include:

    • Flashing firmware to targets.
    • Target control via SWD and JTAG (reading/writing memory, running, halting, resetting, and managing breakpoints).
    • Log retrieval using RTT and defmt, including stacktrace printing on panic.
    • Integration with VS Code for debugging, memory inspection, and real-time RTT logs.
  6. Overview of probe-rs embedded toolkit

    probe-rs is a flexible embedded toolkit for ARM and RISC-V targets. It allows developers to run programs on microchips with the ease of native applications, supporting both Rust and C. Key capabilities include reading/writing memory, setting breakpoints, and controlling target execution (run/halt) via a clean API.
  7. Cross-compile probe-rs tools using Cross

    When cargo install is not possible due to system permissions or resource limitations (e.g., memory limits on a Raspberry Pi), you can use the cross tool to build a static binary on a different architecture. cross uses Docker images to avoid issues with host machine shared object libraries.

    This process involves creating a custom Docker image that resembles the target system and contains a cross C toolchain, then configuring cross to use that image via a Cross.toml file.

    # 1. Clone the repository and install cross
    git clone https://github.com/probe-rs/probe-rs
    cargo install cross
    
    # 2. Setup the custom Docker image directory
    cd probe-rs
    mkdir crossimage
    # [Place a Dockerfile resembling the target system inside the crossimage folder]
    
    # 3. Build and tag the container image
    docker build -t crossimage crossimage/
    
    # 4. Build the target binary
    cross build \
        -p probe-rs-tools \
        --release \
        --target=armv7-unknown-linux-gnueabihf
  8. Understand CMSIS-Packs and Flash Algorithms

    CMSIS-Packs are ZIP files used by ARM core manufacturers to distribute documentation, HALs, and flash algorithms. The root of the ZIP contains a .pdsc XML file with metadata. Flash algorithms are provided as .FLM files, which are ELF binaries containing functions (following ARM EABI calling convention) that are loaded into RAM by a flash downloader to program the chip.
  9. Configure Cross.toml for custom build images

    To tell cross which Docker container image to use for a specific target architecture, create a Cross.toml file in the root of the repository. The image key should match the tag used when building the Docker image.
    [target.armv7-unknown-linux-gnueabihf]
    image = "crossimage"
  10. Understand CMSIS-Packs in probe-rs

    CMSIS-Packs are ZIP files used to distribute documentation, flash algorithms, code samples, and HALs for ARM cores. They contain a .pdsc XML file at the root which defines the metadata for the Pack. Flash algorithms within these packs are stored as .FLM files, which are ELF binaries containing the logic required to program the chip's flash memory.
  11. Define target descriptions using the probe-rs YAML format

    probe-rs uses a slimmed-down YAML format to describe chip families, avoiding the bloat of full CMSIS-Packs. The YAML structure defines the chip family, its variants, CPU cores (including architecture and access options), a memory map (RAM, NVM, or Generic), and the associated flash algorithms.
    ---
    # The name of the chip family.
    name: string
    # A list of all the chips in the family.
    variants:
      # The name of the chip.
      - name: string
        # Descriptions of the CPU cores.
        cores:
            # The name of the core.
          - name: string
            # Architecture: armv6m | armv7a | armv7m | armv7em | armv8a | armv8m | riscv | xtensa
            type: armv7m
            # Core-specific options. Can be one of: `!Arm {}`, `!Riscv {}`, `!Xtensa {}`
            core_access_options: object
        # A list of all the available memories and their properties.
        memory_map:
          - !Ram
              range:
                start: number
                end: number
              access:
                boot: boolean
              cores:
                - core name
          - !Nvm
              range:
                start: number
                end: number
              access:
                boot: boolean
              cores:
                - core name
          - !Generic
              range:
                start: number
                end: number
              cores:
                - core name
        # A list of all the used flash algorithms.
        flash_algorithms:
          - string
    
    # A list of all the available flash algorithms.
    flash_algorithms:
        - name: string
          description: string
          default: boolean
          # Base 64 encoded ELF binary blob
          instructions: base64string
          pc_init: number
          pc_uninit: number
          pc_program_page: number
          pc_erase_sector: number
          pc_erase_all: number
          data_section_offset: number
          transfer_encoding: raw | miniz
          flash_properties:
            address_range:
              start: number
              end: number
            page_size: number
            erased_byte_value: number
            program_page_timeout: number
            erase_sector_timeout: number
            sectors:
              - size: number
                address: number
            cores:
              - core name
  12. Control CPU execution and registers with the Core struct

    The Core struct allows direct manipulation of the CPU. You can halt the CPU (with a specified timeout), check its halted state, step through instructions, run the CPU, or perform a soft reset. It also provides methods to read and write CPU registers.
    // Halt the core with a 100ms timeout
    core.halt(Duration::from_ms(100))?;
    
    // Check if the core is currently halted
    let is_halted = core.core_halted()?;
    
    // Step the CPU on a per-instruction basis
    core.step()?;
    
    // Resume CPU execution
    core.run()?;
    
    // Perform a soft reset
    core.reset()?;
    
    // Read and write CPU registers
    let reg = core.read_core_reg(0x00)?;
    core.write_core_reg(0x00, reg | 0x42)?;