Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@nightly
with:
components: rustfmt
- uses: Swatinem/rust-cache@v2
Expand Down
16 changes: 5 additions & 11 deletions cargo-espflash/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ use std::{
use cargo_metadata::{Message, MetadataCommand};
use clap::{Args, CommandFactory, Parser, Subcommand};
use espflash::{
cli::{
self, board_info, checksum_md5, completions, config::Config, connect, erase_flash,
erase_partitions, erase_region, flash_elf_image, make_flash_data, monitor::monitor,
partition_table, print_board_info, read_flash, save_elf_as_image, serial_monitor,
ChecksumMd5Args, CompletionsArgs, ConnectArgs, EraseFlashArgs, EraseRegionArgs,
EspflashProgress, FlashConfigArgs, MonitorArgs, PartitionTableArgs, ReadFlashArgs,
},
cli::{self, config::Config, monitor::monitor, *},
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally I'd like to avoid glob imports, but in this case I think it's justified

error::Error as EspflashError,
flasher::parse_partition_table,
logging::initialize_logger,
Expand Down Expand Up @@ -305,8 +299,8 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
)?;
flasher.verify_minimum_revision(args.flash_args.image.min_chip_rev)?;

// If the user has provided a flash size via a command-line argument or config, we'll
// override the detected (or default) value with this.
// If the user has provided a flash size via a command-line argument or config,
// we'll override the detected (or default) value with this.
if let Some(flash_size) = args.build_args.flash_config_args.flash_size {
flasher.set_flash_size(flash_size);
} else if let Some(flash_size) = config.flash.size {
Expand Down Expand Up @@ -493,8 +487,8 @@ fn build(
match message.into_diagnostic()? {
Message::BuildScriptExecuted(script) => {
// We can't use the `Index` implementation on `Metadata` because `-Zbuild-std`
// pulls in dependencies not listed in the metadata which then causes the `Index`
// implementation to panic.
// pulls in dependencies not listed in the metadata which then causes the
// `Index` implementation to panic.
let Some(package) = metadata.packages.iter().find(|p| p.id == script.package_id)
else {
continue;
Expand Down
9 changes: 1 addition & 8 deletions espflash/src/bin/espflash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ use std::{

use clap::{Args, CommandFactory, Parser, Subcommand};
use espflash::{
cli::{
self, board_info, checksum_md5, completions, config::Config, connect, erase_flash,
erase_partitions, erase_region, flash_elf_image, make_flash_data, monitor::monitor,
parse_uint32, partition_table, print_board_info, read_flash, save_elf_as_image,
serial_monitor, ChecksumMd5Args, CompletionsArgs, ConnectArgs, EraseFlashArgs,
EraseRegionArgs, EspflashProgress, FlashConfigArgs, MonitorArgs, PartitionTableArgs,
ReadFlashArgs,
},
cli::{self, config::Config, monitor::monitor, *},
error::Error,
flasher::parse_partition_table,
logging::initialize_logger,
Expand Down
6 changes: 3 additions & 3 deletions espflash/src/cli/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ use miette::{IntoDiagnostic, Result, WrapErr};
use serde::{Deserialize, Serialize};
use serialport::UsbPortInfo;

use crate::error::Error;
use crate::flasher::FlashSettings;
use crate::{error::Error, flasher::FlashSettings};

/// A configured, known serial connection
#[derive(Debug, Deserialize, Serialize, Default, Clone)]
Expand Down Expand Up @@ -167,9 +166,10 @@ impl Config {

#[cfg(test)]
mod tests {
use super::*;
use serde::Deserialize;

use super::*;

#[derive(Debug, Deserialize, Serialize)]
struct TestData {
#[serde(serialize_with = "parse_u16_hex", deserialize_with = "parse_hex_u16")]
Expand Down
13 changes: 10 additions & 3 deletions espflash/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ use crate::{
elf::ElfFirmwareImage,
error::{Error, MissingPartition, MissingPartitionTable},
flasher::{
parse_partition_table, FlashData, FlashFrequency, FlashMode, FlashSettings, FlashSize,
Flasher, ProgressCallbacks,
parse_partition_table,
FlashData,
FlashFrequency,
FlashMode,
FlashSettings,
FlashSize,
Flasher,
ProgressCallbacks,
},
targets::{Chip, XtalFrequency},
};
Expand Down Expand Up @@ -857,9 +863,10 @@ pub fn make_flash_data(
}

mod test {
use crate::cli::FlashArgs;
use clap::Parser;

use crate::cli::FlashArgs;

#[derive(Parser)]
struct TestParser {
#[clap(flatten)]
Expand Down
20 changes: 13 additions & 7 deletions espflash/src/cli/monitor/external_processors.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
#![allow(clippy::needless_doctest_main)]
//! External processor support
//!
//! Via the command line argument `--processors` you can instruct espflash to run external executables to pre-process
//! the logs received from the target. Multiple processors are supported by separating them via `,`. Processors are executed in the specified order.
//! Via the command line argument `--processors` you can instruct espflash to
//! run external executables to pre-process the logs received from the target.
//! Multiple processors are supported by separating them via `,`. Processors are
//! executed in the specified order.
//!
//! You can use full-qualified paths or run an executable which is already in the search path.
//! You can use full-qualified paths or run an executable which is already in
//! the search path.
//!
//! A processors reads from stdin and output to stdout. Be aware this runs before further processing by espflash.
//! i.e. addresses are not resolved and when using `defmt` you will see encoded data.
//! A processors reads from stdin and output to stdout. Be aware this runs
//! before further processing by espflash. i.e. addresses are not resolved and
//! when using `defmt` you will see encoded data.
//!
//! Additionally be aware that you might receive chunked data which is not always split at valid UTF character boundaries.
//! Additionally be aware that you might receive chunked data which is not
//! always split at valid UTF character boundaries.
//!
//! The executable will get the path of the ELF file as the first argument if available.
//! The executable will get the path of the ELF file as the first argument if
//! available.
//!
//! Example processor which turns some letters into uppercase
//! ```rust,no_run
Expand Down
6 changes: 3 additions & 3 deletions espflash/src/cli/monitor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ use std::{
time::Duration,
};

use crossterm::event::KeyEventKind;
use crossterm::{
event::{poll, read, Event, KeyCode, KeyEvent, KeyModifiers},
event::{poll, read, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers},
terminal::{disable_raw_mode, enable_raw_mode},
};
use external_processors::ExternalProcessors;
Expand Down Expand Up @@ -68,7 +67,8 @@ impl Drop for RawModeGuard {
}
}

/// Open a serial monitor on the given serial port, using the given input parser.
/// Open a serial monitor on the given serial port, using the given input
/// parser.
#[allow(clippy::too_many_arguments)]
pub fn monitor(
mut serial: Port,
Expand Down
6 changes: 4 additions & 2 deletions espflash/src/cli/monitor/parser/esp_defmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ impl FrameDelimiter {
}

if !self.in_frame {
// If we have a 0xFF byte at the end, we should assume it's the start of a new frame.
// If we have a 0xFF byte at the end, we should assume it's the start of a new
// frame.
let consume = if self.buffer.ends_with(&[0xFF]) {
&self.buffer[..self.buffer.len() - 1]
} else {
Expand All @@ -102,7 +103,8 @@ pub struct EspDefmt {
}

impl EspDefmt {
/// Loads symbols from the ELF file (if provided) and initializes the context.
/// Loads symbols from the ELF file (if provided) and initializes the
/// context.
fn load_table(elf: Option<&[u8]>) -> Result<Table> {
let Some(elf) = elf else {
bail!(DefmtError::NoElf);
Expand Down
4 changes: 2 additions & 2 deletions espflash/src/cli/monitor/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ impl Utf8Merger {
let mut buffer = std::mem::take(&mut self.incomplete_utf8_buffer);
buffer.extend(normalized(buff.iter().copied()));

// look for longest slice that we can then lossily convert without introducing errors for
// partial sequences (#457)
// look for longest slice that we can then lossily convert without introducing
// errors for partial sequences (#457)
let mut len = 0;

loop {
Expand Down
12 changes: 8 additions & 4 deletions espflash/src/cli/monitor/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::error::Error;
use addr2line::{
gimli::{EndianRcSlice, RunTimeEndian},
object::{read::File, Object, ObjectSegment, ObjectSymbol},
Context, LookupResult,
Context,
LookupResult,
};

// Wrapper around addr2line that allows to look up function names and
Expand All @@ -21,7 +22,8 @@ impl<'sym> Symbols<'sym> {
Ok(Self { file, ctx })
}

/// Returns the name of the function at the given address, if one can be found.
/// Returns the name of the function at the given address, if one can be
/// found.
pub fn get_name(&self, addr: u64) -> Option<String> {
// no need to try an address not contained in any segment
if !self.file.segments().any(|segment| {
Expand Down Expand Up @@ -51,7 +53,8 @@ impl<'sym> Symbols<'sym> {
.and_then(|name| name.demangle().map(|s| s.into_owned()).ok())
})
.or_else(|| {
// Don't use `symbol_map().get(addr)` - it's documentation says "Get the symbol before the given address." which might be totally wrong
// Don't use `symbol_map().get(addr)` - it's documentation says "Get the symbol
// before the given address." which might be totally wrong
let symbol = self.file.symbols().find(|symbol| {
(symbol.address()..=(symbol.address() + symbol.size())).contains(&addr)
});
Expand All @@ -70,7 +73,8 @@ impl<'sym> Symbols<'sym> {
})
}

/// Returns the file name and line number of the function at the given address, if one can be.
/// Returns the file name and line number of the function at the given
/// address, if one can be.
pub fn get_location(&self, addr: u64) -> Option<(String, u32)> {
// Find the location which `addr` is in. If we can dedetermine a file name and
// line number for this function we will return them both in a tuple.
Expand Down
7 changes: 4 additions & 3 deletions espflash/src/cli/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ fn find_serial_port(ports: &[SerialPortInfo], name: &str) -> Result<SerialPortIn
}
}

/// Serialport's auto-detect doesn't provide any port information when using MUSL
/// Linux we can do some manual parsing of sysfs to get the relevant bits
/// Serialport's auto-detect doesn't provide any port information when using
/// MUSL Linux we can do some manual parsing of sysfs to get the relevant bits
/// without udev
#[cfg(all(target_os = "linux", target_env = "musl"))]
fn detect_usb_serial_ports(_list_all_ports: bool) -> Result<Vec<SerialPortInfo>> {
Expand All @@ -129,7 +129,8 @@ fn detect_usb_serial_ports(_list_all_ports: bool) -> Result<Vec<SerialPortInfo>>
};

// This will give something like:
// `/sys/devices/pci0000:00/0000:00:07.1/0000:0c:00.3/usb5/5-3/5-3.1/5-3.1:1.0/ttyUSB0/tty/ttyUSB0`
// `/sys/devices/pci0000:00/0000:00:07.1/0000:0c:00.3/usb5/5-3/5-3.1/5-3.1:1.0/
// ttyUSB0/tty/ttyUSB0`
let mut parent_dev = path.canonicalize().ok()?;

// Walk up 3 dirs to get to the device hosting the tty:
Expand Down
3 changes: 2 additions & 1 deletion espflash/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const SYNC_TIMEOUT: Duration = Duration::from_millis(100);
const FLASH_DEFLATE_END_TIMEOUT: Duration = Duration::from_secs(10);
const FLASH_MD5_TIMEOUT: Duration = Duration::from_secs(8);

/// Input data for SYNC command (36 bytes: 0x07 0x07 0x12 0x20, followed by 32 x 0x55)
/// Input data for SYNC command (36 bytes: 0x07 0x07 0x12 0x20, followed by
/// 32 x 0x55)
const SYNC_FRAME: [u8; 36] = [
0x07, 0x07, 0x12, 0x20, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
Expand Down
30 changes: 20 additions & 10 deletions espflash/src/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ use self::reset::UnixTightReset;
use self::{
encoder::SlipEncoder,
reset::{
construct_reset_strategy_sequence, hard_reset, reset_after_flash, ClassicReset,
ResetAfterOperation, ResetBeforeOperation, ResetStrategy, UsbJtagSerialReset,
construct_reset_strategy_sequence,
hard_reset,
reset_after_flash,
ClassicReset,
ResetAfterOperation,
ResetBeforeOperation,
ResetStrategy,
UsbJtagSerialReset,
},
};
use crate::{
Expand Down Expand Up @@ -334,16 +340,20 @@ impl Connection {
match self.read(10)? {
None => Ok(None),
Some(response) => {
// here is what esptool does: https://github.com/espressif/esptool/blob/master/esptool/loader.py#L458
// Here is what esptool does: https://github.com/espressif/esptool/blob/master/esptool/loader.py#L458
// from esptool: things are a bit weird here, bear with us

// we rely on the known and expected response sizes which should be fine for now - if that changes we need to pass the command type
// we are parsing the response for
// for most commands the response length is 10 (for the stub) or 12 (for ROM code)
// the MD5 command response is 44 for ROM loader, 26 for the stub
// see https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#response-packet
// see https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#status-bytes
// see https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#verifying-uploaded-data
// We rely on the known and expected response sizes which should be fine for now
// - if that changes we need to pass the command type we are parsing the
// response for.
//
// For most commands the response length is 10 (for the stub) or 12 (for ROM
// code). The MD5 command response is 44 for ROM loader, 26 for the stub.
//
// See:
// - https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#response-packet
// - https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#status-bytes
// - https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#verifying-uploaded-data
let status_len = if response.len() == 10 || response.len() == 26 {
2
} else {
Expand Down
5 changes: 2 additions & 3 deletions espflash/src/connection/reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
use std::{io, os::fd::AsRawFd};
use std::{thread::sleep, time::Duration};

#[cfg(unix)]
use libc::ioctl;
use log::debug;
use serialport::SerialPort;
use strum::{Display, EnumIter, EnumString, VariantNames};

#[cfg(unix)]
use libc::ioctl;

use crate::{
command::{Command, CommandType},
connection::{Connection, Port, USB_SERIAL_JTAG_PID},
Expand Down
6 changes: 3 additions & 3 deletions espflash/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

#[cfg(feature = "serialport")]
use std::fmt::{Display, Formatter};
use std::io;

use miette::Diagnostic;
use std::io;
#[cfg(feature = "serialport")]
use slip_codec::SlipError;
use strum::VariantNames;
use thiserror::Error;

Expand All @@ -16,8 +18,6 @@ use crate::{
flasher::{FlashFrequency, FlashSize},
targets::Chip,
};
#[cfg(feature = "serialport")]
use slip_codec::SlipError;

/// All possible errors returned by espflash
#[derive(Debug, Diagnostic, Error)]
Expand Down
Loading