GithubHelp home page GithubHelp logo

probe-rs / flash-algorithm-template Goto Github PK

View Code? Open in Web Editor NEW
10.0 10.0 6.0 29 KB

A template for writing CMSIS-Pack flash algorithms in Rust

License: Apache License 2.0

Rust 96.68% RPC 3.32%

flash-algorithm-template's Introduction

probe-rs

a modern, embedded debugging toolkit, written in Rust

crates.io documentation Actions Status chat

The goal of this library is to provide a toolset to interact with a variety of embedded MCUs and debug probes.

Similar projects like OpenOCD, PyOCD, Segger Toolset, ST Tooling, etc. exist. They all implement the GDB protocol and their own protocol on top of it to enable GDB to communicate with the debug probe. Only Segger provides a closed source DLL which you can use for talking to the JLink.

This project gets rid of the GDB layer and provides a direct interface to the debug probe, which then enables other software to use its debug functionality.

The end goal of this project is to have a complete library toolset to enable other tools to communicate with embedded targets.

Functionality

As of version 0.10.0 this library can

  • connect to a DAPLink, STLink or JLink
  • talk to ARM and Risc-V cores via SWD or JTAG
  • read and write arbitrary memory of the target
  • halt, run, step, breakpoint and much more the core
  • download ELF, BIN and IHEX binaries using standard CMSIS-Pack flash algorithms to ARM cores
  • provide debug information about the target state (stacktrace, stackframe, etc.)

To see what new functionality was added have a look at the CHANGELOG

Support

If you think probe-rs makes your embedded journey more enjoyable or even earns you money, please consider supporting the project on Github Sponsors for better support and more features.

Tools

In addition to being a library, probe-rs also includes a suite of tools which can be used for flashing and debugging.

Installation

The recommended way to install the tools is to download a precompiled version, using one of the methods below. See https://probe.rs/docs/getting-started/installation/ for a more detailed guide.

cargo-flash

The cargo-flash utility can be used as a cargo subcommand to download a compiled Rust program onto a target device. It can also be used to download arbitrary ELF files that might come out of a C/C++ compiler. Have a look at cargo-flash for more information.

cargo-embed

If you are looking for a more extended debugging experience, please have a look at cargo-embed which provides support for GDB, RTT, and config files.

Editors and IDEs

We have implemented the Microsoft Debug Adapter Protocol (DAP). This makes embedded debugging via probe-rs available in modern code editors implementing the standard, such as VSCode. The DAP website includes a list of editors and IDEs which support DAP.

VSCode

The probe-rs website includes VSCode configuration instructions.

Usage Examples

Halting the attached chip

use probe_rs::{Permissions, Probe};

fn main() -> Result<(), probe_rs::Error> {
    // Get a list of all available debug probes.
    let probes = Probe::list_all();

    // Use the first probe found.
    let probe = probes[0].open()?;

    // Attach to a chip.
    let mut session = probe.attach("nRF52840_xxAA", Permissions::default())?;

    // Select a core.
    let mut core = session.core(0)?;

    // Halt the attached core.
    core.halt(std::time::Duration::from_millis(300))?;

    Ok(())
}

Reading from RAM

use probe_rs::{MemoryInterface, Permissions, Session};

fn main() -> Result<(), probe_rs::Error> {
    // Attach to a chip.
    let mut session = Session::auto_attach("nRF52840_xxAA", Permissions::default())?;

    // Select a core.
    let mut core = session.core(0)?;

    // Read a block of 50 32 bit words.
    let mut buff = [0u32; 50];
    core.read_32(0x2000_0000, &mut buff)?;

    // Read a single 32 bit word.
    let word = core.read_word_32(0x2000_0000)?;

    // Writing is just as simple.
    let buff = [0u32; 50];
    core.write_32(0x2000_0000, &buff)?;

    // of course we can also write 8bit words.
    let buff = [0u8; 50];
    core.write_8(0x2000_0000, &buff)?;

    Ok(())
}

FAQ

I need help!

Don't hesitate to file an issue, ask questions on Matrix, or contact @Yatekii via e-mail.

There is also a troubleshooting section on the project page.

How can I help?

Please have a look at the issues or open one if you feel that something is needed.

Any contributions are very welcome!

Also have a look at CONTRIBUTING.md.

Our company needs feature X and would pay for its development

Please reach out to @Yatekii

Building

Building requires Rust and Cargo which can be installed using rustup. On Linux these can be installed with your package manager:

# Ubuntu
> sudo apt install -y libudev-dev

# Fedora
> sudo dnf install -y libudev-devel

Adding Targets

Target files are generated using target-gen from CMSIS packs provided here. Generated files are then placed in probe-rs/targets for inclusion in the probe-rs project.

Writing new flash algorithms

If there is no CMSIS-Pack with a flash algorithm available, it is necessary to write a target definition and a flash algorithm by oneself. You can use our template for writing an algorithm. Please follow the instructions in the README.md in that repo.

Acknowledgements

In early stages of this library, we profited invaluably from the pyOCD code to understand how flashing works. Also it's always a good reference to cross check how ARM specific things work. So, a big thank you to the team behind pyOCD!

License

Licensed under either of

Contributing

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

flash-algorithm-template's People

Contributors

elfmimi avatar tgross35 avatar yatekii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

flash-algorithm-template's Issues

No RTT messages

When running with cargo run, RTT messages are not printed.

Actual behavior:

Generating the YAML file in `"target/definition.yaml"`
Test: Erasing sectorwise and writing two pages ...
thread 'main' panicked at 'Not all sectors were erased'

Expected:

Generating the YAML file in `"target/definition.yaml"`
Test: Erasing sectorwise and writing two pages ...
Message: Init
Message: Erase sector addr:0
Message: Erase sector addr:8192
thread 'main' panicked at 'Not all sectors were erased'

This happens because target-gen disables the default rtt feature of probe-rs when installed according to the README.

cargo install target-gen

Installing target-gen with the feature enabled gives the expected behavior.

cargo install target-gen --features probe-rs/rtt

The README could be updated to suggest this, but I'm not sure if it makes more sense to change the default features of target-gen instead.

Need flash-algorithm 0.4.0 instead of 0.3.0

This is how program_page() is defined in this template.

fn program_page(&mut self, addr: u32, data: &[u8]) -> Result<(), ErrorCode> {

Here, the dependency is requesting for flash-algorithm 0.3.0 .

flash-algorithm = { version = "0.3.0" }

https://crates.io/crates/flash-algorithm/0.3.0 is based on the following commit.
probe-rs/flash-algorithm@5488faf
Where program_page() is still declared in this way.
https://github.com/probe-rs/flash-algorithm/blob/5488faf5efcd467379cfb0ae3c7d0f5b673095a6/src/lib.rs#L51

fn program_page(&mut self, address: u32, size: u32, data: *const u8) -> Result<(), ErrorCode>;

also, it can be checked at docs.rs .
https://docs.rs/flash-algorithm/0.3.0/src/flash_algorithm/lib.rs.html#44-51
https://docs.rs/flash-algorithm/0.4.0/src/flash_algorithm/lib.rs.html#55-61

Feature suggestion: read chip UID and self testing functions?

Hi,

I'm wondering if you guys would like to have some sort of self-testing or reading chip UID functions. I can implement something like that but I'm not sure if that might be out of scope for this project or not. But I believe it may be quite useful for mass production purposes.

For example, I implement some functions (in C symbol, not Rust, that exposes to some customized offline programming probe or host-side debug program like probe-rs's YAML configs) like:

  • ReadChipUID(): read out the chip's unique ID (for STM32 it's 96-bit + some STM32s have an additional 64-bit unique MAC)
  • SelfTest(): do a simple, custom self-test, e.g. check if the UART/I2C/SPI communications with other external peripherals on the boards are working or not; return a zero result if successful, otherwise returns some non-zero values to indicate what has gone wrong.

For ReadChipUID(), it can be done by asking the probe to read out the memory address directly (like STM32WL that's 0x1fff7590) but it's more for some sort of unification. Different chips have different UID addresses, and the host-side debug/mass production programs only need to call the same ReadChipUID() to retrieve the UID number without knowing where the address is.

Regards,
Jackson

Panic - "Not all sectors were erased" while the flash has been wiped?

Hi all,

Firstly thanks for this great work! I've finally found something much more organized than CMSIS-Pack's flashing algorithm! I'm trying to implement a flash algorithm for STM32WLJC. Here's the implementation: https://github.com/huming2207/stm32wle5-flash-algo/blob/master/src/main.rs

Then I tried running RUST_BACKTRACE=1 cargo run, here's what I've got:

Test: Erasing sectorwise and writing two pages ...
Message: Init
Message: Erase sector addr:0x8000000
Message: Erase sector addr:0x8000800
thread 'main' panicked at 'Not all sectors were erased', /home/hu/.cargo/registry/src/github.com-1ecc6299db9ec823/target-gen-0.16.0/src/commands/test.rs:99:5
stack backtrace:
   0: rust_begin_unwind
             at /rustc/90743e7298aca107ddaa0c202a4d3604e29bfeb6/library/std/src/panicking.rs:575:5
   1: core::panicking::panic_fmt
             at /rustc/90743e7298aca107ddaa0c202a4d3604e29bfeb6/library/core/src/panicking.rs:65:14
   2: target_gen::commands::test::cmd_test
   3: target_gen::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

However, if I use pyocd cmd and run rw 0x08000000 128, here's what I've got:

pyocd> rw 0x08000000 4096
08000000:  ffffffff ffffffff ffffffff ffffffff    |................|
08000010:  ffffffff ffffffff ffffffff ffffffff    |................|
08000020:  ffffffff ffffffff ffffffff ffffffff    |................|
08000030:  ffffffff ffffffff ffffffff ffffffff    |................|
08000040:  ffffffff ffffffff ffffffff ffffffff    |................|
08000050:  ffffffff ffffffff ffffffff ffffffff    |................|
08000060:  ffffffff ffffffff ffffffff ffffffff    |................|
08000070:  ffffffff ffffffff ffffffff ffffffff    |................|
...
08000e40:  ffffffff ffffffff ffffffff ffffffff    |................|
08000e50:  ffffffff ffffffff ffffffff ffffffff    |................|
08000e60:  ffffffff ffffffff ffffffff ffffffff    |................|
08000e70:  ffffffff ffffffff ffffffff ffffffff    |................|
08000e80:  ffffffff ffffffff ffffffff ffffffff    |................|
08000e90:  ffffffff ffffffff ffffffff ffffffff    |................|
08000ea0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000eb0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000ec0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000ed0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000ee0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000ef0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f00:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f10:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f20:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f30:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f40:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f50:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f60:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f70:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f80:  ffffffff ffffffff ffffffff ffffffff    |................|
08000f90:  ffffffff ffffffff ffffffff ffffffff    |................|
08000fa0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000fb0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000fc0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000fd0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000fe0:  ffffffff ffffffff ffffffff ffffffff    |................|
08000ff0:  ffffffff ffffffff ffffffff ffffffff    |................|

As you see, the flash has been emptied.

I've also checked the target-gen 's code and here's something that made me a bit confused: https://github.com/probe-rs/probe-rs/blob/dc5eb11ba23a5abfd1dd734385b93c7edd60f490/target-gen/src/commands/test.rs#L98

I'm not sure why it's hardcoded to 0x0? I think it probably should be to whichever the microcontroller's flash base address is. For my STM32WLE5JC, it should be 0x08000000. May I ask, am I right? Have I misinterpreted something?

Regards,
Jackson

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.