diff --git a/.cargo/config b/.cargo/config index 8b2fc36..64a3068 100644 --- a/.cargo/config +++ b/.cargo/config @@ -2,7 +2,7 @@ rustflags = [ "-C", "link-arg=--nmagic", - "-C", "link-arg=-Tlink.x", + "-C", "link-arg=-Tlink_generated.x", # Code-size optimizations. "-C", "inline-threshold=5", diff --git a/Cargo.toml b/Cargo.toml index 6a8e4e8..9322b64 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,11 @@ flash-algorithm = { version = "0.4.0", default-features = false, features = [ "panic-handler", ] } +[features] +# Keep extra metadata in the final binary that probe-rs doesn't strictly need. +# Other tools use of these datastructures: probe-rs' target-gen, pyocd, jlink +cmsis-pack-compat = [] + # this lets you use `cargo fix`! [[bin]] name = "flash-algo" diff --git a/build.rs b/build.rs index 3a610c9..d63575d 100644 --- a/build.rs +++ b/build.rs @@ -1,21 +1,41 @@ use std::env; use std::fs::File; use std::io::Write; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; fn main() { // Put `link.x` in our output directory and ensure it's // on the linker search path. let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); - File::create(out.join("link.x")) + + println!("cargo:rustc-link-search={}", out.display()); + + // Call another function to copy the linker script into the output directory. + // This allows us to use a different linker script based on whether the + // cmsis-pack-compat feature is enabled or not + setup_linker_script(out); +} + +#[cfg(not(feature = "cmsis-pack-compat"))] +fn setup_linker_script(out: &Path) { + // rename the linker output to ensure we use the one in the + // build output instead of the one in the project root + File::create(out.join("link_generated.x")) .unwrap() .write_all(include_bytes!("link.x")) .unwrap(); - println!("cargo:rustc-link-search={}", out.display()); - // By default, Cargo will re-run a build script whenever // any file in the project changes. By specifying `link.x` // here, we ensure the build script is only re-run when // `link.x` is changed. println!("cargo:rerun-if-changed=link.x"); } + +#[cfg(feature = "cmsis-pack-compat")] +fn setup_linker_script(out: &Path) { + File::create(out.join("link_generated.x")) + .unwrap() + .write_all(include_bytes!("link_metadata.x")) + .unwrap(); + println!("cargo:rerun-if-changed=link_metadata.x"); +} diff --git a/build_w_metadata.sh b/build_w_metadata.sh new file mode 100755 index 0000000..f314b92 --- /dev/null +++ b/build_w_metadata.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -euo pipefail + +# macOS base64 doesn't take -w argument and defaults to a single line. +if [[ $(uname) = "Darwin" ]]; then + BASE64_FLAGS="" +else + BASE64_FLAGS="-w0" +fi + +cargo build --release --features cmsis-pack-compat +ELF=target/thumbv6m-none-eabi/release/flash-algo + +rust-objdump --disassemble $ELF > target/disassembly.s +rust-objdump -x $ELF > target/dump.txt +rust-nm $ELF -n > target/nm.txt + +function bin { + rust-objcopy $ELF -O binary - | base64 $BASE64_FLAGS +} + +function sym { + echo $((0x$(rust-nm $ELF | grep -w $1 | cut -d ' ' -f 1) + 1)) +} + +cat <