diff --git a/CHANGELOG.md b/CHANGELOG.md index 146a02b3..d981d6bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,12 +35,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Windows: Update RST/DTR order to avoid issues. ### Changed + - Created `FlashData`, `FlashDataBuilder` and `FlashSettings` structs to reduce number of input arguments in some functions (#512, #566) - `espflash` will now exit with an error if `defmt` is selected but not usable (#524) - Unify configuration methods (#551) ### Removed +- Remove support for the ESP8266 (#576) + ## [2.1.0] - 2023-10-03 ### Added diff --git a/README.md b/README.md index a0437e36..8696cd26 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Serial flasher utilities for Espressif devices, based loosely on [esptool.py](https://github.com/espressif/esptool/). -Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, **ESP32-S2/S3**, and **ESP8266**. +Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, and **ESP32-S2/S3**. ## [cargo-espflash](./cargo-espflash/) diff --git a/cargo-espflash/README.md b/cargo-espflash/README.md index f59318d8..02e4c54e 100644 --- a/cargo-espflash/README.md +++ b/cargo-espflash/README.md @@ -7,7 +7,7 @@ Cross-compiler and Cargo extension for flashing Espressif devices. -Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, **ESP32-S2/S3**, and **ESP8266**. +Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, and **ESP32-S2/S3**. ## Table of Contents @@ -57,6 +57,7 @@ cargo install cargo-espflash --features=raspberry ``` By default, in Unix systems, we use the [`vendored-openssl` Cargo feature] which may require additional tools such as `perl` and `make`. To disable this feature, use: + ``` OPENSSL_NO_VENDOR=1 cargo install cargo-espflash ``` @@ -117,6 +118,7 @@ If the `--bootloader` and/or `--partition-table` options are provided then these ## Configuration File The configuration file allows you to define various parameters for your application: + - Serial port: - By name: ```toml @@ -143,6 +145,7 @@ The configuration file allows you to define various parameters for your applicat ``` You can have a local and/or a global configuration file: + - For local configurations, store the file under the current working directory with the name `espflash.toml` - Global file location differs based on your operating system: - Linux: `$HOME/.config/espflash/espflash.toml` @@ -158,6 +161,7 @@ You can have a local and/or a global configuration file: ## Logging Format `cargo-espflash` `flash` and `monitor` subcommands support several logging formats using the `-L/--log-format` argument: + - `serial`: Default logging format - `defmt`: Uses [`defmt`] logging framework. With logging format, logging strings have framing bytes to indicate that they are `defmt` messages. - See [`defmt` section] of `esp-println` readme. diff --git a/cargo-espflash/src/main.rs b/cargo-espflash/src/main.rs index 81cfee2f..2b8174b7 100644 --- a/cargo-espflash/src/main.rs +++ b/cargo-espflash/src/main.rs @@ -164,7 +164,8 @@ pub struct ErasePartsArgs { /// Input partition table #[arg(long, value_name = "FILE")] pub partition_table: Option, - /// Specify a (binary) package within a workspace which may provide a partition table + /// Specify a (binary) package within a workspace which may provide a + /// partition table #[arg(long)] pub package: Option, } @@ -244,18 +245,18 @@ pub fn erase_parts(args: ErasePartsArgs, config: &Config) -> Result<()> { .as_deref() .or(config.partition_table.as_deref()); - let mut flash = connect(&args.connect_args, config, false, false)?; + let mut flasher = connect(&args.connect_args, config, false, false)?; let partition_table = match partition_table { Some(path) => Some(parse_partition_table(path)?), None => None, }; info!("Erasing the following partitions: {:?}", args.erase_parts); - let chip: Chip = flash.chip(); - erase_partitions(&mut flash, partition_table, Some(args.erase_parts), None)?; - flash + + erase_partitions(&mut flasher, partition_table, Some(args.erase_parts), None)?; + flasher .connection() - .reset_after(!args.connect_args.no_stub, chip)?; + .reset_after(!args.connect_args.no_stub)?; Ok(()) } diff --git a/espflash/README.md b/espflash/README.md index ba3fc787..325361b8 100644 --- a/espflash/README.md +++ b/espflash/README.md @@ -8,7 +8,7 @@ A library and command-line tool for flashing Espressif devices. -Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**,**ESP32-S2/S3**, and **ESP8266**. +Supports the **ESP32**, **ESP32-C2/C3/C6**, **ESP32-H2**, **ESP32-P4**, and **ESP32-S2/S3**. ## Table of Contents @@ -117,9 +117,11 @@ With this configuration you can flash and monitor you application using `cargo r ## Using `espflash` as a Library `espflash` can be used as a library in other applications: + ```toml espflash = { version = "2.1", default-features = false } ``` + or `cargo add espflash --no-default-features` > **Warning** @@ -136,6 +138,7 @@ espflash = { version = "2.1", default-features = false, features = ["raspberry"] ## Configuration File The configuration file allows you to define various parameters for your application: + - Serial port: - By name: ```toml @@ -162,6 +165,7 @@ The configuration file allows you to define various parameters for your applicat ``` You can have a local and/or a global configuration file: + - For local configurations, store the file under the current working directory with the name `espflash.toml` - Global file location differs based on your operating system: - Linux: `$HOME/.config/espflash/espflash.toml` @@ -177,6 +181,7 @@ You can have a local and/or a global configuration file: ## Logging Format `espflash` `flash` and `monitor` subcommands support several logging formats using the `-L/--log-format` argument: + - `serial`: Default logging format - `defmt`: Uses [`defmt`] logging framework. With logging format, logging strings have framing bytes to indicate that they are `defmt` messages. - See [`defmt` section] of `esp-println` readme. diff --git a/espflash/resources/README.md b/espflash/resources/README.md index 0adebbe6..cb880ad3 100644 --- a/espflash/resources/README.md +++ b/espflash/resources/README.md @@ -5,5 +5,3 @@ https://github.com/espressif/esp-idf/tree/release/v5.1 The ESP32s flasher stubs are taken from the **esp-rs/esp-flasher-stub** repository: https://github.com/esp-rs/esp-flasher-stub/releases/latest -The ESP8266 flasher stub is taken from the **espressif/esptool** repository: -https://github.com/espressif/esptool/tree/master/esptool/targets/stub_flasher diff --git a/espflash/resources/stubs/stub_flasher_8266.toml b/espflash/resources/stubs/stub_flasher_8266.toml deleted file mode 100644 index 187e0180..00000000 --- a/espflash/resources/stubs/stub_flasher_8266.toml +++ /dev/null @@ -1,5 +0,0 @@ -entry = 1_074_843_652 -text = "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" -text_start = 1_074_843_648 -data = "CIH+PwUFBAACAwcAAwMLALnXEEDv1xBAHdgQQLrYEEBo5xBAHtkQQHTZEEDA2RBAaOcQQILaEED/2hBAwNsQQGjnEEBo5xBAWNwQQGjnEEA33xBAAOAQQDvgEEBo5xBAaOcQQNfgEEBo5xBAv+EQQGXiEECj4xBAY+QQQDTlEEBo5xBAaOcQQGjnEEBo5xBAYuYQQGjnEEBX5xBAkN0QQI/YEECm5RBAq9oQQPzZEEBo5xBA7OYQQDHnEEBo5xBAaOcQQGjnEEBo5xBAaOcQQGjnEEBo5xBAaOcQQCLaEEBf2hBAvuUQQAEAAAACAAAAAwAAAAQAAAAFAAAABwAAAAkAAAANAAAAEQAAABkAAAAhAAAAMQAAAEEAAABhAAAAgQAAAMEAAAABAQAAgQEAAAECAAABAwAAAQQAAAEGAAABCAAAAQwAAAEQAAABGAAAASAAAAEwAAABQAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAUAAAAGAAAABgAAAAcAAAAHAAAACAAAAAgAAAAJAAAACQAAAAoAAAAKAAAACwAAAAsAAAAMAAAADAAAAA0AAAANAAAAAAAAAAAAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAANAAAADwAAABEAAAATAAAAFwAAABsAAAAfAAAAIwAAACsAAAAzAAAAOwAAAEMAAABTAAAAYwAAAHMAAACDAAAAowAAAMMAAADjAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAgAAAAMAAAADAAAAAwAAAAMAAAAEAAAABAAAAAQAAAAEAAAABQAAAAUAAAAFAAAABQAAAAAAAAAAAAAAAAAAABAREgAIBwkGCgULBAwDDQIOAQ8AAQEAAAEAAAAEAAAA" -data_start = 1_073_720_488 diff --git a/espflash/src/bin/espflash.rs b/espflash/src/bin/espflash.rs index 50992e69..5780ac51 100644 --- a/espflash/src/bin/espflash.rs +++ b/espflash/src/bin/espflash.rs @@ -191,18 +191,18 @@ pub fn erase_parts(args: ErasePartsArgs, config: &Config) -> Result<()> { return Err(Error::StubRequired.into()); } - let mut flash = connect(&args.connect_args, config, false, false)?; + let mut flasher = connect(&args.connect_args, config, false, false)?; let partition_table = match args.partition_table { Some(path) => Some(parse_partition_table(&path)?), None => None, }; info!("Erasing the following partitions: {:?}", args.erase_parts); - let chip = flash.chip(); - erase_partitions(&mut flash, partition_table, Some(args.erase_parts), None)?; - flash + + erase_partitions(&mut flasher, partition_table, Some(args.erase_parts), None)?; + flasher .connection() - .reset_after(!args.connect_args.no_stub, chip)?; + .reset_after(!args.connect_args.no_stub)?; Ok(()) } diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index 708a9def..c665badb 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -10,8 +10,7 @@ //! [cargo-espflash]: https://crates.io/crates/cargo-espflash //! [espflash]: https://crates.io/crates/espflash -use std::num::ParseIntError; -use std::{collections::HashMap, fs, io::Write, path::PathBuf}; +use std::{collections::HashMap, fs, io::Write, num::ParseIntError, path::PathBuf}; use clap::Args; use clap_complete::Shell; @@ -590,11 +589,9 @@ pub fn erase_flash(args: EraseFlashArgs, config: &Config) -> Result<()> { let mut flash = connect(&args.connect_args, config, true, true)?; info!("Erasing Flash..."); + flash.erase_flash()?; - let chip = flash.chip(); - flash - .connection() - .reset_after(!args.connect_args.no_stub, chip)?; + flash.connection().reset_after(!args.connect_args.no_stub)?; Ok(()) } @@ -604,17 +601,17 @@ pub fn erase_region(args: EraseRegionArgs, config: &Config) -> Result<()> { return Err(Error::StubRequired).into_diagnostic(); } - let mut flash = connect(&args.connect_args, config, true, true)?; + let mut flasher = connect(&args.connect_args, config, true, true)?; info!( "Erasing region at 0x{:08x} ({} bytes)", args.addr, args.size ); - flash.erase_region(args.addr, args.size)?; - let chip = flash.chip(); - flash + + flasher.erase_region(args.addr, args.size)?; + flasher .connection() - .reset_after(!args.connect_args.no_stub, chip)?; + .reset_after(!args.connect_args.no_stub)?; Ok(()) } diff --git a/espflash/src/command.rs b/espflash/src/command.rs index 0ae2f923..5a320e34 100644 --- a/espflash/src/command.rs +++ b/espflash/src/command.rs @@ -31,7 +31,7 @@ const SYNC_FRAME: [u8; 36] = [ #[repr(u8)] pub enum CommandType { Unknown = 0, - // Commands supported by the ESP8266 & ESP32s bootloaders + // Commands supported by the ESP32's bootloaders FlashBegin = 0x02, FlashData = 0x03, FlashEnd = 0x04, @@ -461,7 +461,7 @@ fn begin_command( let bytes = bytes_of(¶ms); let data = if !supports_encryption { - // The ESP32 and ESP8266 do not take the `encrypted` field, so truncate the last + // The ESP32 does not take the `encrypted` field, so truncate the last // 4 bytes of the slice where it resides. let end = bytes.len() - 4; &bytes[0..end] diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index 6c2114ea..7621a90d 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -31,7 +31,6 @@ use crate::{ connection::reset::soft_reset, error::{ConnectionError, Error, ResultExt, RomError, RomErrorKind}, interface::Interface, - targets::Chip, }; pub mod reset; @@ -257,17 +256,12 @@ impl Connection { } // Reset the device taking into account the reset after argument - pub fn reset_after(&mut self, is_stub: bool, chip: Chip) -> Result<(), Error> { + pub fn reset_after(&mut self, is_stub: bool) -> Result<(), Error> { match self.after_operation { ResetAfterOperation::HardReset => HardReset.reset(&mut self.serial), - ResetAfterOperation::SoftReset => { - info!("Soft resetting"); - soft_reset(self, false, is_stub, chip)?; - Ok(()) - } ResetAfterOperation::NoReset => { info!("Staying in bootloader"); - soft_reset(self, true, is_stub, chip)?; + soft_reset(self, true, is_stub)?; Ok(()) } diff --git a/espflash/src/connection/reset.rs b/espflash/src/connection/reset.rs index 7992febf..dfcfc96b 100644 --- a/espflash/src/connection/reset.rs +++ b/espflash/src/connection/reset.rs @@ -3,18 +3,16 @@ #[cfg(unix)] use std::{io, os::fd::AsRawFd}; use std::{thread::sleep, time::Duration}; -use strum::{Display, EnumIter, EnumString, EnumVariantNames}; use log::debug; +use strum::{Display, EnumIter, EnumString, EnumVariantNames}; use crate::{ command::{Command, CommandType}, - connection::Connection, - connection::USB_SERIAL_JTAG_PID, + connection::{Connection, USB_SERIAL_JTAG_PID}, error::Error, flasher, interface::Interface, - targets::Chip, }; /// Default time to wait before releasing the boot pin after a reset @@ -220,12 +218,11 @@ impl ResetStrategy for HardReset { } } -/// +/// Perform a soft reset of the device. pub fn soft_reset( connection: &mut Connection, stay_in_bootloader: bool, is_stub: bool, - chip: Chip, ) -> Result<(), Error> { debug!("Using SoftReset reset strategy"); if !is_stub { @@ -269,8 +266,6 @@ pub fn soft_reset( connection.with_timeout(CommandType::FlashEnd.timeout(), |connection| { connection.write_command(Command::FlashEnd { reboot: true }) })?; - } else if chip != Chip::Esp8266 { - return Err(Error::SoftResetNotAvailable); } else { // Running user code from stub loader requires some hacks in the stub loader connection.with_timeout(CommandType::RunUserCode.timeout(), |connection| { @@ -321,12 +316,15 @@ pub fn construct_reset_strategy_sequence( #[non_exhaustive] #[strum(serialize_all = "lowercase")] pub enum ResetBeforeOperation { - /// Uses DTR & RTS serial control lines to try to reset the chip into bootloader mode. + /// Uses DTR & RTS serial control lines to try to reset the chip into + /// bootloader mode. #[default] DefaultReset, - /// Skips DTR/RTS control signal assignments and just start sending a serial synchronisation command to the chip. + /// Skips DTR/RTS control signal assignments and just start sending a serial + /// synchronisation command to the chip. NoReset, - /// Skips DTR/RTS control signal assignments and also skips the serial synchronization command. + /// Skips DTR/RTS control signal assignments and also skips the serial + /// synchronization command. NoResetNoSync, /// Reset sequence for USB-JTAG-Serial peripheral UsbReset, @@ -338,13 +336,10 @@ pub enum ResetBeforeOperation { )] #[non_exhaustive] pub enum ResetAfterOperation { - /// The DTR serial control line is used to reset the chip into a normal boot sequence. + /// The DTR serial control line is used to reset the chip into a normal boot + /// sequence. #[default] HardReset, - /// Runs the user firmware, but any subsequent reset will return to the serial bootloader. - /// - /// Only supported on ESP8266. - SoftReset, /// Leaves the chip in the serial bootloader, no reset is performed. NoReset, /// Leaves the chip in the stub bootloader, no reset is performed. diff --git a/espflash/src/error.rs b/espflash/src/error.rs index fe1fa16a..740c18bd 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -165,10 +165,6 @@ pub enum Error { )] SerialNotFound(String), - #[error("Soft reseting is currently only supported on ESP8266")] - #[diagnostic(code(espflash::soft_reset_not_available))] - SoftResetNotAvailable, - #[error("Unrecognized image format '{0}'")] #[diagnostic( code(espflash::unknown_format), diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index a6dc82b6..41367b59 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -49,8 +49,6 @@ pub(crate) const FLASH_WRITE_SIZE: usize = 0x400; const CHIP_DETECT_MAGIC_REG_ADDR: u32 = 0x40001000; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(3); const EXPECTED_STUB_HANDSHAKE: &str = "OHAI"; -const FLASH_BLOCK_SIZE: usize = 0x100; -const FLASH_SECTORS_PER_BLOCK: usize = FLASH_SECTOR_SIZE / FLASH_BLOCK_SIZE; /// Supported flash frequencies /// @@ -180,37 +178,22 @@ impl FlashSize { /// Encodes flash size into the format used by the bootloader. /// /// ## Values: - /// * [ESP8266](https://docs.espressif.com/projects/esptool/en/latest/esp8266/advanced-topics/firmware-image-format.html#file-header) - /// * [Others](https://docs.espressif.com/projects/esptool/en/latest/esp32s3/advanced-topics/firmware-image-format.html#file-header) - pub const fn encode_flash_size(self: FlashSize, chip: Chip) -> Result { + /// + /// * https://docs.espressif.com/projects/esptool/en/latest/esp32s3/advanced-topics/firmware-image-format.html#file-header + pub const fn encode_flash_size(self: FlashSize) -> Result { use FlashSize::*; - let encoded = match chip { - Chip::Esp8266 => match self { - _256Kb => 1, - _512Kb => 0, - _1Mb => 2, - _2Mb => 3, - _4Mb => 4, - // Currently not supported - // _2Mb_c1 => 5, - // _4Mb_c1 => 6, - _8Mb => 8, - _16Mb => 9, - _ => return Err(Error::UnsupportedFlash(self as u8)), - }, - _ => match self { - _1Mb => 0, - _2Mb => 1, - _4Mb => 2, - _8Mb => 3, - _16Mb => 4, - _32Mb => 5, - _64Mb => 6, - _128Mb => 7, - _256Mb => 8, - _ => return Err(Error::UnsupportedFlash(self as u8)), - }, + let encoded = match self { + _1Mb => 0, + _2Mb => 1, + _4Mb => 2, + _8Mb => 3, + _16Mb => 4, + _32Mb => 5, + _64Mb => 6, + _128Mb => 7, + _256Mb => 8, + _ => return Err(Error::UnsupportedFlash(self as u8)), }; Ok(encoded) @@ -672,14 +655,9 @@ impl Flasher { // Now that we have established a connection and detected the chip and flash // size, we can set the baud rate of the connection to the configured value. if let Some(baud) = speed { - match flasher.chip { - Chip::Esp8266 => (), // Not available - _ => { - if baud > 115_200 { - warn!("Setting baud rate higher than 115,200 can cause issues"); - flasher.change_baud(baud)?; - } - } + if baud > 115_200 { + warn!("Setting baud rate higher than 115,200 can cause issues"); + flasher.change_baud(baud)?; } } @@ -828,27 +806,15 @@ impl Flasher { } fn enable_flash(&mut self, spi_params: SpiAttachParams) -> Result<(), Error> { - match self.chip { - Chip::Esp8266 => { - self.connection.command(Command::FlashBegin { - supports_encryption: false, - offset: 0, - block_size: FLASH_WRITE_SIZE as u32, - size: 0, - blocks: 0, - })?; - } - _ => { - self.connection - .with_timeout(CommandType::SpiAttach.timeout(), |connection| { - connection.command(if self.use_stub { - Command::SpiAttachStub { spi_params } - } else { - Command::SpiAttach { spi_params } - }) - })?; - } - } + self.connection + .with_timeout(CommandType::SpiAttach.timeout(), |connection| { + connection.command(if self.use_stub { + Command::SpiAttachStub { spi_params } + } else { + Command::SpiAttach { spi_params } + }) + })?; + Ok(()) } @@ -955,14 +921,7 @@ impl Flasher { let chip = self.chip(); let target = chip.into_target(); - // The ESP8266 does not have readable major/minor revision numbers, so we have - // nothing to return if targeting it. - let revision = if chip != Chip::Esp8266 { - Some(target.chip_revision(self.connection())?) - } else { - None - }; - + let revision = Some(target.chip_revision(self.connection())?); let crystal_frequency = target.crystal_freq(self.connection())?; let features = target .chip_features(self.connection())? @@ -1028,17 +987,11 @@ impl Flasher { .flash_target(self.spi_params, self.use_stub, self.verify, self.skip); target.begin(&mut self.connection).flashing()?; - // The ESP8266 does not have readable major/minor revision numbers, so we have - // nothing to return if targeting it. - let chip_revision = if self.chip != Chip::Esp8266 { - Some( - self.chip - .into_target() - .chip_revision(&mut self.connection)?, - ) - } else { - None - }; + let chip_revision = Some( + self.chip + .into_target() + .chip_revision(&mut self.connection)?, + ); let image = self.chip.into_target().get_flash_image( &image, @@ -1266,22 +1219,6 @@ impl Flasher { } } -pub(crate) fn get_erase_size(offset: usize, size: usize) -> usize { - let sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; - let start_sector = offset / FLASH_SECTOR_SIZE; - - let head_sectors = usize::min( - FLASH_SECTORS_PER_BLOCK - (start_sector % FLASH_SECTORS_PER_BLOCK), - sector_count, - ); - - if sector_count < 2 * head_sectors { - (sector_count + 1) / 2 * FLASH_SECTOR_SIZE - } else { - (sector_count - head_sectors) * FLASH_SECTOR_SIZE - } -} - pub(crate) fn checksum(data: &[u8], mut checksum: u8) -> u8 { for byte in data { checksum ^= *byte; diff --git a/espflash/src/flasher/stubs.rs b/espflash/src/flasher/stubs.rs index d0fe47a9..bee3c3c0 100644 --- a/espflash/src/flasher/stubs.rs +++ b/espflash/src/flasher/stubs.rs @@ -27,7 +27,6 @@ const STUB_32H2: &str = include_str!("../../resources/stubs/stub_flasher_32h2.to const STUB_32P4: &str = include_str!("../../resources/stubs/stub_flasher_32p4.toml"); const STUB_32S2: &str = include_str!("../../resources/stubs/stub_flasher_32s2.toml"); const STUB_32S3: &str = include_str!("../../resources/stubs/stub_flasher_32s3.toml"); -const STUB_8266: &str = include_str!("../../resources/stubs/stub_flasher_8266.toml"); impl FlashStub { /// Fetch flash stub for the provided chip @@ -41,7 +40,6 @@ impl FlashStub { Chip::Esp32p4 => STUB_32P4, Chip::Esp32s2 => STUB_32S2, Chip::Esp32s3 => STUB_32S3, - Chip::Esp8266 => STUB_8266, }; let stub: FlashStub = toml::from_str(s).unwrap(); diff --git a/espflash/src/image_format/esp8266.rs b/espflash/src/image_format/esp8266.rs deleted file mode 100644 index 39d4f001..00000000 --- a/espflash/src/image_format/esp8266.rs +++ /dev/null @@ -1,187 +0,0 @@ -use std::{borrow::Cow, io::Write, iter::once, mem::size_of}; - -use bytemuck::bytes_of; - -use crate::{ - elf::{CodeSegment, FirmwareImage, RomSegment}, - error::Error, - flasher::FlashSettings, - image_format::{ - update_checksum, ImageFormat, ImageHeader, SegmentHeader, ESP_CHECKSUM_MAGIC, ESP_MAGIC, - }, - targets::Chip, -}; - -/// Image format for flashing to the ESP8266 -pub struct Esp8266Format<'a> { - irom_data: Option>, - flash_segment: RomSegment<'a>, - app_size: u32, -} - -impl<'a> Esp8266Format<'a> { - pub fn new( - image: &'a dyn FirmwareImage<'a>, - flash_settings: FlashSettings, - ) -> Result { - // IROM goes into a separate plain binary - let irom_data = merge_rom_segments(image.rom_segments(Chip::Esp8266)); - - let mut common_data = Vec::with_capacity( - image - .ram_segments(Chip::Esp8266) - .map(|segment| segment.size() as usize) - .sum(), - ); - - // Common header - let flash_mode = flash_settings.mode.unwrap_or_default() as u8; - let segment_count = image.ram_segments(Chip::Esp8266).count() as u8; - - let mut header = ImageHeader { - magic: ESP_MAGIC, - segment_count, - flash_mode, - entry: image.entry(), - ..Default::default() - }; - header.write_flash_config( - flash_settings.size.unwrap_or_default(), - flash_settings.freq.unwrap_or_default(), - Chip::Esp8266, - )?; - - // Esp8266 does not have extended header - let mut total_len = ImageHeader::COMMON_HEADER_LEN; - common_data.write_all(&bytes_of(&header)[0..total_len as usize])?; - - let mut checksum = ESP_CHECKSUM_MAGIC; - - for segment in image.ram_segments(Chip::Esp8266) { - let data = segment.data(); - let padding = 4 - data.len() % 4; - - let segment_header = SegmentHeader { - addr: segment.addr, - length: (data.len() + padding) as u32, - }; - - total_len += size_of::() as u32 + segment_header.length; - - common_data.write_all(bytes_of(&segment_header))?; - common_data.write_all(data)?; - - let padding = &[0u8; 4][0..padding]; - common_data.write_all(padding)?; - - checksum = update_checksum(data, checksum); - } - - let padding = 15 - (total_len % 16); - let padding = &[0u8; 16][0..padding as usize]; - - common_data.write_all(padding)?; - common_data.write_all(&[checksum])?; - - let flash_segment = RomSegment { - addr: 0, - data: Cow::Owned(common_data), - }; - - let app_size = irom_data - .clone() - .map(|d| d.data.len() as u32) - .unwrap_or_default() - + flash_segment.data.len() as u32; - - Ok(Self { - irom_data, - flash_segment, - app_size, - }) - } -} - -impl<'a> ImageFormat<'a> for Esp8266Format<'a> { - fn flash_segments<'b>(&'b self) -> Box> + 'b> - where - 'a: 'b, - { - Box::new( - self.irom_data - .iter() - .map(RomSegment::borrow) - .chain(once(self.flash_segment.borrow())), - ) - } - - fn ota_segments<'b>(&'b self) -> Box> + 'b> - where - 'a: 'b, - { - Box::new( - self.irom_data - .iter() - .map(RomSegment::borrow) - .chain(once(self.flash_segment.borrow())), - ) - } - - fn app_size(&self) -> u32 { - self.app_size - } - - fn part_size(&self) -> Option { - None - } -} - -fn merge_rom_segments<'a>( - mut segments: impl Iterator>, -) -> Option> { - const IROM_MAP_START: u32 = 0x4020_0000; - - let first = segments.next()?; - let data = if let Some(second) = segments.next() { - let mut data = Vec::with_capacity(first.data().len() + second.data().len()); - data.extend_from_slice(first.data()); - - for segment in once(second).chain(segments) { - let padding_size = segment.addr as usize - first.addr as usize - data.len(); - data.resize(data.len() + padding_size, 0); - data.extend_from_slice(segment.data()); - } - - data - } else { - first.data().into() - }; - - Some(RomSegment { - addr: first.addr - IROM_MAP_START, - data: Cow::Owned(data), - }) -} - -#[cfg(test)] -mod tests { - use std::fs; - - use super::*; - use crate::elf::ElfFirmwareImage; - - #[test] - fn test_esp8266_image_format() { - let input_bytes = fs::read("tests/resources/esp8266_hal_blinky").unwrap(); - let expected_bin = fs::read("tests/resources/esp8266_hal_blinky.bin").unwrap(); - - let image = ElfFirmwareImage::try_from(input_bytes.as_slice()).unwrap(); - let flash_image = Esp8266Format::new(&image, FlashSettings::default()).unwrap(); - - let segments = flash_image.flash_segments().collect::>(); - let buf = segments[0].data.as_ref(); - - assert_eq!(expected_bin.len(), buf.len()); - assert_eq!(expected_bin.as_slice(), buf); - } -} diff --git a/espflash/src/image_format/mod.rs b/espflash/src/image_format/mod.rs index ade8c666..a49d52d2 100644 --- a/espflash/src/image_format/mod.rs +++ b/espflash/src/image_format/mod.rs @@ -1,9 +1,4 @@ -//! Supported binary image formats -//! -//! Since the ESP8266 is not supported by ESP-IDF, it has its own image format -//! which must be used. All other devices support the ESP-IDF bootloader format. -//! Certain devices additionally support direct boot, which needs its own unique -//! image format. +//! ESP-IDF application binary image format use std::str::FromStr; @@ -11,9 +6,7 @@ use bytemuck::{Pod, Zeroable}; use serde::Deserialize; use strum::{Display, EnumVariantNames, IntoStaticStr}; -pub use self::{ - direct_boot::DirectBootFormat, esp8266::Esp8266Format, idf_bootloader::IdfBootloaderFormat, -}; +pub use self::{direct_boot::DirectBootFormat, idf_bootloader::IdfBootloaderFormat}; use crate::{ elf::RomSegment, error::Error, @@ -22,7 +15,6 @@ use crate::{ }; mod direct_boot; -mod esp8266; mod idf_bootloader; const ESP_CHECKSUM_MAGIC: u8 = 0xef; @@ -87,11 +79,6 @@ impl Default for ImageHeader { } impl ImageHeader { - /// Header size without extended part. - /// - /// [ESP8266 header format](https://docs.espressif.com/projects/esptool/en/latest/esp8266/advanced-topics/firmware-image-format.html#file-header) - pub const COMMON_HEADER_LEN: u32 = 8; - /// Updates flash size and speed filed. pub fn write_flash_config( &mut self, @@ -99,7 +86,7 @@ impl ImageHeader { freq: FlashFrequency, chip: Chip, ) -> Result<(), Error> { - let flash_size = size.encode_flash_size(chip)?; + let flash_size = size.encode_flash_size()?; let flash_speed = freq.encode_flash_frequency(chip)?; // bit field diff --git a/espflash/src/targets/esp8266.rs b/espflash/src/targets/esp8266.rs deleted file mode 100644 index 5f5ffeed..00000000 --- a/espflash/src/targets/esp8266.rs +++ /dev/null @@ -1,142 +0,0 @@ -use std::ops::Range; - -#[cfg(feature = "serialport")] -use crate::{connection::Connection, targets::bytes_to_mac_addr}; -use crate::{ - elf::FirmwareImage, - error::{Error, UnsupportedImageFormatError}, - flasher::FlashData, - image_format::{Esp8266Format, ImageFormat, ImageFormatKind}, - targets::{Chip, ReadEFuse, SpiRegisters, Target, XtalFrequency}, -}; - -const CHIP_DETECT_MAGIC_VALUES: &[u32] = &[0xfff0_c101]; - -#[allow(clippy::single_range_in_vec_init)] -const FLASH_RANGES: &[Range] = &[ - 0x40200000..0x40300000, // IROM -]; - -const UART_CLKDIV_REG: u32 = 0x6000_0014; -const UART_CLKDIV_MASK: u32 = 0xfffff; - -const XTAL_CLK_DIVIDER: u32 = 2; - -/// ESP8266 Target -pub struct Esp8266; - -impl Esp8266 { - /// Check if the magic value contains the specified value - pub fn has_magic_value(value: u32) -> bool { - CHIP_DETECT_MAGIC_VALUES.contains(&value) - } -} - -impl ReadEFuse for Esp8266 { - fn efuse_reg(&self) -> u32 { - 0x3ff0_0050 - } -} - -impl Target for Esp8266 { - fn addr_is_flash(&self, addr: u32) -> bool { - FLASH_RANGES.iter().any(|range| range.contains(&addr)) - } - - #[cfg(feature = "serialport")] - fn chip_features(&self, _connection: &mut Connection) -> Result, Error> { - Ok(vec!["WiFi"]) - } - - #[cfg(feature = "serialport")] - fn major_chip_version(&self, _connection: &mut Connection) -> Result { - Err(Error::UnsupportedFeature { - chip: Chip::Esp8266, - feature: "reading the major chip version".into(), - }) - } - - #[cfg(feature = "serialport")] - fn minor_chip_version(&self, _connection: &mut Connection) -> Result { - Err(Error::UnsupportedFeature { - chip: Chip::Esp8266, - feature: "reading the minor chip version".into(), - }) - } - - #[cfg(feature = "serialport")] - fn crystal_freq(&self, connection: &mut Connection) -> Result { - let uart_div = connection.read_reg(UART_CLKDIV_REG)? & UART_CLKDIV_MASK; - let est_xtal = (connection.get_baud()? * uart_div) / 1_000_000 / XTAL_CLK_DIVIDER; - let norm_xtal = if est_xtal > 33 { - XtalFrequency::_40Mhz - } else { - XtalFrequency::_26Mhz - }; - - Ok(norm_xtal) - } - - fn get_flash_image<'a>( - &self, - image: &'a dyn FirmwareImage<'a>, - flash_data: FlashData, - _chip_revision: Option<(u32, u32)>, - _xtal_freq: XtalFrequency, - ) -> Result + 'a>, Error> { - let image_format = flash_data - .image_format - .unwrap_or(ImageFormatKind::EspBootloader); - - match image_format { - ImageFormatKind::EspBootloader => Ok(Box::new(Esp8266Format::new( - image, - flash_data.flash_settings, - )?)), - _ => Err(UnsupportedImageFormatError::new(image_format, Chip::Esp8266, None).into()), - } - } - - #[cfg(feature = "serialport")] - fn mac_address(&self, connection: &mut Connection) -> Result { - let word0 = self.read_efuse(connection, 0)?; - let word1 = self.read_efuse(connection, 1)?; - let word3 = self.read_efuse(connection, 3)?; - - // First determine the OUI portion of the MAC address - let mut bytes = if word3 != 0 { - vec![ - ((word3 >> 16) & 0xff) as u8, - ((word3 >> 8) & 0xff) as u8, - (word3 & 0xff) as u8, - ] - } else if ((word1 >> 16) & 0xff) == 0 { - vec![0x18, 0xfe, 0x34] - } else { - vec![0xac, 0xd0, 0x74] - }; - - // Add the remaining NIC portion of the MAC address - bytes.push(((word1 >> 8) & 0xff) as u8); - bytes.push((word1 & 0xff) as u8); - bytes.push(((word0 >> 24) & 0xff) as u8); - - Ok(bytes_to_mac_addr(&bytes)) - } - - fn spi_registers(&self) -> SpiRegisters { - SpiRegisters { - base: 0x6000_0200, - usr_offset: 0x1c, - usr1_offset: 0x20, - usr2_offset: 0x24, - w0_offset: 0x40, - mosi_length_offset: None, - miso_length_offset: None, - } - } - - fn supported_build_targets(&self) -> &[&str] { - &["xtensa-esp8266-none-elf"] - } -} diff --git a/espflash/src/targets/flash_target/esp32.rs b/espflash/src/targets/flash_target/esp32.rs index fba6d9fc..aa1f09a5 100644 --- a/espflash/src/targets/flash_target/esp32.rs +++ b/espflash/src/targets/flash_target/esp32.rs @@ -66,10 +66,11 @@ impl FlashTarget for Esp32Target { connection.command(command) })?; - // The stub usually disables these watchdog timers, however if we're not using the stub - // we need to disable them before flashing begins - // TODO: the stub doesn't appear to disable the watchdog on ESP32-S3, so we explicitly - // disable the watchdog here. + // The stub usually disables these watchdog timers, however if we're not using + // the stub we need to disable them before flashing begins. + // + // TODO: the stub doesn't appear to disable the watchdog on ESP32-S3, so we + // explicitly disable the watchdog here. if connection.get_usb_pid()? == USB_SERIAL_JTAG_PID { match self.chip { Chip::Esp32c3 => { @@ -252,7 +253,7 @@ impl FlashTarget for Esp32Target { } if reboot { - connection.reset_after(self.use_stub, self.chip)?; + connection.reset_after(self.use_stub)?; } Ok(()) diff --git a/espflash/src/targets/flash_target/esp8266.rs b/espflash/src/targets/flash_target/esp8266.rs deleted file mode 100644 index 275a088c..00000000 --- a/espflash/src/targets/flash_target/esp8266.rs +++ /dev/null @@ -1,96 +0,0 @@ -use crate::{ - command::{Command, CommandType}, - elf::RomSegment, - error::Error, - flasher::{get_erase_size, ProgressCallbacks, FLASH_WRITE_SIZE}, -}; -#[cfg(feature = "serialport")] -use crate::{connection::Connection, targets::FlashTarget}; - -/// Applications running from an ESP8266's flash -#[derive(Default)] -pub struct Esp8266Target; - -impl Esp8266Target { - pub fn new() -> Self { - Esp8266Target - } -} - -#[cfg(feature = "serialport")] -impl FlashTarget for Esp8266Target { - fn begin(&mut self, connection: &mut Connection) -> Result<(), Error> { - connection.command(Command::FlashBegin { - size: 0, - blocks: 0, - block_size: FLASH_WRITE_SIZE as u32, - offset: 0, - supports_encryption: false, - })?; - - Ok(()) - } - - fn write_segment( - &mut self, - connection: &mut Connection, - segment: RomSegment, - progress: &mut Option<&mut dyn ProgressCallbacks>, - ) -> Result<(), Error> { - let addr = segment.addr; - let block_count = (segment.data.len() + FLASH_WRITE_SIZE - 1) / FLASH_WRITE_SIZE; - - let erase_size = get_erase_size(addr as usize, segment.data.len()) as u32; - - connection.with_timeout( - CommandType::FlashBegin.timeout_for_size(erase_size), - |connection| { - connection.command(Command::FlashBegin { - size: erase_size, - blocks: block_count as u32, - block_size: FLASH_WRITE_SIZE as u32, - offset: addr, - supports_encryption: false, - }) - }, - )?; - - let chunks = segment.data.chunks(FLASH_WRITE_SIZE); - let num_chunks = chunks.len(); - - if let Some(cb) = progress.as_mut() { - cb.init(addr, num_chunks) - } - - for (i, block) in chunks.enumerate() { - connection.command(Command::FlashData { - sequence: i as u32, - pad_to: FLASH_WRITE_SIZE, - pad_byte: 0xff, - data: block, - })?; - - if let Some(cb) = progress.as_mut() { - cb.update(i + 1) - } - } - - if let Some(cb) = progress.as_mut() { - cb.finish() - } - - Ok(()) - } - - fn finish(&mut self, connection: &mut Connection, reboot: bool) -> Result<(), Error> { - connection.with_timeout(CommandType::FlashEnd.timeout(), |connection| { - connection.write_command(Command::FlashEnd { reboot: false }) - })?; - - if reboot { - connection.reset()?; - } - - Ok(()) - } -} diff --git a/espflash/src/targets/flash_target/mod.rs b/espflash/src/targets/flash_target/mod.rs index 3a76250d..505b3c93 100644 --- a/espflash/src/targets/flash_target/mod.rs +++ b/espflash/src/targets/flash_target/mod.rs @@ -1,13 +1,12 @@ use bytemuck::{Pod, Zeroable}; pub(crate) use self::ram::MAX_RAM_BLOCK_SIZE; -pub use self::{esp32::Esp32Target, esp8266::Esp8266Target, ram::RamTarget}; +pub use self::{esp32::Esp32Target, ram::RamTarget}; #[cfg(feature = "serialport")] use crate::connection::Connection; use crate::{elf::RomSegment, error::Error, flasher::ProgressCallbacks}; mod esp32; -mod esp8266; mod ram; #[cfg(feature = "serialport")] diff --git a/espflash/src/targets/mod.rs b/espflash/src/targets/mod.rs index 50c5f4a2..daea7cad 100644 --- a/espflash/src/targets/mod.rs +++ b/espflash/src/targets/mod.rs @@ -1,10 +1,8 @@ //! Flashable target devices //! -//! Different devices support different boot options; the ESP8266 does not use a -//! second-stage bootloader, nor does direct boot (only supported by certain -//! devices). All ESP32* devices support booting via the ESP-IDF bootloader. -//! It's also possible to write an application to and boot from RAM, where a -//! bootloader is obviously not required either. +//! All ESP32 devices support booting via the ESP-IDF bootloader. It's also +//! possible to write an application to and boot from RAM, where a bootloader is +//! obviously not required either. use std::collections::HashMap; @@ -23,8 +21,7 @@ pub use self::{ esp32p4::Esp32p4, esp32s2::Esp32s2, esp32s3::Esp32s3, - esp8266::Esp8266, - flash_target::{Esp32Target, Esp8266Target, RamTarget}, + flash_target::{Esp32Target, RamTarget}, }; #[cfg(feature = "serialport")] use crate::connection::Connection; @@ -46,7 +43,6 @@ mod esp32h2; mod esp32p4; mod esp32s2; mod esp32s3; -mod esp8266; mod flash_target; /// Supported crystal frequencies @@ -92,7 +88,6 @@ impl XtalFrequency { Chip::Esp32p4 => Self::_40Mhz, Chip::Esp32s2 => Self::_40Mhz, Chip::Esp32s3 => Self::_40Mhz, - Chip::Esp8266 => Self::_40Mhz, } } } @@ -119,8 +114,6 @@ pub enum Chip { Esp32s2, /// ESP32-S3 Esp32s3, - /// ESP8266 - Esp8266, } impl Chip { @@ -141,8 +134,6 @@ impl Chip { Ok(Chip::Esp32s2) } else if Esp32s3::has_magic_value(magic) { Ok(Chip::Esp32s3) - } else if Esp8266::has_magic_value(magic) { - Ok(Chip::Esp8266) } else { Err(Error::ChipDetectError(magic)) } @@ -158,7 +149,6 @@ impl Chip { Chip::Esp32p4 => Box::new(Esp32p4), Chip::Esp32s2 => Box::new(Esp32s2), Chip::Esp32s3 => Box::new(Esp32s3), - Chip::Esp8266 => Box::new(Esp8266), } } @@ -170,10 +160,7 @@ impl Chip { verify: bool, skip: bool, ) -> Box { - match self { - Chip::Esp8266 => Box::new(Esp8266Target::new()), - _ => Box::new(Esp32Target::new(*self, spi_params, use_stub, verify, skip)), - } + Box::new(Esp32Target::new(*self, spi_params, use_stub, verify, skip)) } #[cfg(feature = "serialport")] diff --git a/espflash/tests/README.md b/espflash/tests/README.md index 23716c9b..97269c91 100644 --- a/espflash/tests/README.md +++ b/espflash/tests/README.md @@ -29,17 +29,3 @@ The ELF file is located at `target/xtensa-esp32-none-elf/release/examples/blinky ```bash $ espflash save-image --chip=esp32 esp32_hal_blinky.bin esp32_hal_blinky ``` - -## ESP8266 - -```bash -$ git clone https://github.com/esp-rs/esp8266-hal -$ cd esp8266-hal/ -$ cargo build --release --example=blinky -``` - -The ELF file is located at `target/xtensa-esp8266-none-elf/release/examples/blinky` - -```bash -$ espflash save-image --chip=esp8266 esp8266_hal_blinky.bin esp8266_hal_blinky -```