From 1f882a75c59df1b4fae2be16c1c4b411c55d1d2d Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" <5425387+Ralim@users.noreply.github.com> Date: Thu, 9 May 2024 21:28:11 +1000 Subject: [PATCH] Wait for port (#22) * Create trivial serial port opener to handle waiting for a port * Stitch in new wait command * use PathBuf directly for file paths on disk * Bump version --- bestool/Cargo.lock | 2 +- bestool/Cargo.toml | 2 +- bestool/src/beslink/message.rs | 6 +- bestool/src/cmds/read_image.rs | 36 ++++---- bestool/src/cmds/serial_monitor.rs | 14 +-- bestool/src/cmds/write_image.rs | 55 ++++++------ bestool/src/cmds/write_image_then_monitor.rs | 89 ++++++++++---------- bestool/src/main.rs | 32 ++++--- bestool/src/serial_port_opener.rs | 26 ++++++ 9 files changed, 146 insertions(+), 116 deletions(-) create mode 100644 bestool/src/serial_port_opener.rs diff --git a/bestool/Cargo.lock b/bestool/Cargo.lock index 89028fd..7cf9ec9 100644 --- a/bestool/Cargo.lock +++ b/bestool/Cargo.lock @@ -62,7 +62,7 @@ dependencies = [ [[package]] name = "bestool" -version = "0.1.1" +version = "0.1.2" dependencies = [ "clap", "crc", diff --git a/bestool/Cargo.toml b/bestool/Cargo.toml index d5db8a2..31a5fe3 100644 --- a/bestool/Cargo.toml +++ b/bestool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bestool" -version = "0.1.1" +version = "0.1.2" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/bestool/src/beslink/message.rs b/bestool/src/beslink/message.rs index 6ff57b0..d0ea976 100644 --- a/bestool/src/beslink/message.rs +++ b/bestool/src/beslink/message.rs @@ -169,7 +169,7 @@ pub fn read_message(serial_port: &mut Box) -> Result Result<(), BESLinkError> { - let checksum = calculate_message_checksum(&packet[0..packet.len()-1]); + let checksum = calculate_message_checksum(&packet[0..packet.len() - 1]); if checksum == packet[packet.len() - 1] { return Ok(()); } @@ -275,7 +275,7 @@ mod tests { ], ]; for v in test_messages { - assert!(validate_packet_checksum(&v).is_ok()) - } + assert!(validate_packet_checksum(&v).is_ok()) + } } } diff --git a/bestool/src/cmds/read_image.rs b/bestool/src/cmds/read_image.rs index 16ee892..d2839cd 100644 --- a/bestool/src/cmds/read_image.rs +++ b/bestool/src/cmds/read_image.rs @@ -2,33 +2,39 @@ use crate::beslink::{ helper_sync_and_load_programmer, read_flash_data, send_device_reboot, BESLinkError, BES_PROGRAMMING_BAUDRATE, }; +use crate::serial_port_opener::open_serial_port_with_wait; use serialport::SerialPort; use std::fs::File; use std::io::prelude::*; +use std::path::PathBuf; use std::time::Duration; use tracing::error; use tracing::info; -pub fn cmd_read_image(input_file: String, serial_port: String, start: usize, length: usize) { +pub fn cmd_read_image( + input_file: &PathBuf, + port_name: &str, + start: usize, + length: usize, + wait_for_port: bool, +) { //First gain sync to the device - println!("Reading binary data from {serial_port} @ {BES_PROGRAMMING_BAUDRATE}"); - let mut serial_port = serialport::new(serial_port, BES_PROGRAMMING_BAUDRATE); - serial_port = serial_port.timeout(Duration::from_millis(5000)); + println!("Reading binary data from {port_name} @ {BES_PROGRAMMING_BAUDRATE}"); + let mut port = open_serial_port_with_wait(port_name, BES_PROGRAMMING_BAUDRATE, wait_for_port); + port.set_timeout(Duration::from_millis(5000)) + .expect("Cant set port timeout"); - match serial_port.open() { - Ok(mut port) => match do_read_flash_data(input_file, &mut port, start, length) { - Ok(_) => { - info!("Done..."); - } - Err(e) => { - error!("Failed {:?}", e); - } - }, - Err(e) => println!("Failed to open serial port - {e:?}"), + match do_read_flash_data(input_file, &mut port, start, length) { + Ok(_) => { + info!("Done..."); + } + Err(e) => { + error!("Failed {:?}", e); + } } } fn do_read_flash_data( - output_file_path: String, + output_file_path: &PathBuf, serial_port: &mut Box, start: usize, length: usize, diff --git a/bestool/src/cmds/serial_monitor.rs b/bestool/src/cmds/serial_monitor.rs index d881742..345b4d1 100644 --- a/bestool/src/cmds/serial_monitor.rs +++ b/bestool/src/cmds/serial_monitor.rs @@ -1,15 +1,9 @@ -use crate::serial_monitor::run_serial_monitor; +use crate::{serial_monitor::run_serial_monitor, serial_port_opener::open_serial_port_with_wait}; -pub fn cmd_serial_port_monitor(port_name: String, baud_rate: u32) { +pub fn cmd_serial_port_monitor(port_name: &str, baud_rate: u32, wait_for_port: bool) { // Span a basic serial port monitor attached to the serial port // Eventually we will hook in extra utility commands - println!("Opening serial monitor to {port_name} @ {baud_rate}"); - let serial_port = serialport::new(port_name, baud_rate); + let port = open_serial_port_with_wait(port_name, baud_rate, wait_for_port); - match serial_port.open() { - Ok(port) => { - let _ = run_serial_monitor(port); - } - Err(e) => println!("Failed to open serial port - {e:?}"), - } + run_serial_monitor(port).unwrap(); } diff --git a/bestool/src/cmds/write_image.rs b/bestool/src/cmds/write_image.rs index 52a1819..3d6f035 100644 --- a/bestool/src/cmds/write_image.rs +++ b/bestool/src/cmds/write_image.rs @@ -2,47 +2,44 @@ use crate::beslink::{ burn_image_to_flash, helper_sync_and_load_programmer, send_device_reboot, BESLinkError, BES_PROGRAMMING_BAUDRATE, }; +use crate::serial_port_opener::open_serial_port_with_wait; use serialport::{ClearBuffer, SerialPort}; use std::fs; - +use std::path::PathBuf; use std::time::Duration; use tracing::error; use tracing::info; -pub fn cmd_write_image(input_file: String, serial_port: String) { +pub fn cmd_write_image(input_file: &PathBuf, port_name: &str, wait_for_port: bool) { //First gain sync to the device - println!("Writing binary data to {serial_port} @ {BES_PROGRAMMING_BAUDRATE}"); - let mut serial_port = serialport::new(serial_port, BES_PROGRAMMING_BAUDRATE); - serial_port = serial_port.timeout(Duration::from_millis(5000)); + println!("Writing binary data to {port_name} @ {BES_PROGRAMMING_BAUDRATE}"); + let mut port = open_serial_port_with_wait(port_name, BES_PROGRAMMING_BAUDRATE, wait_for_port); + port.set_timeout(Duration::from_millis(5000)) + .expect("Cant set port timeout"); - match serial_port.open() { - Ok(mut port) => { - let _ = port.clear(ClearBuffer::All); - info!("Starting loader and checking communications"); - match helper_sync_and_load_programmer(&mut port) { - Ok(_) => { - info!("Done..."); - } - Err(e) => { - error!("Failed {:?}", e); - return; - } - } - info!("Now doing firmware load"); - match do_burn_image_to_flash(input_file, &mut port) { - Ok(_) => { - info!("Done..."); - } - Err(e) => { - error!("Failed {:?}", e); - } - } + let _ = port.clear(ClearBuffer::All); + info!("Starting loader and checking communications"); + match helper_sync_and_load_programmer(&mut port) { + Ok(_) => { + info!("Done..."); + } + Err(e) => { + error!("Failed {:?}", e); + return; + } + } + info!("Now doing firmware load"); + match do_burn_image_to_flash(input_file, &mut port) { + Ok(_) => { + info!("Done..."); + } + Err(e) => { + error!("Failed {:?}", e); } - Err(e) => println!("Failed to open serial port - {e:?}"), } } fn do_burn_image_to_flash( - input_file: String, + input_file: &PathBuf, serial_port: &mut Box, ) -> Result<(), BESLinkError> { // Open file, read file, call burn_image_to_flash diff --git a/bestool/src/cmds/write_image_then_monitor.rs b/bestool/src/cmds/write_image_then_monitor.rs index 553b591..0d2b276 100644 --- a/bestool/src/cmds/write_image_then_monitor.rs +++ b/bestool/src/cmds/write_image_then_monitor.rs @@ -3,71 +3,70 @@ use crate::beslink::{ BES_PROGRAMMING_BAUDRATE, }; use crate::serial_monitor::run_serial_monitor; +use crate::serial_port_opener::open_serial_port_with_wait; use serialport::{ClearBuffer, SerialPort}; use std::fs; +use std::path::PathBuf; use std::time::Duration; use tracing::error; use tracing::info; pub fn cmd_write_image_then_monitor( - input_file: String, - serial_port: String, + input_file_path: &PathBuf, + serial_port: &str, monitor_baud_rate: u32, + wait_for_port: bool, ) { //First gain sync to the device println!( "Writing binary data to {serial_port} @ {BES_PROGRAMMING_BAUDRATE}; then monitoring at {monitor_baud_rate}" ); - let mut serial_port = serialport::new(serial_port, BES_PROGRAMMING_BAUDRATE); - serial_port = serial_port.timeout(Duration::from_millis(5000)); + let mut port = open_serial_port_with_wait(serial_port, BES_PROGRAMMING_BAUDRATE, wait_for_port); + port.set_timeout(Duration::from_millis(5000)) + .expect("Cant set port timeout"); - match serial_port.open() { - Ok(mut port) => { - let _ = port.clear(ClearBuffer::All); - info!("Starting loader and checking communications"); - match helper_sync_and_load_programmer(&mut port) { - Ok(_) => { - info!("Done..."); - } - Err(e) => { - error!("Failed {:?}", e); - return; - } - } - info!("Now doing firmware load"); - match do_burn_image_to_flash(input_file, &mut port) { - Ok(_) => { - info!("Done..."); - } - Err(e) => { - error!("Failed {:?}", e); - return; - } - } - info!("Starting monitoring"); - match port.set_baud_rate(monitor_baud_rate) { - Ok(_) => { - info!("Done..."); - } - Err(e) => { - error!("Failed {:?}", e); - return; - } - } - match run_serial_monitor(port) { - Ok(_) => {} - Err(e) => { - error!("Failed monitoring: {:?}", e); - } - } + let _ = port.clear(ClearBuffer::All); + info!("Starting loader and checking communications"); + match helper_sync_and_load_programmer(&mut port) { + Ok(_) => { + info!("Done..."); + } + Err(e) => { + error!("Failed {:?}", e); + return; + } + } + info!("Now doing firmware load"); + match do_burn_image_to_flash(input_file_path, &mut port) { + Ok(_) => { + info!("Done..."); + } + Err(e) => { + error!("Failed {:?}", e); + return; + } + } + info!("Starting monitoring"); + match port.set_baud_rate(monitor_baud_rate) { + Ok(_) => { + info!("Done..."); + } + Err(e) => { + error!("Failed {:?}", e); + return; + } + } + match run_serial_monitor(port) { + Ok(_) => {} + Err(e) => { + error!("Failed monitoring: {:?}", e); } - Err(e) => println!("Failed to open serial port - {e:?}"), } } fn do_burn_image_to_flash( - input_file: String, + input_file: &PathBuf, serial_port: &mut Box, ) -> Result<(), BESLinkError> { // Open file, read file, call burn_image_to_flash diff --git a/bestool/src/main.rs b/bestool/src/main.rs index 60c17ab..32c30e3 100644 --- a/bestool/src/main.rs +++ b/bestool/src/main.rs @@ -1,6 +1,7 @@ mod beslink; mod cmds; mod serial_monitor; +mod serial_port_opener; use crate::cmds::{ cmd_list_serial_ports, cmd_read_image, cmd_serial_port_monitor, cmd_write_image, cmd_write_image_then_monitor, @@ -38,33 +39,41 @@ struct SerialMonitor { serial_port_path: String, #[arg(short, long, default_value_t = 2000000)] baud_rate: u32, + #[arg(short, long, default_value_t = false)] + wait: bool, } #[derive(clap::Args, Debug)] #[command(author, version, about, long_about = None)] struct WriteImage { - firmware_path: Option, + firmware_path: std::path::PathBuf, #[arg(short, long)] port: String, + #[arg(short, long, default_value_t = false)] + wait: bool, } #[derive(clap::Args, Debug)] #[command(author, version, about, long_about = None)] struct WriteImageThenMonitor { - firmware_path: Option, + firmware_path: std::path::PathBuf, #[arg(short, long)] port: String, #[arg(short, long, default_value_t = 2000000)] monitor_baud_rate: u32, + #[arg(short, long, default_value_t = false)] + wait: bool, } #[derive(clap::Args, Debug)] #[command(author, version, about, long_about = None)] struct ReadImage { - firmware_path: Option, + firmware_path: std::path::PathBuf, #[arg(short, long)] port: String, #[arg(short, long, default_value_t = 1024*1024*4)] // default to full flash length: u32, #[arg(short, long, default_value_t = 0)] // default to start of flash offset: u32, + #[arg(short, long, default_value_t = false)] + wait: bool, } fn main() { @@ -78,22 +87,21 @@ fn main() { match BesTool::parse() { BesTool::ListSerialPorts(_) => cmd_list_serial_ports(), BesTool::SerialMonitor(args) => { - cmd_serial_port_monitor(args.serial_port_path, args.baud_rate); + cmd_serial_port_monitor(&args.serial_port_path, args.baud_rate, args.wait); } - BesTool::WriteImage(args) => cmd_write_image( - args.firmware_path.unwrap().to_str().unwrap().to_owned(), - args.port, - ), + BesTool::WriteImage(args) => cmd_write_image(&args.firmware_path, &args.port, args.wait), BesTool::ReadImage(args) => cmd_read_image( - args.firmware_path.unwrap().to_str().unwrap().to_owned(), - args.port, + &args.firmware_path, + &args.port, args.offset as usize, args.length as usize, + args.wait, ), BesTool::WriteImageThenMonitor(args) => cmd_write_image_then_monitor( - args.firmware_path.unwrap().to_str().unwrap().to_owned(), - args.port, + &args.firmware_path, + &args.port, args.monitor_baud_rate, + args.wait, ), } } diff --git a/bestool/src/serial_port_opener.rs b/bestool/src/serial_port_opener.rs new file mode 100644 index 0000000..6f9e8ed --- /dev/null +++ b/bestool/src/serial_port_opener.rs @@ -0,0 +1,26 @@ +use std::time::Duration; + +use serialport::SerialPort; +use tracing::info; + +pub fn open_serial_port_with_wait( + port_path: &str, + baud_rate: u32, + wait_for_port: bool, +) -> Box { + // If wait for port is true, we handle it not being openable by retrying while waiting for it + info!("Opening {port_path} @ {baud_rate}"); + loop { + let serial_port = serialport::new(port_path, baud_rate); + match serial_port.open() { + Ok(port) => return port, + Err(_) => { + //Port didnt open + if !wait_for_port { + panic!("Unable to open requested Serial Port"); + } + } + } + std::thread::sleep(Duration::from_millis(250)); + } +}