Browse Source

First draft of the config structure for cmsis pack based flashing configuration (#86)

* First draft of the config structure for cmsis pack based flashing configuration

* Remove repositories module as we don't need it for now

* Add range extension function testing

* Updated some types

* Add config parsing

* Fix target selection

* Change everything to the new config structure.

* Add fixed algorithm. It is slow as hell now (example blinky takes 68s)

* Add extracted LPC845

* Clean up flash builder module

* Clean up download.rs & add hex flashing

* Removal of old types that were moved to the config module

* Add LPC55 series

* Add STM32F103 targets

* Combine all chip configs into one family config.

* Clean up code, comment, remove pyocd artifacts

* Improve logging

* Add some docs

* Clean up some real ugly code

* Update cargo-flash/README.md

* Add the m33 to the get_core() method
double-buffering
Yatekii 2 years ago
committed by GitHub
parent
commit
4dda1fc14e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      .gitignore
  2. 1
      Cargo.toml
  3. 4
      README.md
  4. 1
      cargo-flash/Cargo.toml
  5. 15
      cargo-flash/README.md
  6. 119
      cargo-flash/src/main.rs
  7. 1
      cli/Cargo.toml
  8. 62
      cli/src/common.rs
  9. 2
      cli/src/debugger.rs
  10. 12
      cli/src/main.rs
  11. 25
      probe-rs-targets/Cargo.toml
  12. 27
      probe-rs-targets/algorithms/STM32F042.yaml
  13. 27
      probe-rs-targets/algorithms/STM32F429xI.yaml
  14. 23
      probe-rs-targets/algorithms/nRF51822.yaml
  15. 23
      probe-rs-targets/algorithms/nRF52832.yaml
  16. 23
      probe-rs-targets/algorithms/nRF52840.yaml
  17. 118
      probe-rs-targets/build.rs
  18. 70
      probe-rs-targets/src/lib.rs
  19. 31
      probe-rs-targets/targets/STM32F042.yaml
  20. 32
      probe-rs-targets/targets/STM32F429xI.yaml
  21. 46
      probe-rs-targets/targets/nRF51822.yaml
  22. 46
      probe-rs-targets/targets/nRF52832.yaml
  23. 47
      probe-rs-targets/targets/nRF52840.yaml
  24. 8
      probe-rs/Cargo.toml
  25. 283
      probe-rs/build.rs
  26. 20
      probe-rs/src/collection/cores/mod.rs
  27. 126
      probe-rs/src/collection/mod.rs
  28. 13
      probe-rs/src/config/chip.rs
  29. 42
      probe-rs/src/config/chip_family.rs
  30. 133
      probe-rs/src/config/flash_algorithm.rs
  31. 230
      probe-rs/src/config/memory.rs
  32. 6
      probe-rs/src/config/mod.rs
  33. 259
      probe-rs/src/config/registry.rs
  34. 50
      probe-rs/src/config/target.rs
  35. 0
      probe-rs/src/cores/m0.rs
  36. 0
      probe-rs/src/cores/m33.rs
  37. 0
      probe-rs/src/cores/m4.rs
  38. 33
      probe-rs/src/cores/mod.rs
  39. 5
      probe-rs/src/lib.rs
  40. 8
      probe-rs/src/probe/daplink/mod.rs
  41. 646
      probe-rs/src/probe/flash/builder.rs
  42. 249
      probe-rs/src/probe/flash/download.rs
  43. 261
      probe-rs/src/probe/flash/flasher.rs
  44. 241
      probe-rs/src/probe/flash/loader.rs
  45. 169
      probe-rs/src/probe/flash/memory.rs
  46. 2
      probe-rs/src/probe/flash/mod.rs
  47. 16
      probe-rs/src/session.rs
  48. 64
      probe-rs/src/target/mod.rs
  49. 456
      probe-rs/targets/LPC55S66.yaml
  50. 877
      probe-rs/targets/LPC55S69.yaml
  51. 538
      probe-rs/targets/LPC800 Series.yaml
  52. 1627
      probe-rs/targets/STM32F1 Series.yaml
  53. 1287
      probe-rs/targets/nRF51 Series.yaml
  54. 1096
      probe-rs/targets/nRF52 Series.yaml
  55. 812
      probe-rs/targets/nRF91 Series.yaml

5
.gitignore

@ -1,3 +1,8 @@
/target
**/*.rs.bk
Cargo.lock
# Needed for RLS
probe-rs/target
cli/target
cargo-flash/target

1
Cargo.toml

@ -1,7 +1,6 @@
[workspace]
members = [
"probe-rs",
"probe-rs-targets",
"cli",
"cargo-flash",
]

4
README.md

@ -63,11 +63,13 @@ The help dialog should then tell you how to use the CLI.
- [x] Basic flash downloader working with nRF51.
- [x] cargo-flash which can automatically build & flash the target elf file.
- [x] Docs
- [ ] v0.2.0
- [x] v0.2.0
- [x] Parse yaml (or anything else) config files for flash algorithm definitions, such that arbitrary chips can be added.
- [x] Modularize code to allow other cores than M0 and be able to dynamically load chip definitions.
- [x] Target autodetection.
- [x] M4 targets.
- [ ] v0.3.0
- [x] Automatic CMSIS-Pack parsing and loading for flash algorithms.
- [ ] ...
- [ ] Basic debugging for Cortex m0, m3, m4.
- [ ] Stepping in

1
cargo-flash/Cargo.toml

@ -19,4 +19,3 @@ cargo-project = "0.2.2"
failure = "0.1.5"
colored = "1.8.0"
probe-rs = { path = "../probe-rs", version = "0.2.0" }
probe-rs-targets = { path = "../probe-rs-targets", version = "0.2.0" }

15
cargo-flash/README.md

@ -32,20 +32,23 @@ which will then build your binary and download the contents onto the connected t
#### Use a custom chip definition from a non-builtin file
`cargo flash --release --chip-description-path ../../.config/probe-rs/targets/nRF52840.yaml --target thumbv6m-none-eabi --example gpio_hal_blinky`
`cargo flash --release --chip-description-path nRF51822.yaml --target thumbv6m-none-eabi --example gpio_hal_blinky`
### Manually selecting a chip
To manually select a chip, you can use the `--chip <chip name>` argument. The chip name is an identifier such as `nRF51822` or `STM32F042`. Capitalization does not matter; Special characters do matter.
### Specifying the chip via chip configuration file
### Specifying a chip family description file
You can directly set the chip description by using the `--chip-description-path <chip description file path>` or `-c` argument. You need to pass it the path to a valid yaml chip description.
You can add a temporary chip family description by using the `--chip-description-path <chip description file path>` or `-c` argument. You need to pass it the path to a valid yaml family description.
All the targets of the family will then be added to the registry temporarily and will override existing variants with the same name.
You can use this feature to tinker with a chip family description until it works and then submit it to upstream for inclusion.
### Locally installing & overriding chip descripions
### Extracting a chip family description file from a CMSIS-Pack
You can install valid chip description files locally under `$HOME/.config/probe-rs/targets` and flash algorithm files under `$HOME/.config/probe-rs/algorithms`. Any chip descriptions for identifiers that match the compiled in identifiers will replace the compiled in descriptions. You can override all the descriptions like this. Invalid files will be ignored gracefully.
You can extract the family description file by running [target-gen](https://github.com/probe-rs/target-gen) on a `.pack` file with `cargo run -- file.pack out_dir`. You can obtain the pack from ARM for example. Their online [registry](https://developer.arm.com/tools-and-software/embedded/cmsis/cmsis-search) is a good start :)
You can also reference to an already unziped `pack` directory instead of the `file.pack` archive file.
## Add more chip definitions
If you have a chip you want to flash, feel free to contribute to [probe-rs](https://github.com/probe-rs/probe-rs).
If you have a chip you want to flash, feel free to contribute to [probe-rs](https://github.com/probe-rs/probe-rs).

119
cargo-flash/src/main.rs

@ -6,31 +6,26 @@ use std::{
env,
error::Error,
fmt,
fs::read_to_string,
path::PathBuf,
path::{Path, PathBuf},
process::{self, Command, Stdio},
time::Instant,
};
use structopt::StructOpt;
use probe_rs::{
config::registry::{Registry, SelectionStrategy},
coresight::access_ports::AccessPortError,
probe::{
daplink,
debug_probe::{DebugProbe, DebugProbeError, DebugProbeType, MasterProbe},
flash::{
download::{FileDownloader, Format},
flasher::AlgorithmSelectionError,
},
flash::download::{download_file, Format},
protocol::WireProtocol,
stlink,
},
session::Session,
target::{info::ChipInfo, Target},
target::info::ChipInfo,
};
use probe_rs_targets::{select_algorithm, select_target, SelectionStrategy};
#[derive(Debug, StructOpt)]
struct Opt {
#[structopt(name = "chip", long = "chip")]
@ -43,6 +38,8 @@ struct Opt {
chip_description_path: Option<String>,
#[structopt(name = "nrf-recover", long = "nrf-recover")]
nrf_recover: bool,
#[structopt(name = "list-chips", long = "list-chips")]
list_chips: bool,
// `cargo build` arguments
#[structopt(name = "binary", long = "bin")]
@ -89,6 +86,12 @@ fn main_try() -> Result<(), failure::Error> {
// Get commandline options.
let opt = Opt::from_iter(&args);
if opt.list_chips {
print_families();
std::process::exit(0);
}
args.remove(0); // Remove executable name
// Remove possible `--chip <chip>` arguments as cargo build does not understand it.
@ -210,47 +213,26 @@ fn main_try() -> Result<(), failure::Error> {
}
};
let target_override = opt
.chip_description_path
.as_ref()
.map(|cd| -> Result<_, failure::Error> {
let string = read_to_string(&cd).map_err(|e| {
format_err!("failed to read chip description file from {}: {}", cd, e)
})?;
let target = Target::new(&string)
.map_err(|e| format_err!("failed to parse chip description file {}: {}", cd, e))?;
Ok(target)
})
.transpose()?;
let strategy = if let Some(name) = opt.chip {
if name == "nRF52832" || name == "nRF52840" {
let _ = ChipInfo::read_from_rom_table(&mut probe)?;
}
SelectionStrategy::Name(name)
let strategy = if let Some(identifier) = opt.chip {
SelectionStrategy::TargetIdentifier(identifier.into())
} else {
SelectionStrategy::ChipInfo(ChipInfo::read_from_rom_table(&mut probe)?)
};
let target = if let Some(target) = target_override {
target
} else {
select_target(&strategy)?
};
let flash_algorithm = match target.flash_algorithm.clone() {
Some(name) => select_algorithm(name)?,
None => return Err(AlgorithmSelectionError::NoAlgorithmSuggested.into()),
};
let mut registry = Registry::from_builtin_families();
if let Some(cdp) = opt.chip_description_path {
registry.add_target_from_yaml(&Path::new(&cdp))?;
}
let target = registry.get_target(strategy)?;
let mut session = Session::new(target, probe, Some(flash_algorithm));
let mut session = Session::new(target, probe);
// Start timer.
let instant = Instant::now();
let mm = session.target.memory_map.clone();
let fd = FileDownloader::new();
fd.download_file(
download_file(
&mut session,
std::path::Path::new(&path_str.to_string().as_str()),
Format::Elf,
@ -271,45 +253,21 @@ fn main_try() -> Result<(), failure::Error> {
Ok(())
}
/// Takes a closure that is handed an `DAPLink` instance and then executed.
/// After the closure is done, the USB device is always closed,
/// even in an error case inside the closure!
pub fn with_device<F>(n: usize, target: Target, f: F) -> Result<(), DownloadError>
where
for<'a> F: FnOnce(Session) -> Result<(), DownloadError>,
{
let device = {
let mut list = daplink::tools::list_daplink_devices();
list.extend(stlink::tools::list_stlink_devices());
list.remove(n)
};
let probe = match device.probe_type {
DebugProbeType::DAPLink => {
let mut link = daplink::DAPLink::new_from_probe_info(&device)?;
link.attach(Some(WireProtocol::Swd))?;
MasterProbe::from_specific_probe(link)
fn print_families() {
println!("Available chips:");
let registry = Registry::from_builtin_families();
for family in registry.families() {
println!("{}", family.name);
println!(" Variants:");
for variant in family.variants() {
println!(" {}", variant.name);
}
DebugProbeType::STLink => {
let mut link = stlink::STLink::new_from_probe_info(&device)?;
link.attach(Some(WireProtocol::Swd))?;
MasterProbe::from_specific_probe(link)
println!(" Algorithms:");
for algorithms in family.algorithms() {
println!(" {} ({})", algorithms.name, algorithms.description);
}
};
let flash_algorithm = match target.flash_algorithm.clone() {
Some(name) => select_algorithm(name)?,
None => return Err(AlgorithmSelectionError::NoAlgorithmSuggested.into()),
};
let session = Session::new(target, probe, Some(flash_algorithm));
f(session)
}
}
#[cfg(unix)]
@ -331,7 +289,6 @@ pub enum DownloadError {
AccessPort(AccessPortError),
StdIO(std::io::Error),
Quit,
FlashAlgorithm(AlgorithmSelectionError),
}
impl Error for DownloadError {
@ -343,7 +300,6 @@ impl Error for DownloadError {
AccessPort(ref e) => Some(e),
StdIO(ref e) => Some(e),
Quit => None,
FlashAlgorithm(ref e) => Some(e),
}
}
}
@ -357,7 +313,6 @@ impl fmt::Display for DownloadError {
AccessPort(ref e) => e.fmt(f),
StdIO(ref e) => e.fmt(f),
Quit => write!(f, "Quit error..."),
FlashAlgorithm(ref e) => e.fmt(f),
}
}
}
@ -379,9 +334,3 @@ impl From<std::io::Error> for DownloadError {
DownloadError::StdIO(error)
}
}
impl From<AlgorithmSelectionError> for DownloadError {
fn from(error: AlgorithmSelectionError) -> Self {
DownloadError::FlashAlgorithm(error)
}
}

1
cli/Cargo.toml

@ -14,7 +14,6 @@ license = "MIT OR Apache-2.0"
[dependencies]
probe-rs = { path = "../probe-rs", version = "0.2.0" }
probe-rs-targets = { path = "../probe-rs-targets", version = "0.2.0" }
pretty_env_logger = "0.3.0"
log = "0.4.6"

62
cli/src/common.rs

@ -1,20 +1,19 @@
use crate::SharedOptions;
use probe_rs::{
collection::cores::m0::FakeM0,
config::registry::{Registry, RegistryError, SelectionStrategy},
cores::m0::FakeM0,
coresight::access_ports::AccessPortError,
probe::{
daplink,
debug_probe::{DebugProbe, DebugProbeError, DebugProbeType, FakeProbe, MasterProbe},
flash::{download::FileDownloadError, flasher::AlgorithmSelectionError},
flash::download::FileDownloadError,
protocol::WireProtocol,
stlink,
},
session::Session,
target::info::{self, ChipInfo},
target::TargetSelectionError,
};
use probe_rs_targets::{select_algorithm, select_target, SelectionStrategy};
use ron;
@ -28,10 +27,9 @@ pub enum CliError {
InfoReadError(info::ReadError),
DebugProbe(DebugProbeError),
AccessPort(AccessPortError),
TargetSelectionError(TargetSelectionError),
StdIO(std::io::Error),
FlashAlgorithm(AlgorithmSelectionError),
FileDownload(FileDownloadError),
RegistryError(RegistryError),
MissingArgument,
UnableToOpenProbe,
}
@ -44,11 +42,10 @@ impl Error for CliError {
InfoReadError(e) => Some(e),
DebugProbe(ref e) => Some(e),
AccessPort(ref e) => Some(e),
TargetSelectionError(ref e) => Some(e),
StdIO(ref e) => Some(e),
RegistryError(ref e) => Some(e),
MissingArgument => None,
UnableToOpenProbe => None,
FlashAlgorithm(ref e) => Some(e),
FileDownload(ref e) => Some(e),
}
}
@ -62,10 +59,9 @@ impl fmt::Display for CliError {
InfoReadError(e) => e.fmt(f),
DebugProbe(ref e) => e.fmt(f),
AccessPort(ref e) => e.fmt(f),
TargetSelectionError(ref e) => e.fmt(f),
StdIO(ref e) => e.fmt(f),
FlashAlgorithm(ref e) => e.fmt(f),
FileDownload(ref e) => e.fmt(f),
RegistryError(ref e) => e.fmt(f),
MissingArgument => write!(f, "Command expected more arguments."),
UnableToOpenProbe => write!(f, "Unable to open probe."),
}
@ -96,15 +92,9 @@ impl From<std::io::Error> for CliError {
}
}
impl From<TargetSelectionError> for CliError {
fn from(error: TargetSelectionError) -> Self {
CliError::TargetSelectionError(error)
}
}
impl From<AlgorithmSelectionError> for CliError {
fn from(error: AlgorithmSelectionError) -> Self {
CliError::FlashAlgorithm(error)
impl From<RegistryError> for CliError {
fn from(error: RegistryError) -> Self {
CliError::RegistryError(error)
}
}
@ -159,29 +149,17 @@ where
{
let mut probe = open_probe(shared_options.n)?;
let selection_strategy = if let Some(ref target_name) = shared_options.target {
SelectionStrategy::Name(target_name.clone())
let strategy = if let Some(identifier) = &shared_options.target {
SelectionStrategy::TargetIdentifier(identifier.into())
} else {
let chip_info = ChipInfo::read_from_rom_table(&mut probe)?;
SelectionStrategy::ChipInfo(chip_info)
SelectionStrategy::ChipInfo(ChipInfo::read_from_rom_table(&mut probe)?)
};
let target = select_target(&selection_strategy)?;
let flash_algorithm = match target.flash_algorithm {
Some(ref name) => select_algorithm(name),
None => Err(AlgorithmSelectionError::NoAlgorithmSuggested),
};
let registry = Registry::from_builtin_families();
let flash_algorithm = match flash_algorithm {
Ok(flash_algorithm) => Some(flash_algorithm),
Err(error) => {
println!("{:?}", error);
None
}
};
let target = registry.get_target(strategy)?;
let session = Session::new(target, probe, flash_algorithm);
let session = Session::new(target, probe);
f(session)
}
@ -199,17 +177,19 @@ where
let probe = MasterProbe::from_specific_probe(Box::new(fake_probe));
let selection_strategy = if let Some(ref target_name) = shared_options.target {
SelectionStrategy::Name(target_name.clone())
let strategy = if let Some(identifier) = &shared_options.target {
SelectionStrategy::TargetIdentifier(identifier.into())
} else {
unimplemented!();
};
let mut target = select_target(&selection_strategy)?;
let registry = Registry::from_builtin_families();
let mut target = registry.get_target(strategy)?;
target.core = Box::new(core);
let session = Session::new(target, probe, None);
let session = Session::new(target, probe);
f(session)
}

2
cli/src/debugger.rs

@ -1,6 +1,6 @@
use crate::common::CliError;
use probe_rs::{collection::cores::CortexDump, debug::DebugInfo, memory::MI, session::Session};
use probe_rs::{cores::CortexDump, debug::DebugInfo, memory::MI, session::Session};
use capstone::Capstone;

12
cli/src/main.rs

@ -11,13 +11,12 @@ use probe_rs::{
probe::{
daplink,
debug_probe::DebugProbeInfo,
flash::download::{FileDownloader, Format},
flash::download::{download_file, Format},
stlink,
},
};
use capstone::{arch::arm::ArchMode, prelude::*, Capstone, Endian};
use colored::*;
use memmap;
use rustyline::Editor;
use structopt::StructOpt;
@ -130,11 +129,7 @@ fn main() {
};
if let Err(e) = cli_result {
if let CliError::TargetSelectionError(e) = e {
eprintln!(" {} {}", "Error".red().bold(), e);
} else {
eprintln!("Error processing command: {}", e);
}
eprintln!("Error processing command: {}", e);
std::process::exit(1);
}
}
@ -188,10 +183,9 @@ fn download_program_fast(shared_options: &SharedOptions, path: &str) -> Result<(
// Start timer.
// let instant = Instant::now();
let fd = FileDownloader::new();
let mm = session.target.memory_map.clone();
fd.download_file(&mut session, std::path::Path::new(&path), Format::Elf, &mm)?;
download_file(&mut session, std::path::Path::new(&path), Format::Elf, &mm)?;
Ok(())
})

25
probe-rs-targets/Cargo.toml

@ -1,25 +0,0 @@
[package]
name = "probe-rs-targets"
version = "0.2.0"
authors = ["Noah Hüsser <yatekii@yatekii.ch>", "Dominik Boehi <dominik.boehi@gmail.ch>"]
edition = "2018"
description = "A collection of on chip debugging tools to comminicate with ARM chips."
documentation = "https://docs.rs/probe-rs-targets/"
homepage = "https://github.com/probe-rs/probe-rs"
repository = "https://github.com/probe-rs/probe-rs"
readme = "../README.md"
categories = ["embedded", "hardware-support", "development-tools::debugging"]
keywords = ["embedded"]
license = "MIT OR Apache-2.0"
build = "build.rs"
[dependencies]
phf = { version = "0.7.24", default-features = false }
probe-rs = { path = "../probe-rs", version = "0.2.0" }
lazy_static = "1.4.0"
[build-dependencies]
quote = "1.0.2"
log = "0.4.6"
probe-rs = { path = "../probe-rs", version = "0.2.0" }

27
probe-rs-targets/algorithms/STM32F042.yaml

@ -1,27 +0,0 @@
load_address: 0x20000000
instructions: [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x49544853, 0x48546048, 0x20006048, 0xb5104770, 0x20344603, 0x60e04c4f, 0xbd102000, 0x20004601,
0xb5004770, 0x23002200, 0x6902484a, 0x40102080, 0xd1012880, 0xffe4f7ff, 0x4846bf00, 0x07d868c3,
0xd1fa0fc0, 0x69024843, 0x43022004, 0x61024841, 0x20406902, 0x483f4302, 0xbf006102, 0x68c3483d,
0x0fc007d8, 0x483bd1fa, 0x21046902, 0x43884610, 0x48384602, 0x20006102, 0xb510bd00, 0x22004603,
0x48342400, 0x20806902, 0x28804010, 0xf7ffd101, 0xbf00ffb7, 0x68c4482f, 0x0fc007e0, 0x482dd1fa,
0x20026902, 0x482b4302, 0x61436102, 0x20406902, 0x48284302, 0xbf006102, 0x68c44826, 0x0fc007e0,
0x4824d1fa, 0x21026902, 0x43884610, 0x48214602, 0x20006102, 0xb5f7bd10, 0x22004615, 0x27002600,
0x462c9b00, 0x6902481b, 0x40102080, 0xd1012880, 0xff86f7ff, 0x4817bf00, 0x07f068c6, 0xd1fa0fc0,
0x4814e01b, 0x20016902, 0x48124302, 0x88206102, 0xbf008018, 0x68c6480f, 0x0fc007f0, 0x8820d1fa,
0x42888819, 0x480bd006, 0x08526902, 0x61020052, 0xbdfe2001, 0x1ca41c9b, 0x98011c7f, 0x42b80840,
0x4804d8df, 0x08526902, 0x61020052, 0xe7f02000, 0x45670123, 0x40022000, 0xcdef89ab, 0x00000000,
]
pc_init: 0x2000002F
pc_uninit: null
pc_program_page: 0x200000F7
pc_erase_sector: 0x2000009B
pc_erase_all: 0x20000043
static_base: 0x200001A0
begin_stack: 0x20001000
begin_data: 0x20000400
page_buffers: [0x20000400, 0x20000800]
min_program_length: 2
analyzer_supported: true
analyzer_address: 0x20001400

27
probe-rs-targets/algorithms/STM32F429xI.yaml

@ -1,27 +0,0 @@
load_address: 0x20000000
instructions: [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x03004601, 0x28200e00, 0x0940d302, 0xe0051d00, 0xd3022810, 0x1cc00900, 0x0880e000, 0xd50102c9,
0x43082110, 0x48464770, 0x60414944, 0x60414945, 0x60012100, 0x22f068c1, 0x60c14311, 0x06806940,
0x4842d406, 0x60014940, 0x60412106, 0x60814940, 0x47702000, 0x6901483a, 0x43110542, 0x20006101,
0xb5304770, 0x69014836, 0x43212404, 0x69016101, 0x43290365, 0x69016101, 0x431103a2, 0x49356101,
0xe0004a32, 0x68c36011, 0xd4fb03db, 0x43a16901, 0x69016101, 0x610143a9, 0xbd302000, 0xf7ffb530,
0x4927ffaf, 0x23f068ca, 0x60ca431a, 0x610c2402, 0x06c0690a, 0x43020e00, 0x6908610a, 0x431003e2,
0x48246108, 0xe0004a21, 0x68cd6010, 0xd4fb03ed, 0x43a06908, 0x68c86108, 0x0f000600, 0x68c8d003,
0x60c84318, 0xbd302001, 0x4d15b570, 0x08891cc9, 0x008968eb, 0x433326f0, 0x230060eb, 0x4b16612b,
0x692ce017, 0x612c431c, 0x60046814, 0x03e468ec, 0x692cd4fc, 0x00640864, 0x68ec612c, 0x0f240624,
0x68e8d004, 0x60e84330, 0xbd702001, 0x1d121d00, 0x29001f09, 0x2000d1e5, 0x0000bd70, 0x45670123,
0x40023c00, 0xcdef89ab, 0x00005555, 0x40003000, 0x00000fff, 0x0000aaaa, 0x00000201, 0x00000000,
]
pc_init: 0x20000047
pc_uninit: 0x20000075
pc_program_page: 0x20000109
pc_erase_sector: 0x200000bd
pc_erase_all: 0x20000083
static_base: 0x20000171
begin_stack: 0x20000800
begin_data: 0x20001000
page_buffers: [0x20001000, 0x20002000]
min_program_length: 1
analyzer_supported: true
analyzer_address: 0x20002000

23
probe-rs-targets/algorithms/nRF51822.yaml

@ -1,23 +0,0 @@
load_address: 0x20000000
instructions: [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x47702000, 0x47702000, 0x4c26b570, 0x60602002, 0x60e02001, 0x68284d24, 0xd00207c0, 0x60602000,
0xf000bd70, 0xe7f6f82c, 0x4c1eb570, 0x60612102, 0x4288491e, 0x2001d302, 0xe0006160, 0x4d1a60a0,
0xf81df000, 0x07c06828, 0x2000d0fa, 0xbd706060, 0x4605b5f8, 0x4813088e, 0x46142101, 0x4f126041,
0xc501cc01, 0x07c06838, 0x1e76d006, 0x480dd1f8, 0x60412100, 0xbdf84608, 0xf801f000, 0x480ce7f2,
0x06006840, 0xd00b0e00, 0x6849490a, 0xd0072900, 0x4a0a4909, 0xd00007c3, 0x1d09600a, 0xd1f90840,
0x00004770, 0x4001e500, 0x4001e400, 0x10001000, 0x40010400, 0x40010500, 0x40010600, 0x6e524635,
0x00000000,
]
pc_init: 0x20000021
pc_uninit: null
pc_program_page: 0x20000071
pc_erase_sector: 0x20000049
pc_erase_all: 0x20000029
static_base: 0x20000170
begin_stack: 0x20001000
begin_data: 0x20002000
page_buffers: [0x20002000, 0x20002400]
min_program_length: 4
analyzer_supported: true
analyzer_address: 0x20003000

23
probe-rs-targets/algorithms/nRF52832.yaml

@ -1,23 +0,0 @@
load_address: 0x20000000
instructions: [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x47702000, 0x47702000, 0x4c26b570, 0x60602002, 0x60e02001, 0x68284d24, 0xd00207c0, 0x60602000,
0xf000bd70, 0xe7f6f82c, 0x4c1eb570, 0x60612102, 0x4288491e, 0x2001d302, 0xe0006160, 0x4d1a60a0,
0xf81df000, 0x07c06828, 0x2000d0fa, 0xbd706060, 0x4605b5f8, 0x4813088e, 0x46142101, 0x4f126041,
0xc501cc01, 0x07c06838, 0x1e76d006, 0x480dd1f8, 0x60412100, 0xbdf84608, 0xf801f000, 0x480ce7f2,
0x06006840, 0xd00b0e00, 0x6849490a, 0xd0072900, 0x4a0a4909, 0xd00007c3, 0x1d09600a, 0xd1f90840,
0x00004770, 0x4001e500, 0x4001e400, 0x10001000, 0x40010400, 0x40010500, 0x40010600, 0x6e524635,
0x00000000,
]
pc_init: 0x20000021
pc_uninit: null
pc_program_page: 0x20000071
pc_erase_sector: 0x20000049
pc_erase_all: 0x20000029
static_base: 0x20000170
begin_stack: 0x20001000
begin_data: 0x20002000
page_buffers: [0x20002000, 0x20003000]
min_program_length: 4
analyzer_supported: true
analyzer_address: 0x20004000

23
probe-rs-targets/algorithms/nRF52840.yaml

@ -1,23 +0,0 @@
load_address: 0x20000000
instructions: [
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x47702000, 0x47702000, 0x4c26b570, 0x60602002, 0x60e02001, 0x68284d24, 0xd00207c0, 0x60602000,
0xf000bd70, 0xe7f6f82c, 0x4c1eb570, 0x60612102, 0x4288491e, 0x2001d302, 0xe0006160, 0x4d1a60a0,
0xf81df000, 0x07c06828, 0x2000d0fa, 0xbd706060, 0x4605b5f8, 0x4813088e, 0x46142101, 0x4f126041,
0xc501cc01, 0x07c06838, 0x1e76d006, 0x480dd1f8, 0x60412100, 0xbdf84608, 0xf801f000, 0x480ce7f2,
0x06006840, 0xd00b0e00, 0x6849490a, 0xd0072900, 0x4a0a4909, 0xd00007c3, 0x1d09600a, 0xd1f90840,
0x00004770, 0x4001e500, 0x4001e400, 0x10001000, 0x40010400, 0x40010500, 0x40010600, 0x6e524635,
0x00000000,
]
pc_init: 0x20000021
pc_uninit: null
pc_program_page: 0x20000071
pc_erase_sector: 0x20000049
pc_erase_all: 0x20000029
static_base: 0x20000170
begin_stack: 0x20001000
begin_data: 0x20002000
page_buffers: [0x20002000, 0x20003000]
min_program_length: 4
analyzer_supported: true
analyzer_address: 0x20004000

118
probe-rs-targets/build.rs

@ -1,118 +0,0 @@
use std::env;
use std::fs::{read_dir, read_to_string, File};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use probe_rs::{probe::flash::FlashAlgorithm, target::Target};
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("targets.rs");
let mut f = File::create(&dest_path).unwrap();
// TARGETS
let mut files = vec![];
visit_dirs(Path::new("algorithms"), &mut files).unwrap();
let mut algorithm_names = vec![];
let mut algorithm_files = vec![];
let root_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
for file in files {
let string = read_to_string(&file).expect(
"Algorithm definition file could not be read. This is a bug. Please report it.",
);
match FlashAlgorithm::new(&string) {
Ok(_algorithm) => {
let abs_path = root_dir.join(&file);
algorithm_files.push(abs_path.to_str().unwrap().to_owned());
algorithm_names.push(
file.strip_prefix("algorithms")
.unwrap()
.to_str()
.expect("Non UTF-8 Filename!")
.to_owned(),
);
}
Err(e) => {
panic!("Failed to parse target file: {:?} because:\n{}", file, e);
}
}
}
dbg!(&algorithm_names);
dbg!(&algorithm_files);
// TARGETS
let mut files = vec![];
visit_dirs(Path::new("targets"), &mut files).unwrap();
let mut target_names = vec![];
let mut target_files = vec![];
for file in files {
let string = read_to_string(&file)
.expect("Chip definition file could not be read. This is a bug. Please report it.");
match Target::new(&string) {
Ok(target) => {
if let Some(algo) = target.flash_algorithm {
assert!(
algorithm_names.contains(&algo),
"Algorithm {} does not exist.",
algo
);
}
target_files.push(root_dir.join(file).to_str().unwrap().to_owned());
target_names.push(target.name.to_ascii_lowercase());
}
Err(e) => {
panic!("Failed to parse target file: {:?} because:\n{}", file, e);
}
}
}
dbg!(&target_names);
dbg!(&target_files);
let stream: String = format!(
"{}",
quote::quote! {
// START QUOTE
lazy_static::lazy_static! {
static ref FLASH_ALGORITHMS: HashMap<&'static str, &'static str> = vec![
#((#algorithm_names, include_str!(#algorithm_files)),)*
].into_iter().collect();
static ref TARGETS: HashMap<&'static str, &'static str> = vec![
#((#target_names, include_str!(#target_files)),)*
].into_iter().collect();
}
// END QUOTE
}
);
f.write_all(stream.as_bytes())
.expect("Writing build.rs output failed.");
}
// one possible implementation of walking a directory only visiting files
fn visit_dirs(dir: &Path, targets: &mut Vec<PathBuf>) -> io::Result<()> {
if dir.is_dir() {
for entry in read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, targets)?;
} else {
targets.push(path.to_owned());
}
}
}
Ok(())
}

70
probe-rs-targets/src/lib.rs

@ -1,70 +0,0 @@
use std::collections::HashMap;
use probe_rs::{
collection,
probe::flash::flasher::{AlgorithmSelectionError, FlashAlgorithm},
target::{info::ChipInfo, Target, TargetSelectionError},
};
include!(concat!(env!("OUT_DIR"), "/targets.rs"));
pub fn get_built_in_target(name: impl AsRef<str>) -> Result<Target, TargetSelectionError> {
let name = name.as_ref().to_string().to_ascii_lowercase();
TARGETS
.get(&name[..])
.ok_or(TargetSelectionError::TargetNotFound(name))
.and_then(|target| Target::new(target).map_err(From::from))
}
pub fn get_built_in_target_by_chip_id(chip_info: &ChipInfo) -> Option<Target> {
for target in TARGETS.values() {
let target = Target::new(target).unwrap();
if target.manufacturer == chip_info.manufacturer && target.part == chip_info.part {
return Some(target);
}
}
None
}
pub enum SelectionStrategy {
Name(String),
ChipInfo(ChipInfo),
}
pub fn select_target(strategy: &SelectionStrategy) -> Result<Target, TargetSelectionError> {
match strategy {
SelectionStrategy::Name(name) => match collection::get_target(name) {
Some(target) => Ok(target),
None => get_built_in_target(name),
},
SelectionStrategy::ChipInfo(chip_info) => get_built_in_target_by_chip_id(&chip_info)
.ok_or_else(|| {
TargetSelectionError::TargetNotFound(format!(
"No target info found for device: {}",
chip_info
))
}),
}
}
pub fn get_built_in_algorithm(
name: impl AsRef<str>,
) -> Result<FlashAlgorithm, AlgorithmSelectionError> {
let name = name.as_ref().to_string();
FLASH_ALGORITHMS
.get(&name[..])
.ok_or(AlgorithmSelectionError::AlgorithmNotFound(name))
.and_then(|definition| FlashAlgorithm::new(definition).map_err(From::from))
}
pub fn select_algorithm(name: impl AsRef<str>) -> Result<FlashAlgorithm, AlgorithmSelectionError> {
let algorithm = match collection::get_algorithm(name.as_ref()) {
Some(algorithm) => Some(algorithm),
None => None,
};
match algorithm {
Some(algorithm) => Ok(algorithm),
None => get_built_in_algorithm(name),
}
}

31
probe-rs-targets/targets/STM32F042.yaml

@ -1,31 +0,0 @@
name: "STM32F042"
# TODO: Manufacturer and Part are not correct yet. They are only needed for autodetection.
manufacturer:
cc: 0x00
id: 0x20
part: 0x1991
flash_algorithm: "STM32F042.yaml"
memory_map:
- Flash:
range:
start: 0x08000000
end: 0x08010000
is_boot_memory: true
is_testable: true
blocksize: 0x400
sector_size: 0x400
page_size: 0x400
phrase_size: 0x400
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Ram:
range:
start: 0x20000000
end: 0x20002000
is_boot_memory: false
is_testable: true
core: "M0"

32
probe-rs-targets/targets/STM32F429xI.yaml

@ -1,32 +0,0 @@
name: "STM32F429xI"
# TODO: Manufacturer and Part are not correct yet. They are only needed for autodetection.
manufacturer:
cc: 0x00
id: 0x20
part: 0x000411
flash_algorithm: "STM32F429xI.yaml"
memory_map:
- Flash:
range:
start: 0x08000000
end: 0x08010000
is_boot_memory: true
is_testable: true
blocksize: 0x4000
sector_size: 0x4000
page_size: 0x1000
phrase_size: 0x1000
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
# TODO: There is many more Flash areas.
- Ram:
range:
start: 0x20000000
end: 0x20030000
is_boot_memory: false
is_testable: true
core: "M0"

46
probe-rs-targets/targets/nRF51822.yaml

@ -1,46 +0,0 @@
name: "nRF51822"
manufacturer:
cc: 0x02
id: 0x44
part: 0x000001
flash_algorithm: "nRF51822.yaml"
memory_map:
- Flash:
range:
start: 0
end: 0x40000
is_boot_memory: true
is_testable: true
blocksize: 0x400
sector_size: 0x400
page_size: 0x400
phrase_size: 0x400
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Flash:
range:
start: 0x10001000
end: 0x10001100
is_boot_memory: false
is_testable: false
blocksize: 0x100
sector_size: 0x100
page_size: 0x100
phrase_size: 0x100
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Ram:
range:
start: 0x20000000
end: 0x20004000
is_boot_memory: false
is_testable: true
core: "M0"

46
probe-rs-targets/targets/nRF52832.yaml

@ -1,46 +0,0 @@
name: "nRF52832"
manufacturer:
cc: 0x02
id: 0x44
part: 0x000006
flash_algorithm: "nRF52832.yaml"
memory_map:
- Flash:
range:
start: 0
end: 0x80000
is_boot_memory: true
is_testable: true
blocksize: 0x1000
sector_size: 0x1000
page_size: 0x1000
phrase_size: 0x100
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Flash:
range:
start: 0x10001000
end: 0x10001100
is_boot_memory: false
is_testable: false
blocksize: 0x100
sector_size: 0x100
page_size: 0x100
phrase_size: 0x100
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Ram:
range:
start: 0x20000000
end: 0x20010000
is_boot_memory: false
is_testable: true
core: "M4"

47
probe-rs-targets/targets/nRF52840.yaml

@ -1,47 +0,0 @@
name: "nRF52840"
# TODO: Manufacturer and Part are not correct yet. They are only needed for autodetection.
manufacturer:
cc: 0x02
id: 0x44
part: 0x000008
flash_algorithm: "nRF52840.yaml"
memory_map:
- Flash:
range:
start: 0
end: 0x100000
is_boot_memory: true
is_testable: true
blocksize: 0x1000
sector_size: 0x1000
page_size: 0x1000
phrase_size: 0x1000
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Flash:
range:
start: 0x10001000
end: 0x10001100
is_boot_memory: false
is_testable: false
blocksize: 0x100
sector_size: 0x100
page_size: 0x100
phrase_size: 0x100
erase_all_weight: 0.174 # TODO: Replace with proper constant later.
erase_sector_weight: 0.048 # TODO: Replace with proper constant later.
program_page_weight: 0.130 # TODO: Replace with proper constant later.
erased_byte_value: 0xFF
access: 0b00000101 # TODO: Replace with proper constant later.
are_erased_sectors_readable: true
- Ram:
range:
start: 0x20000000
end: 0x20040000
is_boot_memory: false
is_testable: true
core: "M4"

8
probe-rs/Cargo.toml

@ -40,4 +40,10 @@ maplit = "1.0.2"
dirs = "2.0.2"
objekt = "0.1.2"
colored = "1.8.0"
includedir = "0.5.0"
includedir = "0.5.0"
[build-dependencies]
quote = "1.0.2"
log = "0.4.6"
serde_yaml = "0.8.11"
proc-macro2 = "1.0.4"

283
probe-rs/build.rs

@ -0,0 +1,283 @@
use std::env;
use std::fs::{read_dir, read_to_string, File};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("targets.rs");
let mut f = File::create(&dest_path).unwrap();
// Determine all config files to parse.
let mut files = vec![];
visit_dirs(Path::new("targets"), &mut files).unwrap();
let mut configs: Vec<proc_macro2::TokenStream> = vec![];
for file in files {
let string = read_to_string(&file).expect(
"Algorithm definition file could not be read. This is a bug. Please report it.",
);
let yaml: Result<serde_yaml::Value, _> = serde_yaml::from_str(&string);
match yaml {
Ok(chip) => {
let chip = extract_chip_family(&chip);
configs.push(chip);
}
Err(e) => {
panic!("Failed to parse target file: {:?} because:\n{}", file, e);
}
}
}
let stream: String = format!(
"{}",
quote::quote! {
vec![
#(#configs,)*
]
}
);
f.write_all(stream.as_bytes())
.expect("Writing build.rs output failed.");
}
// one possible implementation of walking a directory only visiting files
fn visit_dirs(dir: &Path, targets: &mut Vec<PathBuf>) -> io::Result<()> {
if dir.is_dir() {
for entry in read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, targets)?;
} else {
targets.push(path.to_owned());
}
}
}
Ok(())
}
/// Creates a properly quoted Option<T>` `TokenStream` from an `Option<T>`.
fn quote_option<T: quote::ToTokens>(option: Option<T>) -> proc_macro2::TokenStream {
if let Some(value) = option {
quote::quote! {
Some(#value)
}
} else {
quote::quote! {
None
}
}
}
/// Extracts a list of algorithm token streams from a yaml value.
fn extract_algorithms(chip: &serde_yaml::Value) -> Vec<proc_macro2::TokenStream> {
// Get an iterator over all the algorithms contained in the chip value obtained from the yaml file.
let algorithm_iter = chip
.get("flash_algorithms")
.unwrap()
.as_sequence()
.unwrap()
.iter();
algorithm_iter
.map(|algorithm| {
// Extract all values and form them into a struct.
let name = algorithm
.get("name")
.unwrap()
.as_str()
.unwrap()
.to_ascii_lowercase();
let description = algorithm
.get("description")
.unwrap()
.as_str()
.unwrap()
.to_ascii_lowercase();
let default = algorithm.get("default").unwrap().as_bool().unwrap();
let instructions = algorithm
.get("instructions")
.unwrap()
.as_sequence()
.unwrap()
.iter()
.map(|v| v.as_u64().unwrap() as u32);
let pc_init =
quote_option(algorithm.get("pc_init").unwrap().as_u64().map(|v| v as u32));
let pc_uninit = quote_option(
algorithm
.get("pc_uninit")
.unwrap()
.as_u64()
.map(|v| v as u32),
);
let pc_program_page =
algorithm.get("pc_program_page").unwrap().as_u64().unwrap() as u32;
let pc_erase_sector =
algorithm.get("pc_erase_sector").unwrap().as_u64().unwrap() as u32;
let pc_erase_all = quote_option(
algorithm
.get("pc_erase_all")
.unwrap()
.as_u64()
.map(|v| v as u32),
);
let data_section_offset = algorithm
.get("data_section_offset")
.unwrap()
.as_u64()
.unwrap() as u32;
// Quote the algorithm struct.
let algorithm = quote::quote! {
RawFlashAlgorithm {
name: #name.to_owned(),
description: #description.to_owned(),
default: #default,
instructions: vec![
#(#instructions,)*
],
pc_init: #pc_init,
pc_uninit: #pc_uninit,
pc_program_page: #pc_program_page,
pc_erase_sector: #pc_erase_sector,
pc_erase_all: #pc_erase_all,
data_section_offset: #data_section_offset,
}
};
algorithm
})
.collect()
}
/// Extracts a list of algorithm token streams from a yaml value.
fn extract_memory_map(chip: &serde_yaml::Value) -> Vec<proc_macro2::TokenStream> {
// Get an iterator over all the algorithms contained in the chip value obtained from the yaml file.
let memory_map_iter = chip
.get("memory_map")
.unwrap()
.as_sequence()
.unwrap()
.iter();
memory_map_iter
.filter_map(|memory_region| {
// Check if it's a RAM region. If yes, parse it into a TokenStream.
memory_region
.get("Ram")
.map(|region| {
let range = region.get("range").unwrap();
let start = range.get("start").unwrap().as_u64().unwrap() as u32;
let end = range.get("end").unwrap().as_u64().unwrap() as u32;
let is_boot_memory = region.get("is_boot_memory").unwrap().as_bool().unwrap();
quote::quote! {
MemoryRegion::Ram(RamRegion {
range: #start..#end,
is_boot_memory: #is_boot_memory,
})
}
})
.or_else(|| {
memory_region.get("Flash").map(|region| {
let range = region.get("range").unwrap();
let start = range.get("start").unwrap().as_u64().unwrap() as u32;
let end = range.get("end").unwrap().as_u64().unwrap() as u32;
let is_boot_memory =
region.get("is_boot_memory").unwrap().as_bool().unwrap();
let sector_size =
region.get("sector_size").unwrap().as_u64().unwrap() as u32;
let page_size = region.get("page_size").unwrap().as_u64().unwrap() as u32;
let erased_byte_value =
region.get("erased_byte_value").unwrap().as_u64().unwrap() as u8;
quote::quote! {
MemoryRegion::Flash(FlashRegion {
range: #start..#end,
is_boot_memory: #is_boot_memory,
sector_size: #sector_size,
page_size: #page_size,
erased_byte_value: #erased_byte_value,
})
}
})
})
})
.collect()
}
/// Extracts a list of algorithm token streams from a yaml value.
fn extract_variants(chip_family: &serde_yaml::Value) -> Vec<proc_macro2::TokenStream> {
// Get an iterator over all the algorithms contained in the chip value obtained from the yaml file.
let variants_iter = chip_family
.get("variants")
.unwrap()
.as_sequence()
.unwrap()
.iter();
variants_iter
.map(|variant| {
let name = variant.get("name").unwrap().as_str().unwrap();
// Extract all the memory regions into a Vec of TookenStreams.
let memory_map = extract_memory_map(&variant);
quote::quote! {
Chip {
name: #name.to_owned(),
memory_map: vec![
#(#memory_map,)*
],
}
}
})
.collect()
}
/// Extracts a chip family token stream from a yaml value.
fn extract_chip_family(chip: &serde_yaml::Value) -> proc_macro2::TokenStream {
// Extract all the algorithms into a Vec of TokenStreams.
let algorithms = extract_algorithms(&chip);
// Extract all the available variants into a Vec of TokenStreams.
let variants = extract_variants(&chip);
let name = chip
.get("name")
.unwrap()
.as_str()
.unwrap()
.to_ascii_lowercase();
let manufacturer = quote_option(chip.get("manufacturer").map(|v| v.as_str()));
let part = quote_option(chip.get("part").map(|v| v.as_str()));
let core = chip
.get("core")
.unwrap()
.as_str()
.unwrap()
.to_ascii_lowercase();
// Quote the chip.
let chip_family = quote::quote! {
ChipFamily {
name: #name.to_owned(),
manufacturer: #manufacturer,
part: #part,
flash_algorithms: vec![
#(#algorithms,)*
],
variants: vec![
#(#variants,)*
],
core: #core.to_owned(),
}
};
chip_family
}

20
probe-rs/src/collection/cores/mod.rs

@ -1,20 +0,0 @@
pub mod m0;
pub mod m33;
pub mod m4;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CortexDump {
pub regs: [u32; 16],
stack_addr: u32,
stack: Vec<u8>,
}
impl CortexDump {
pub fn new(stack_addr: u32, stack: Vec<u8>) -> CortexDump {
CortexDump {
regs: [0u32; 16],
stack_addr,
stack,
}
}
}

126
probe-rs/src/collection/mod.rs

@ -1,126 +0,0 @@
pub mod cores;
use std::collections::HashMap;
use std::fs::File;
use std::fs::{self, DirEntry};
use std::io;
use std::io::BufReader;
use std::path::Path;
use crate::probe::flash::flasher::FlashAlgorithm;
use crate::target::Core;
use crate::target::Target;
pub fn get_target(name: impl AsRef<str>) -> Option<Target> {
let mut map: HashMap<String, Target> = HashMap::new();
load_targets(
dirs::home_dir()
.map(|home| home.join(".config/probe-rs/targets"))
.as_ref()
.map(|path| path.as_path()),
&mut