diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12bb9a91..da119aef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/cargo-espflash/src/main.rs b/cargo-espflash/src/main.rs index 8d49637c..4fcfb6ba 100644 --- a/cargo-espflash/src/main.rs +++ b/cargo-espflash/src/main.rs @@ -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, *}, error::Error as EspflashError, flasher::parse_partition_table, logging::initialize_logger, @@ -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 { @@ -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; diff --git a/espflash/src/bin/espflash.rs b/espflash/src/bin/espflash.rs index f117b9ce..af5c8324 100644 --- a/espflash/src/bin/espflash.rs +++ b/espflash/src/bin/espflash.rs @@ -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, diff --git a/espflash/src/cli/config.rs b/espflash/src/cli/config.rs index 6e4d7b2d..f4cc8b44 100644 --- a/espflash/src/cli/config.rs +++ b/espflash/src/cli/config.rs @@ -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)] @@ -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")] diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index b4825ce9..d1832521 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -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}, }; @@ -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)] diff --git a/espflash/src/cli/monitor/external_processors.rs b/espflash/src/cli/monitor/external_processors.rs index aa1041f9..e8942bb2 100644 --- a/espflash/src/cli/monitor/external_processors.rs +++ b/espflash/src/cli/monitor/external_processors.rs @@ -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 diff --git a/espflash/src/cli/monitor/mod.rs b/espflash/src/cli/monitor/mod.rs index 562be438..f7bfb7bc 100644 --- a/espflash/src/cli/monitor/mod.rs +++ b/espflash/src/cli/monitor/mod.rs @@ -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; @@ -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, diff --git a/espflash/src/cli/monitor/parser/esp_defmt.rs b/espflash/src/cli/monitor/parser/esp_defmt.rs index 31af4d05..b7531cf2 100644 --- a/espflash/src/cli/monitor/parser/esp_defmt.rs +++ b/espflash/src/cli/monitor/parser/esp_defmt.rs @@ -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 { @@ -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 { let Some(elf) = elf else { bail!(DefmtError::NoElf); diff --git a/espflash/src/cli/monitor/parser/mod.rs b/espflash/src/cli/monitor/parser/mod.rs index 5b3346c8..138413c0 100644 --- a/espflash/src/cli/monitor/parser/mod.rs +++ b/espflash/src/cli/monitor/parser/mod.rs @@ -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 { diff --git a/espflash/src/cli/monitor/symbols.rs b/espflash/src/cli/monitor/symbols.rs index c3bb545b..f4f18090 100644 --- a/espflash/src/cli/monitor/symbols.rs +++ b/espflash/src/cli/monitor/symbols.rs @@ -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 @@ -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 { // no need to try an address not contained in any segment if !self.file.segments().any(|segment| { @@ -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) }); @@ -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. diff --git a/espflash/src/cli/serial.rs b/espflash/src/cli/serial.rs index ab71630b..dbaba19f 100644 --- a/espflash/src/cli/serial.rs +++ b/espflash/src/cli/serial.rs @@ -105,8 +105,8 @@ fn find_serial_port(ports: &[SerialPortInfo], name: &str) -> Result Result> { @@ -129,7 +129,8 @@ fn detect_usb_serial_ports(_list_all_ports: bool) -> Result> }; // 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: diff --git a/espflash/src/command.rs b/espflash/src/command.rs index be91e504..e262537d 100644 --- a/espflash/src/command.rs +++ b/espflash/src/command.rs @@ -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, diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index 76e3c077..937137f4 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -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::{ @@ -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 { diff --git a/espflash/src/connection/reset.rs b/espflash/src/connection/reset.rs index 936f232a..d322c77f 100644 --- a/espflash/src/connection/reset.rs +++ b/espflash/src/connection/reset.rs @@ -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}, diff --git a/espflash/src/error.rs b/espflash/src/error.rs index 1706ca82..31cf7ef7 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -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; @@ -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)] diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index d57fdf55..d62cc2d2 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -4,13 +4,11 @@ //! application to a target device. It additionally provides some operations to //! read information from the target device. -use std::{fs, path::Path, str::FromStr}; - #[cfg(feature = "serialport")] use std::{borrow::Cow, io::Write, path::PathBuf, thread::sleep, time::Duration}; +use std::{fs, path::Path, str::FromStr}; use esp_idf_part::PartitionTable; - #[cfg(feature = "serialport")] use log::{debug, info, warn}; #[cfg(feature = "serialport")] @@ -18,33 +16,33 @@ use md5::{Digest, Md5}; use serde::{Deserialize, Serialize}; #[cfg(feature = "serialport")] use serialport::UsbPortInfo; -use strum::IntoEnumIterator; -use strum::{Display, EnumIter, VariantNames}; - -use crate::{ - error::Error, - targets::{Chip, XtalFrequency}, -}; +use strum::{Display, EnumIter, IntoEnumIterator, VariantNames}; +#[cfg(feature = "serialport")] +pub(crate) use stubs::{FLASH_SECTOR_SIZE, FLASH_WRITE_SIZE}; +#[cfg(feature = "serialport")] +pub use crate::targets::flash_target::ProgressCallbacks; #[cfg(feature = "serialport")] use crate::{ command::{Command, CommandType}, connection::{ reset::{ResetAfterOperation, ResetBeforeOperation}, - Connection, Port, + Connection, + Port, }, elf::{ElfFirmwareImage, FirmwareImage, RomSegment}, error::{ConnectionError, ResultExt}, flasher::stubs::{ - FlashStub, CHIP_DETECT_MAGIC_REG_ADDR, DEFAULT_TIMEOUT, EXPECTED_STUB_HANDSHAKE, + FlashStub, + CHIP_DETECT_MAGIC_REG_ADDR, + DEFAULT_TIMEOUT, + EXPECTED_STUB_HANDSHAKE, }, }; - -#[cfg(feature = "serialport")] -pub use crate::targets::flash_target::ProgressCallbacks; - -#[cfg(feature = "serialport")] -pub(crate) use stubs::{FLASH_SECTOR_SIZE, FLASH_WRITE_SIZE}; +use crate::{ + error::Error, + targets::{Chip, XtalFrequency}, +}; #[cfg(feature = "serialport")] pub(crate) mod stubs; diff --git a/espflash/src/flasher/stubs.rs b/espflash/src/flasher/stubs.rs index 035b5489..e24bbfe5 100644 --- a/espflash/src/flasher/stubs.rs +++ b/espflash/src/flasher/stubs.rs @@ -5,7 +5,8 @@ use serde::{Deserialize, Serialize}; use crate::targets::Chip; -/// Flash stub object (deserialized from TOML, converted from JSON as used by `esptool.py`) +/// Flash stub object (deserialized from TOML, converted from JSON as used by +/// `esptool.py`) #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct FlashStub { /// Entry point (address) diff --git a/espflash/src/lib.rs b/espflash/src/lib.rs index 7c720856..2c52a5af 100644 --- a/espflash/src/lib.rs +++ b/espflash/src/lib.rs @@ -19,8 +19,9 @@ //! //! We add `default-features` here to disable the `cli` feature, which is //! enabled by default. Its important to note that the cli module does not -//! provide SemVer guarantees. You likely will not need any of these types or functions -//! in your application so there's no use pulling in the extra dependencies. +//! provide SemVer guarantees. You likely will not need any of these types or +//! functions in your application so there's no use pulling in the extra +//! dependencies. //! //! [espflash]: https://crates.io/crates/espflash //! [cargo-binstall]: https://github.com/cargo-bins/cargo-binstall diff --git a/espflash/src/targets/mod.rs b/espflash/src/targets/mod.rs index 05e5bf9a..a3150d47 100644 --- a/espflash/src/targets/mod.rs +++ b/espflash/src/targets/mod.rs @@ -10,26 +10,30 @@ use esp_idf_part::{AppType, DataType, Partition, PartitionTable, SubType, Type}; use serde::{Deserialize, Serialize}; use strum::{Display, EnumIter, EnumString, VariantNames}; -use crate::{ - elf::FirmwareImage, - error::Error, - flasher::{FlashData, FlashFrequency}, - image_format::IdfBootloaderFormat, - targets::{ - esp32::Esp32, esp32c2::Esp32c2, esp32c3::Esp32c3, esp32c6::Esp32c6, esp32h2::Esp32h2, - esp32p4::Esp32p4, esp32s2::Esp32s2, esp32s3::Esp32s3, - }, -}; - #[cfg(feature = "serialport")] pub use self::flash_target::{Esp32Target, RamTarget}; - #[cfg(feature = "serialport")] use crate::{ connection::Connection, flasher::{SpiAttachParams, FLASH_WRITE_SIZE}, targets::flash_target::{FlashTarget, MAX_RAM_BLOCK_SIZE}, }; +use crate::{ + elf::FirmwareImage, + error::Error, + flasher::{FlashData, FlashFrequency}, + image_format::IdfBootloaderFormat, + targets::{ + esp32::Esp32, + esp32c2::Esp32c2, + esp32c3::Esp32c3, + esp32c6::Esp32c6, + esp32h2::Esp32h2, + esp32p4::Esp32p4, + esp32s2::Esp32s2, + esp32s3::Esp32s3, + }, +}; /// Max partition size is 16 MB const MAX_PARTITION_SIZE: u32 = 16 * 1000 * 1024; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..0a9902d0 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,9 @@ +# Comments +format_code_in_doc_comments = true +normalize_comments = true +wrap_comments = true + +# Imports +group_imports = "StdExternalCrate" +imports_granularity = "Crate" +imports_layout = "HorizontalVertical"