Skip to content

Commit da99a6d

Browse files
Improve monitoring (#737)
* feat: Make non-interactive available in other commands * feat: Use monitor_args in monitor() * feat: Move elf arg to MonitorConfigArgs * docs: Udpate changelog * docs: Update readmes * feat: Use parse_u32 * tests: Add espflash flash --monitor tests * feat: Allow underscores in parse_u32
1 parent 4ee4b59 commit da99a6d

File tree

8 files changed

+86
-81
lines changed

8 files changed

+86
-81
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- Add `non-interactive` flag to `flash` subcommand (#737)
12+
- Add `no-reset` flag to `monitor` subcommands (#737)
13+
- Add an environment variable to set monitoring baudrate (`MONITOR_BAUD`) (#737)
1114

1215
### Changed
16+
- Split the baudrate for connecting and monitorinig in `flash` subcommand (#737)
1317

1418
### Fixed
1519

cargo-espflash/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, and **ES
1818
- [Windows Subsystem for Linux](#windows-subsystem-for-linux)
1919
- [Bootloader and Partition Table](#bootloader-and-partition-table)
2020
- [Configuration File](#configuration-file)
21-
- [Configuration precedence](#configuration-precedence)
21+
- [Configuration Precedence](#configuration-precedence)
2222
- [Logging Format](#logging-format)
2323
- [License](#license)
2424
- [Contribution](#contribution)
@@ -143,9 +143,9 @@ You can have a local and/or a global configuration file:
143143
- macOS: `$HOME/Library/Application Support/rs.esp.espflash/espflash.toml`
144144
- Windows: `%APPDATA%\esp\espflash\espflash.toml`
145145

146-
### Configuration precedence
146+
### Configuration Precedence
147147

148-
1. Environment variables: If `ESPFLASH_PORT` or `ESPFLASH_BAUD` are set, the will be used instead of the config file value.
148+
1. Environment variables: If `ESPFLASH_PORT`, `MONITOR_BAUD` or `ESPFLASH_BAUD` are set, the will be used instead of the config file value.
149149
2. Local configuration file
150150
3. Global configuration file
151151

cargo-espflash/src/main.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -346,25 +346,20 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
346346

347347
if args.flash_args.monitor {
348348
let pid = flasher.get_usb_pid()?;
349+
let mut monitor_args = args.flash_args.monitor_args;
349350

350351
// The 26MHz ESP32-C2's need to be treated as a special case.
351-
let default_baud = if chip == Chip::Esp32c2 && target_xtal_freq == XtalFrequency::_26Mhz {
352+
if chip == Chip::Esp32c2
353+
&& target_xtal_freq == XtalFrequency::_26Mhz
354+
&& monitor_args.baud_rate == 115_200
355+
{
352356
// 115_200 * 26 MHz / 40 MHz = 74_880
353-
74_880
354-
} else {
355-
115_200
356-
};
357-
358-
monitor(
359-
flasher.into_serial(),
360-
Some(&elf_data),
361-
pid,
362-
args.flash_args.monitor_baud.unwrap_or(default_baud),
363-
args.flash_args.log_format,
364-
true,
365-
args.flash_args.processors,
366-
Some(build_ctx.artifact_path),
367-
)
357+
monitor_args.baud_rate = 74_880;
358+
}
359+
360+
monitor_args.elf = Some(build_ctx.artifact_path);
361+
362+
monitor(flasher.into_serial(), Some(&elf_data), pid, monitor_args)
368363
} else {
369364
Ok(())
370365
}

espflash/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, and **ES
2020
- [Cargo Runner](#cargo-runner)
2121
- [Using `espflash` as a Library](#using-espflash-as-a-library)
2222
- [Configuration File](#configuration-file)
23-
- [Configuration precedence](#configuration-precedence)
23+
- [Configuration Precedence](#configuration-precedence)
2424
- [Logging Format](#logging-format)
2525
- [License](#license)
2626
- [Contribution](#contribution)
@@ -157,9 +157,9 @@ You can have a local and/or a global configuration file:
157157
- macOS: `$HOME/Library/Application Support/rs.esp.espflash/espflash.toml`
158158
- Windows: `%APPDATA%\esp\espflash\espflash.toml`
159159

160-
### Configuration precedence
160+
### Configuration Precedence
161161

162-
1. Environment variables: If `ESPFLASH_PORT` or `ESPFLASH_BAUD` are set, the will be used instead of the config file value.
162+
1. Environment variables: If `ESPFLASH_PORT`, `MONITOR_BAUD` or `ESPFLASH_BAUD` are set, the will be used instead of the config file value.
163163
2. Local configuration file
164164
3. Global configuration file
165165

espflash/src/bin/espflash.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -280,25 +280,20 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
280280

281281
if args.flash_args.monitor {
282282
let pid = flasher.get_usb_pid()?;
283+
let mut monitor_args = args.flash_args.monitor_args;
283284

284285
// The 26MHz ESP32-C2's need to be treated as a special case.
285-
let default_baud = if chip == Chip::Esp32c2 && target_xtal_freq == XtalFrequency::_26Mhz {
286+
if chip == Chip::Esp32c2
287+
&& target_xtal_freq == XtalFrequency::_26Mhz
288+
&& monitor_args.baud_rate == 115_200
289+
{
286290
// 115_200 * 26 MHz / 40 MHz = 74_880
287-
74_880
288-
} else {
289-
115_200
290-
};
291-
292-
monitor(
293-
flasher.into_serial(),
294-
Some(&elf_data),
295-
pid,
296-
args.flash_args.monitor_baud.unwrap_or(default_baud),
297-
args.flash_args.log_format,
298-
true,
299-
args.flash_args.processors,
300-
Some(args.image),
301-
)
291+
monitor_args.baud_rate = 74_880;
292+
}
293+
294+
monitor_args.elf = Some(args.image);
295+
296+
monitor(flasher.into_serial(), Some(&elf_data), pid, monitor_args)
302297
} else {
303298
Ok(())
304299
}

espflash/src/cli/mod.rs

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,12 @@ pub struct FlashArgs {
142142
/// Erase specified data partitions
143143
#[arg(long, value_name = "PARTS", value_enum, value_delimiter = ',')]
144144
pub erase_data_parts: Option<Vec<DataType>>,
145-
/// Logging format.
146-
#[arg(long, short = 'L', default_value = "serial", requires = "monitor")]
147-
pub log_format: LogFormat,
148145
/// Open a serial monitor after flashing
149146
#[arg(short = 'M', long)]
150147
pub monitor: bool,
151-
/// Baud rate at which to read console output
152-
#[arg(long, requires = "monitor", value_name = "BAUD")]
153-
pub monitor_baud: Option<u32>,
148+
/// Monitor configuration
149+
#[clap(flatten)]
150+
pub monitor_args: MonitorConfigArgs,
154151
/// Load the application to RAM instead of Flash
155152
#[arg(long)]
156153
pub ram: bool,
@@ -162,9 +159,6 @@ pub struct FlashArgs {
162159
pub no_skip: bool,
163160
#[clap(flatten)]
164161
pub image: ImageArgs,
165-
/// External log processors to use (comma separated executables)
166-
#[arg(long, requires = "monitor")]
167-
pub processors: Option<String>,
168162
}
169163

170164
/// Operations for partitions tables
@@ -255,22 +249,36 @@ pub struct ImageArgs {
255249
pub min_chip_rev: u16,
256250
}
257251

258-
/// Open the serial monitor without flashing
259252
#[derive(Debug, Args)]
260253
#[non_exhaustive]
261254
pub struct MonitorArgs {
262255
/// Connection configuration
263256
#[clap(flatten)]
264257
connect_args: ConnectArgs,
265-
/// Optional file name of the ELF image to load the symbols from
258+
/// Monitoring arguments
259+
#[clap(flatten)]
260+
monitor_args: MonitorConfigArgs,
261+
}
262+
263+
/// Open the serial monitor without flashing
264+
#[derive(Debug, Args)]
265+
#[non_exhaustive]
266+
pub struct MonitorConfigArgs {
267+
/// Baud rate at which to communicate with target device
268+
#[arg(short = 'r', long, env = "MONITOR_BAUD", default_value = "115_200", value_parser = parse_u32)]
269+
pub baud_rate: u32,
270+
/// File name of the ELF image to load the symbols from
266271
#[arg(short = 'e', long, value_name = "FILE")]
267-
elf: Option<PathBuf>,
272+
pub elf: Option<PathBuf>,
268273
/// Avoids asking the user for interactions like resetting the device
269274
#[arg(long)]
270275
non_interactive: bool,
276+
/// Avoids restarting the device before monitoring
277+
#[arg(long, requires = "non_interactive")]
278+
no_reset: bool,
271279
/// Logging format.
272280
#[arg(long, short = 'L', default_value = "serial", requires = "elf")]
273-
pub log_format: LogFormat,
281+
log_format: LogFormat,
274282
/// External log processors to use (comma separated executables)
275283
#[arg(long)]
276284
processors: Option<String>,
@@ -292,6 +300,7 @@ pub struct ChecksumMd5Args {
292300

293301
/// Parses an integer, in base-10 or hexadecimal format, into a [u32]
294302
pub fn parse_u32(input: &str) -> Result<u32, ParseIntError> {
303+
let input: &str = &input.replace('_', "");
295304
let (s, radix) = if input.len() > 2 && matches!(&input[0..2], "0x" | "0X") {
296305
(&input[2..], 16)
297306
} else {
@@ -437,7 +446,7 @@ pub fn serial_monitor(args: MonitorArgs, config: &Config) -> Result<()> {
437446
let mut flasher = connect(&args.connect_args, config, true, true)?;
438447
let pid = flasher.get_usb_pid()?;
439448

440-
let elf = if let Some(elf_path) = args.elf.clone() {
449+
let elf = if let Some(elf_path) = args.monitor_args.elf.clone() {
441450
let path = fs::canonicalize(elf_path).into_diagnostic()?;
442451
let data = fs::read(path).into_diagnostic()?;
443452

@@ -449,26 +458,18 @@ pub fn serial_monitor(args: MonitorArgs, config: &Config) -> Result<()> {
449458
let chip = flasher.chip();
450459
let target = chip.into_target();
451460

461+
let mut monitor_args = args.monitor_args;
462+
452463
// The 26MHz ESP32-C2's need to be treated as a special case.
453-
let default_baud = if chip == Chip::Esp32c2
464+
if chip == Chip::Esp32c2
454465
&& target.crystal_freq(flasher.connection())? == XtalFrequency::_26Mhz
466+
&& monitor_args.baud_rate == 115_200
455467
{
456468
// 115_200 * 26 MHz / 40 MHz = 74_880
457-
74_880
458-
} else {
459-
115_200
460-
};
469+
monitor_args.baud_rate = 74_880;
470+
}
461471

462-
monitor(
463-
flasher.into_serial(),
464-
elf.as_deref(),
465-
pid,
466-
args.connect_args.baud.unwrap_or(default_baud),
467-
args.log_format,
468-
!args.non_interactive,
469-
args.processors,
470-
args.elf,
471-
)
472+
monitor(flasher.into_serial(), elf.as_deref(), pid, monitor_args)
472473
}
473474

474475
/// Convert the provided firmware image from ELF to binary
@@ -892,6 +893,9 @@ mod test {
892893
// Decimal
893894
assert_eq!(parse_u32("1234"), Ok(1234));
894895
assert_eq!(parse_u32("0"), Ok(0));
896+
// Underscores
897+
assert_eq!(parse_u32("12_34"), Ok(1234));
898+
assert_eq!(parse_u32("0X12_34"), Ok(0x1234));
895899
// Errors
896900
assert!(parse_u32("").is_err());
897901
assert!(parse_u32("0x").is_err());

espflash/src/cli/monitor/mod.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
1313
use std::{
1414
io::{stdout, ErrorKind, Read, Write},
15-
path::PathBuf,
1615
time::Duration,
1716
};
1817

@@ -21,14 +20,17 @@ use crossterm::{
2120
terminal::{disable_raw_mode, enable_raw_mode},
2221
};
2322
use external_processors::ExternalProcessors;
24-
use log::error;
23+
use log::{debug, error};
2524
use miette::{IntoDiagnostic, Result};
2625
#[cfg(feature = "serialport")]
2726
use serialport::SerialPort;
2827
use strum::{Display, EnumIter, EnumString, VariantNames};
2928

3029
use crate::{
31-
cli::monitor::parser::{InputParser, ResolvingPrinter},
30+
cli::{
31+
monitor::parser::{InputParser, ResolvingPrinter},
32+
MonitorConfigArgs,
33+
},
3234
connection::{reset::reset_after_flash, Port},
3335
};
3436

@@ -74,21 +76,20 @@ pub fn monitor(
7476
mut serial: Port,
7577
elf: Option<&[u8]>,
7678
pid: u16,
77-
baud: u32,
78-
log_format: LogFormat,
79-
interactive_mode: bool,
80-
processors: Option<String>,
81-
elf_file: Option<PathBuf>,
79+
monitor_args: MonitorConfigArgs,
8280
) -> miette::Result<()> {
83-
if interactive_mode {
81+
if !monitor_args.non_interactive {
8482
println!("Commands:");
8583
println!(" CTRL+R Reset chip");
8684
println!(" CTRL+C Exit");
8785
println!();
88-
} else {
86+
} else if !monitor_args.no_reset {
8987
reset_after_flash(&mut serial, pid).into_diagnostic()?;
9088
}
9189

90+
let baud = monitor_args.baud_rate;
91+
debug!("Opening serial monitor with baudrate: {}", baud);
92+
9293
// Explicitly set the baud rate when starting the serial monitor, to allow using
9394
// different rates for flashing.
9495
serial.set_baud_rate(baud).into_diagnostic()?;
@@ -102,12 +103,13 @@ pub fn monitor(
102103
let stdout = stdout();
103104
let mut stdout = ResolvingPrinter::new(elf, stdout.lock());
104105

105-
let mut parser: Box<dyn InputParser> = match log_format {
106+
let mut parser: Box<dyn InputParser> = match monitor_args.log_format {
106107
LogFormat::Defmt => Box::new(parser::esp_defmt::EspDefmt::new(elf)?),
107108
LogFormat::Serial => Box::new(parser::serial::Serial),
108109
};
109110

110-
let mut external_processors = ExternalProcessors::new(processors, elf_file)?;
111+
let mut external_processors =
112+
ExternalProcessors::new(monitor_args.processors, monitor_args.elf)?;
111113

112114
let mut buff = [0; 1024];
113115
loop {
@@ -124,7 +126,7 @@ pub fn monitor(
124126
// Don't forget to flush the writer!
125127
stdout.flush().ok();
126128

127-
if interactive_mode && poll(Duration::from_secs(0)).into_diagnostic()? {
129+
if !monitor_args.non_interactive && poll(Duration::from_secs(0)).into_diagnostic()? {
128130
if let Event::Key(key) = read().into_diagnostic()? {
129131
if key.kind == KeyEventKind::Press {
130132
if key.modifiers.contains(KeyModifiers::CONTROL) {

espflash/tests/scripts/flash.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#!/usr/bin/env bash
22

3-
result=$(espflash flash --no-skip $1 2>&1)
3+
result=$(timeout 8s espflash flash --no-skip --monitor --non-interactive $1 2>&1)
44
echo "$result"
55
if [[ ! $result =~ "Flashing has completed!" ]]; then
6+
echo "Flashing failed!"
7+
exit 1
8+
fi
9+
if ! echo "$result" | grep -q "Hello world!"; then
10+
echo "Monitoring failed!"
611
exit 1
712
fi

0 commit comments

Comments
 (0)