Detect log format metadata (#809)

* Detect log format metadata

* Match section name

* Update HIL test

* Changelog
This commit is contained in:
Dániel Buga
2025-03-25 10:33:24 +01:00
committed by GitHub
parent ee954b2c7b
commit b028c5295e
7 changed files with 69 additions and 5 deletions

View File

@@ -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

View File

@@ -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<LogFormat>,
/// External log processors to use (comma separated executables)
#[arg(long)]
processors: Option<String>,

View File

@@ -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<dyn InputParser> = match monitor_args.log_format {
let mut parser: Box<dyn InputParser> = 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.
//

View File

@@ -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()
}
}

View File

@@ -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

Binary file not shown.

View File

@@ -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)