Added functionality for running a command before flashing

This commit is contained in:
2025-09-19 17:50:52 +02:00
parent 1b9f1ea4c1
commit dd49c30ac9
4 changed files with 45 additions and 2 deletions

7
Cargo.lock generated
View File

@@ -222,6 +222,12 @@ dependencies = [
"windows",
]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.106"
@@ -253,6 +259,7 @@ dependencies = [
"pbr",
"serial2",
"serial_enumerator",
"shlex",
"termion",
]

View File

@@ -8,4 +8,5 @@ argp = "0.4.0"
pbr = "1.1.1"
serial2 = "0.2.32"
serial_enumerator = "0.2.12"
shlex = "1.3.0"
termion = "4.0.5"

View File

@@ -55,6 +55,10 @@ pub struct ArgWrite {
#[argp(description = "Path to the source Intel HEX file.")]
pub path: OsString,
#[argp(option)]
#[argp(description = "Command to run before writing the file. Handy for compiling the program and running it at the same time.")]
pub cmd: Option<OsString>,
#[argp(option, default = "0")]
#[argp(description = "Start address where to write from. Only for raw binaries, defaults to 0.")]
pub start: usize,

View File

@@ -1,3 +1,4 @@
use std::ffi::OsString;
use std::io::{Cursor, Error, Write};
use std::time::{Duration, SystemTime};
@@ -201,12 +202,35 @@ fn write_chip_data(args: &ArgWrite, target: &mut PhysicalTarget) -> Result<(), E
fn write_chip(args: ArgWrite, target: &mut PhysicalTarget) -> Result<(), Error> {
loop {
if let Some(cmd) = args.cmd.as_ref() {
let mut args = shlex::bytes::split(cmd.as_encoded_bytes())
.ok_or(Error::other("Error parsing commandline arguments"))?
.into_iter()
.map(|x| unsafe { OsString::from_encoded_bytes_unchecked(x) });
let Some(name) = args.next() else {
Err(Error::other("No command provided"))?
};
let out = std::process::Command::new(name)
.args(args)
.output()?;
if !out.status.success() {
Err(Error::other(format!("Command failed with exit code {}:\n\n{}",
out.status.code().unwrap_or(1),
String::from_utf8_lossy(&out.stderr))))?
}
println!("Command `{}` successful.", cmd.to_string_lossy());
}
write_chip_data(&args, target)?;
if !args.monitor { break }
let cause = Monitor::new()
.add_hook(Key::Ctrl('f'), "Re-flash target")
.add_hook(Key::Ctrl('f'), if args.cmd.is_none() { "Re-flash target" } else { "Re-run command and flash target" })
.run(target.port())?;
if cause != Key::Ctrl('f') { break }
@@ -241,7 +265,13 @@ fn main() {
}
None
}).unwrap();
});
let Some(port) = port else {
println!("Could not find any compatible serial port. Please make sure that the target is connected.");
println!("If the issue persists, please specify the port manually with the `--port ...` argument.");
std::process::exit(1);
};
let mut target = PhysicalTarget::init(port, if args.slow { 57600 } else { 312500 }).unwrap();
@@ -254,6 +284,7 @@ fn main() {
if let Err(err) = res {
println!("An error occured during the operation: {}", err);
std::process::exit(1);
}
let end = SystemTime::now();