diff --git a/CHANGELOG.md b/CHANGELOG.md index 356c89c..d04bbeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `--monitor` option to `write-bin`. (#783) - Add `watchdog-reset` strategy to `--after` subcommand (#779) - Add `ROM` version of `read-flash` command (#812) +- `espflash` can detect the log format automatically from ESP-HAL metadata. Reqires `esp-println` 0.14 (presumably, yet to be released) (#809) ### Changed diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index 0d87298..28a82ce 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -280,8 +280,8 @@ pub struct MonitorConfigArgs { #[arg(long, requires = "non_interactive")] no_reset: bool, /// Logging format. - #[arg(long, short = 'L', default_value = "serial")] - log_format: LogFormat, + #[arg(long, short = 'L')] + log_format: Option, /// External log processors to use (comma separated executables) #[arg(long)] processors: Option, diff --git a/espflash/src/cli/monitor/mod.rs b/espflash/src/cli/monitor/mod.rs index 11d5032..a86ac38 100644 --- a/espflash/src/cli/monitor/mod.rs +++ b/espflash/src/cli/monitor/mod.rs @@ -20,7 +20,7 @@ use crossterm::{ terminal::{disable_raw_mode, enable_raw_mode}, }; use external_processors::ExternalProcessors; -use log::{debug, error}; +use log::{debug, error, warn}; use miette::{IntoDiagnostic, Result}; #[cfg(feature = "serialport")] use serialport::SerialPort; @@ -28,7 +28,10 @@ use strum::{Display, EnumIter, EnumString, VariantNames}; use crate::{ cli::{ - monitor::parser::{InputParser, ResolvingPrinter}, + monitor::{ + parser::{InputParser, ResolvingPrinter}, + symbols::Symbols, + }, MonitorConfigArgs, }, connection::{reset::reset_after_flash, Port}, @@ -102,7 +105,10 @@ pub fn monitor( let stdout = stdout(); let mut stdout = ResolvingPrinter::new(elf, stdout.lock()); - let mut parser: Box = match monitor_args.log_format { + let mut parser: Box = match monitor_args + .log_format + .unwrap_or_else(|| deduce_log_format(elf)) + { LogFormat::Defmt => Box::new(parser::esp_defmt::EspDefmt::new(elf)?), LogFormat::Serial => Box::new(parser::serial::Serial), }; @@ -151,6 +157,34 @@ pub fn monitor( Ok(()) } +fn deduce_log_format(elf: Option<&[u8]>) -> LogFormat { + let Some(elf) = elf else { + return LogFormat::Serial; + }; + + let Ok(symbols) = Symbols::try_from(elf) else { + return LogFormat::Serial; + }; + + let Some(format_symbol) = + symbols.get_symbol_data(Some(".espressif.metadata"), b"espflash.LOG_FORMAT") + else { + return LogFormat::Serial; + }; + + match format_symbol { + b"defmt-espflash" => LogFormat::Defmt, + b"serial" => LogFormat::Serial, + other => { + warn!( + "Unknown log format symbol: {}. Defaulting to serial.", + String::from_utf8_lossy(other), + ); + LogFormat::Serial + } + } +} + // Converts key events from crossterm into appropriate character/escape // sequences which are then sent over the serial connection. // diff --git a/espflash/src/cli/monitor/symbols.rs b/espflash/src/cli/monitor/symbols.rs index 4e9d9a1..46ec0b5 100644 --- a/espflash/src/cli/monitor/symbols.rs +++ b/espflash/src/cli/monitor/symbols.rs @@ -98,4 +98,18 @@ impl<'sym> Symbols<'sym> { } })? } + + pub(crate) fn get_symbol_data( + &self, + section_name: Option<&str>, + name_bytes: &[u8], + ) -> Option<&'sym [u8]> { + let sym = self.object.symbol_by_name_bytes(name_bytes)?; + + let section = match section_name { + Some(section_name) => self.object.section_by_name(section_name)?, + None => self.object.section_by_index(sym.section_index()?).ok()?, + }; + section.data_range(sym.address(), sym.size()).ok().flatten() + } } diff --git a/espflash/tests/data/README.md b/espflash/tests/data/README.md index 615d948..b31de83 100644 --- a/espflash/tests/data/README.md +++ b/espflash/tests/data/README.md @@ -8,6 +8,8 @@ cargo build --release The `esp32c6_defmt` elf file under this folder has been generated using `esp-generate@04d69c9`: +> TODO: this part needs to be updated, and the elf re-created once ESP-HAL beta.1 is out. + ``` esp-generate --chip=esp32c6 -o defmt --headless esp32c6_defmt cd esp32c6_defmt diff --git a/espflash/tests/data/esp32c6_defmt b/espflash/tests/data/esp32c6_defmt index ef5e61d..44972d3 100755 Binary files a/espflash/tests/data/esp32c6_defmt and b/espflash/tests/data/esp32c6_defmt differ diff --git a/espflash/tests/scripts/flash.sh b/espflash/tests/scripts/flash.sh index c45ec52..90a5551 100644 --- a/espflash/tests/scripts/flash.sh +++ b/espflash/tests/scripts/flash.sh @@ -2,6 +2,7 @@ app="espflash/tests/data/$1" if [[ "$1" == "esp32c6" ]]; then + # With manual log-format app_defmt="${app}_defmt" result=$(timeout 8s espflash flash --no-skip --monitor --non-interactive $app_defmt --log-format defmt 2>&1) echo "$result" @@ -13,6 +14,18 @@ if [[ "$1" == "esp32c6" ]]; then echo "Monitoring failed!" exit 1 fi + + # With auto-detected log-format + result=$(timeout 8s espflash flash --no-skip --monitor --non-interactive $app_defmt 2>&1) + echo "$result" + if [[ ! $result =~ "Flashing has completed!" ]]; then + echo "Flashing failed!" + exit 1 + fi + if ! echo "$result" | grep -q "Hello world!"; then + echo "Monitoring failed!" + exit 1 + fi fi result=$(timeout 8s espflash flash --no-skip --monitor --non-interactive $app 2>&1)