diff --git a/Cargo.lock b/Cargo.lock index d46dd3f..5baf8b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,24 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "CoreFoundation-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "mach 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "IOKit-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "CoreFoundation-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "mach 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aho-corasick" version = "0.7.10" @@ -119,6 +138,11 @@ name = "byteorder" version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cc" +version = "1.0.54" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "cfg-if" version = "0.1.10" @@ -206,6 +230,7 @@ dependencies = [ "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)", + "serialport 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -314,6 +339,24 @@ name = "libc" version = "0.2.70" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "libudev" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "libudev-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.4.8" @@ -322,6 +365,22 @@ dependencies = [ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mach" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mach" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "maplit" version = "1.0.2" @@ -332,6 +391,18 @@ name = "memchr" version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "nix" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)", + "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "opaque-debug" version = "0.2.3" @@ -376,6 +447,11 @@ dependencies = [ "sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "pkg-config" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ppv-lite86" version = "0.2.6" @@ -575,6 +651,22 @@ dependencies = [ "serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serialport" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "CoreFoundation-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "IOKit-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "sha-1" version = "0.8.2" @@ -759,6 +851,11 @@ name = "version_check" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "walkdir" version = "2.3.1" @@ -802,6 +899,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] +"checksum CoreFoundation-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e9889e6db118d49d88d84728d0e964d973a5680befb5f85f55141beea5c20b" +"checksum IOKit-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "99696c398cbaf669d2368076bdb3d627fb0ce51a26899d7c61228c5c0af3bf4a" "checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" @@ -819,6 +918,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum bstr 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "31accafdb70df7871592c058eca3985b71104e15ac32f64706022c58867da931" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +"checksum cc 1.0.54 (registry+https://github.com/rust-lang/crates.io-index)" = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" "checksum constant_time_eq 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" @@ -839,14 +939,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +"checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe" +"checksum libudev-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +"checksum mach 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9" +"checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" "checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" "checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" +"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum pest 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" "checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" "checksum pest_generator 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" "checksum pest_meta 2.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" "checksum proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" @@ -870,6 +976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)" = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" "checksum serde_derive 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)" = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984" "checksum serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)" = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" +"checksum serialport 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8d3ecaf58010bedccae17be55d4ed6f2ecde5646fc48ce8c66ea2d35a1419c" "checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" "checksum signal-hook 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff2db2112d6c761e12522c65f7768548bd6e8cd23d2a9dae162520626629bd6" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" @@ -893,6 +1000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" diff --git a/Cargo.toml b/Cargo.toml index 0cf3c1c..913842d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ prettytable-rs = "0.8" regex = "1" serde = { version = "1", features = ["derive"] } serde_json = "1" +serialport = "3.3" signal-hook = "0.1" structopt = "0.3" tempfile = "3" diff --git a/src/log/mod.rs b/src/log/mod.rs index f0ee490..e724ebb 100644 --- a/src/log/mod.rs +++ b/src/log/mod.rs @@ -9,10 +9,8 @@ pub use self::output::{Output, OutputMap, OutputStream}; use anyhow::Result; use std::{ - fs::File, - io::prelude::*, + io::Read, ops::{Generator, GeneratorState}, - path::PathBuf, pin::Pin, thread, }; @@ -20,10 +18,9 @@ use std::{ type ParserFn = fn(&[Output]) -> Pin> + '_>>; /// Runs log capture thread. -pub fn capture(input: PathBuf, outputs: Vec, parser: ParserFn) { +pub fn capture(input: Box, outputs: Vec, parser: ParserFn) { thread::spawn(move || { (|| -> Result<()> { - let input = File::open(input)?; let mut parser = Box::pin(parser(&outputs)); for byte in input.bytes() { let byte = byte?; diff --git a/src/probe/bmp.rs b/src/probe/bmp.rs index 92e31e1..aeb8126 100644 --- a/src/probe/bmp.rs +++ b/src/probe/bmp.rs @@ -80,9 +80,9 @@ pub fn log_swo_serial( let mut gdb = spawn_command(gdb_script_command(&config, None, script.path()))?; let (pipe, packet) = gdb_script_wait(&signals, pipe)?; - setup_serial_endpoint(&signals, serial_endpoint, config_log_swo.baud_rate)?; - exhaust_fifo(serial_endpoint)?; - log::capture(serial_endpoint.into(), log::Output::open_all(&outputs)?, log::swo::parser); + let port = setup_serial_endpoint(serial_endpoint, config_log_swo.baud_rate)?; + exhaust_fifo(&port)?; + log::capture(port, log::Output::open_all(&outputs)?, log::swo::parser); begin_log_output(color); gdb_script_continue(&signals, pipe, packet)?; diff --git a/src/probe/jlink.rs b/src/probe/jlink.rs index 16090f8..a1d38ad 100644 --- a/src/probe/jlink.rs +++ b/src/probe/jlink.rs @@ -111,13 +111,9 @@ pub fn log_dso_serial( let mut gdb = spawn_command(gdb_script_command(&config, None, script.path()))?; let (pipe, packet) = gdb_script_wait(&signals, pipe)?; - setup_serial_endpoint(&signals, &config_log_dso.serial_endpoint, config_log_dso.baud_rate)?; - exhaust_fifo(&config_log_dso.serial_endpoint)?; - log::capture( - config_log_dso.serial_endpoint.clone().into(), - log::Output::open_all(&outputs)?, - log::dso::parser, - ); + let port = setup_serial_endpoint(&config_log_dso.serial_endpoint, config_log_dso.baud_rate)?; + exhaust_fifo(&port)?; + log::capture(port, log::Output::open_all(&outputs)?, log::dso::parser); begin_log_output(color); gdb_script_continue(&signals, pipe, packet)?; diff --git a/src/probe/mod.rs b/src/probe/mod.rs index 9dca8c0..848b084 100644 --- a/src/probe/mod.rs +++ b/src/probe/mod.rs @@ -14,6 +14,7 @@ use ansi_term::Color::Cyan; use anyhow::{anyhow, bail, Error, Result}; use drone_config as config; use serde::{Deserialize, Serialize}; +use serialport::{posix::TTYPort, SerialPortSettings}; use signal_hook::iterator::Signals; use std::{ convert::TryFrom, @@ -23,6 +24,7 @@ use std::{ path::{Path, PathBuf}, process::{Command, Stdio}, thread, + time::Duration, }; /// An `enum` of all supported debug probes. @@ -136,14 +138,12 @@ pub fn log(probe: Probe, log: Log) -> Option { } } -/// Configures the endpoint with `stty` command. -pub fn setup_serial_endpoint(signals: &Signals, endpoint: &str, baud_rate: u32) -> Result<()> { - let mut stty = Command::new("stty"); - stty.arg(format!("--file={}", endpoint)); - stty.arg("speed"); - stty.arg(format!("{}", baud_rate)); - stty.arg("raw"); - block_with_signals(signals, true, || run_command(stty)) +/// Opens and configures the serial port endpoint. +pub fn setup_serial_endpoint(endpoint: &str, baud_rate: u32) -> Result> { + let mut settings: SerialPortSettings = Default::default(); + settings.baud_rate = baud_rate; + settings.timeout = Duration::new(10, 0); + Ok(Box::new(TTYPort::open(Path::new(endpoint), &settings)?)) } /// Runs a GDB server. diff --git a/src/probe/openocd.rs b/src/probe/openocd.rs index 0912630..c9e3629 100644 --- a/src/probe/openocd.rs +++ b/src/probe/openocd.rs @@ -14,7 +14,7 @@ use crate::{ use anyhow::Result; use drone_config as config; use signal_hook::iterator::Signals; -use std::process::Command; +use std::{fs::File, io::Read, process::Command}; use tempfile::tempdir_in; /// Runs `drone reset` command. @@ -97,16 +97,17 @@ pub fn log_swo( let dir = tempdir_in(temp_dir())?; let pipe = make_fifo(&dir, "pipe")?; let ports = outputs.iter().flat_map(|output| output.ports.iter().copied()).collect(); - let input; + let input: Box; let script; if let Some(serial_endpoint) = &config_log_swo.serial_endpoint { - setup_serial_endpoint(&signals, serial_endpoint, config_log_swo.baud_rate)?; - exhaust_fifo(serial_endpoint)?; - input = serial_endpoint.into(); + let port = setup_serial_endpoint(serial_endpoint, config_log_swo.baud_rate)?; + exhaust_fifo(&port)?; + input = port; script = registry.openocd_swo(&config, &ports, reset, &pipe, None)?; } else { - input = make_fifo(&dir, "input")?; - script = registry.openocd_swo(&config, &ports, reset, &pipe, Some(&input))?; + let fifo_name = make_fifo(&dir, "input")?; + script = registry.openocd_swo(&config, &ports, reset, &pipe, Some(&fifo_name))?; + input = Box::new(File::open(fifo_name)?); } log::capture(input, log::Output::open_all(&outputs)?, log::swo::parser); let mut gdb = spawn_command(gdb_script_command(&config, None, script.path()))?; diff --git a/src/utils.rs b/src/utils.rs index 927bf46..23634fe 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -4,13 +4,18 @@ use crate::color::Color; use ansi_term::Color::Red; use anyhow::{bail, Result}; use serde::{de, ser}; +use serialport::posix::TTYPort; use signal_hook::{iterator::Signals, SIGINT, SIGQUIT, SIGTERM}; use std::{ env, ffi::CString, - fs::OpenOptions, + fs::File, io::{prelude::*, ErrorKind}, - os::unix::{ffi::OsStrExt, io::AsRawFd, process::CommandExt}, + os::unix::{ + ffi::OsStrExt, + io::{AsRawFd, FromRawFd}, + process::CommandExt, + }, path::PathBuf, process::{exit, Child, Command}, sync::mpsc::{channel, RecvTimeoutError}, @@ -120,9 +125,13 @@ pub fn make_fifo(dir: &TempDir, name: &str) -> Result { } /// Consumes all remaining data in the fifo. -pub fn exhaust_fifo(path: &str) -> Result<()> { - let mut fifo = OpenOptions::new().read(true).open(path)?; - unsafe { libc::fcntl(fifo.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK) }; +pub fn exhaust_fifo(port: &TTYPort) -> Result<()> { + let mut fifo; + unsafe { + let fifo_fd = libc::dup(port.as_raw_fd()); + libc::fcntl(fifo_fd, libc::F_SETFL, libc::O_NONBLOCK); + fifo = File::from_raw_fd(fifo_fd); + } let mut bytes = [0_u8; 1024]; loop { match fifo.read(&mut bytes) {