Skip to content

Commit c35728a

Browse files
jessebrahamMabezDevSergioGasquez
authored
Apply relevant Rust API guidelines (#915)
* Derive more traits on public types in `image_format` module * Don't leak `PartitionTable` type in public API * Derive more traits on public types in `command` module * fixups * impl Hash for things * fmt * wording consistency * feat: Udpate docstrings and derives * feat: Implement C-CONV * Derive more traits on public types in `flasher` module * docs: Add missing module documentation * docs: Udpate changelog * docs: Fix changelog --------- Co-authored-by: Scott Mabin <scott@mabez.dev> Co-authored-by: Sergio Gasquez <sergio.gasquez@gmail.com>
1 parent de3bbdc commit c35728a

File tree

17 files changed

+206
-157
lines changed

17 files changed

+206
-157
lines changed

CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131
- Add a `check-app-descriptor` bool option to `ImageArgs` and add the flag to `flash` command (#872)
3232
- `Connection::into_serial` to get the underlying port from the connection (#882)
3333
- All methods on the now removed `Target` & `ReadEFuse`, `UsbOtg` and `RtcWdtReset` traits have been implemented directly on (#891)
34-
- Update checks can now be skipped by setting the the `ESPFLASH_SKIP_UPDATE_CHECK` environment variable (#900)
34+
- Update checks can now be skipped by setting the `ESPFLASH_SKIP_UPDATE_CHECK` environment variable (#900)
3535
- `flash_write_size` and `max_ram_block_size` functions no longer take a connection parameter and return a Result type (#903)
3636
- `DefaultProgressCallback` which implements `ProgressCallbacks` but all methods are no-ops (#904)
37-
- Update checks can now be skipped by setting the `ESPFLASH_SKIP_UPDATE_CHECK` environment variable (#900)
3837
- `ProgressCallbacks` now has a `verifying` method to notify when post-flash checksum checking has begun (#908)
38+
- Implement `From<Connection> for Port` and both `From<Flasher> for Connection` and `Port` conversions (#915)
3939

4040
### Changed
4141

@@ -79,7 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7979
- Fixed typos in error variant names (#782)
8080
- Fix `read-flash` which didn't work with some lengths (#804)
8181
- espflash can now flash an ESP32-S2 in download mode over USB (#813)
82-
- Fixed a case where esplash transformed the firmware elf in a way that made it unbootable (#831)
82+
- Fixed a case where espflash transformed the firmware ELF in a way that made it unbootable (#831)
8383
- The app descriptor is now correctly placed in the front of the binary (#835)
8484
- espflash now extracts the MMU page size from the app descriptor (#835)
8585
- `ResetBeforeOperation` & `ResetAfterOperation` are now public, to allow the creation of a `Connection` (#895)

cargo-espflash/src/main.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ use espflash::{
1515
*,
1616
},
1717
flasher::FlashSize,
18-
image_format::{
19-
ImageFormat,
20-
ImageFormatKind,
21-
idf::{check_idf_bootloader, parse_partition_table},
22-
},
18+
image_format::{ImageFormat, ImageFormatKind, idf::check_idf_bootloader},
2319
logging::initialize_logger,
2420
target::{Chip, XtalFrequency},
2521
update::check_for_update,
@@ -419,7 +415,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
419415
monitor_args.elf = Some(build_ctx.artifact_path);
420416

421417
monitor(
422-
flasher.into_connection().into_serial(),
418+
flasher.into(),
423419
Some(&elf_data),
424420
pid,
425421
monitor_args,

espflash/src/bin/espflash.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ use espflash::{
1010
*,
1111
},
1212
flasher::FlashSize,
13-
image_format::{
14-
ImageFormat,
15-
ImageFormatKind,
16-
idf::{check_idf_bootloader, parse_partition_table},
17-
},
13+
image_format::{ImageFormat, ImageFormatKind, idf::check_idf_bootloader},
1814
logging::initialize_logger,
1915
target::{Chip, XtalFrequency},
2016
update::check_for_update,
@@ -332,7 +328,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> {
332328
monitor_args.elf = Some(args.image);
333329

334330
monitor(
335-
flasher.into_connection().into_serial(),
331+
flasher.into(),
336332
Some(&elf_data),
337333
pid,
338334
monitor_args,

espflash/src/cli/mod.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,7 @@ use crate::{
5050
FlashSize,
5151
Flasher,
5252
},
53-
image_format::{
54-
ImageFormat,
55-
ImageFormatKind,
56-
Metadata,
57-
idf::{IdfBootloaderFormat, parse_partition_table},
58-
},
53+
image_format::{ImageFormat, ImageFormatKind, Metadata, idf::IdfBootloaderFormat},
5954
target::{Chip, ProgressCallbacks, XtalFrequency},
6055
};
6156

@@ -660,7 +655,7 @@ pub fn serial_monitor(args: MonitorArgs, config: &Config) -> Result<()> {
660655
}
661656

662657
monitor(
663-
flasher.into_connection().into_serial(),
658+
flasher.into(),
664659
elf.as_deref(),
665660
pid,
666661
monitor_args,
@@ -996,6 +991,13 @@ pub fn partition_table(args: PartitionTableArgs) -> Result<()> {
996991
Ok(())
997992
}
998993

994+
/// Parse a [PartitionTable] from the provided path
995+
pub fn parse_partition_table(path: &Path) -> Result<PartitionTable, Error> {
996+
let data = fs::read(path).map_err(|e| Error::FileOpenError(path.display().to_string(), e))?;
997+
998+
Ok(PartitionTable::try_from(data)?)
999+
}
1000+
9991001
/// Pretty print a partition table
10001002
fn pretty_print(table: PartitionTable) {
10011003
let mut pretty = Table::new();
@@ -1162,7 +1164,7 @@ pub fn write_bin(args: WriteBinArgs, config: &Config) -> Result<()> {
11621164
monitor_args.monitor_baud = 74_880;
11631165
}
11641166
monitor(
1165-
flasher.into_connection().into_serial(),
1167+
flasher.into(),
11661168
None,
11671169
pid,
11681170
monitor_args,

espflash/src/command.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::{io::Write, mem::size_of, time::Duration};
44

55
use bytemuck::{Pod, Zeroable, bytes_of};
6+
use serde::{Deserialize, Serialize};
67
use strum::Display;
78

89
use crate::{
@@ -30,7 +31,7 @@ const SYNC_FRAME: [u8; 36] = [
3031
/// Types of commands that can be sent to a target device
3132
///
3233
/// <https://docs.espressif.com/projects/esptool/en/latest/esp32c3/advanced-topics/serial-protocol.html#supported-by-stub-loader-and-rom-loader>
33-
#[derive(Copy, Clone, Debug, Display)]
34+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display, Deserialize, Serialize)]
3435
#[non_exhaustive]
3536
#[repr(u8)]
3637
pub enum CommandType {
@@ -95,7 +96,7 @@ pub enum CommandType {
9596
}
9697

9798
/// The value of a command response.
98-
#[derive(Debug, Clone)]
99+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
99100
pub enum CommandResponseValue {
100101
/// A 32-bit value.
101102
ValueU32(u32),
@@ -154,7 +155,7 @@ impl TryInto<Vec<u8>> for CommandResponseValue {
154155
}
155156

156157
/// A response from a target device following a command.
157-
#[derive(Debug, Clone)]
158+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
158159
pub struct CommandResponse {
159160
/// The response byte.
160161
pub resp: u8,
@@ -215,7 +216,7 @@ impl CommandType {
215216
/// Available commands
216217
///
217218
/// See <https://docs.espressif.com/projects/esptool/en/latest/esp32c6/advanced-topics/serial-protocol.html#commands>
218-
#[derive(Copy, Clone, Debug)]
219+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
219220
#[non_exhaustive]
220221
pub enum Command<'a> {
221222
/// Begin flash download

espflash/src/connection/mod.rs

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub struct Connection {
6565
}
6666

6767
impl Connection {
68-
/// Create a new connection with a target device.
68+
/// Creates a new connection with a target device.
6969
pub fn new(
7070
serial: Port,
7171
port_info: UsbPortInfo,
@@ -84,7 +84,7 @@ impl Connection {
8484
}
8585
}
8686

87-
/// Initialize a connection with a device.
87+
/// Initializes a connection with a device.
8888
pub fn begin(&mut self) -> Result<(), Error> {
8989
let port_name = self.serial.name().unwrap_or_default();
9090
let reset_sequence = construct_reset_strategy_sequence(
@@ -109,7 +109,7 @@ impl Connection {
109109
)))
110110
}
111111

112-
/// Try to connect to a device.
112+
/// Connects to a device.
113113
fn connect_attempt(&mut self, reset_strategy: &dyn ResetStrategy) -> Result<(), Error> {
114114
// If we're doing no_sync, we're likely communicating as a pass through
115115
// with an intermediate device to the ESP32
@@ -187,7 +187,7 @@ impl Connection {
187187
)))
188188
}
189189

190-
/// Try to sync with the device for a given timeout.
190+
/// Syncs with a device.
191191
pub(crate) fn sync(&mut self) -> Result<(), Error> {
192192
self.with_timeout(CommandType::Sync.timeout(), |connection| {
193193
connection.command(Command::Sync)?;
@@ -221,14 +221,14 @@ impl Connection {
221221
Ok(())
222222
}
223223

224-
/// Reset the device.
224+
/// Resets the device.
225225
pub fn reset(&mut self) -> Result<(), Error> {
226226
reset_after_flash(&mut self.serial, self.port_info.pid)?;
227227

228228
Ok(())
229229
}
230230

231-
/// Reset the device taking into account the reset after argument.
231+
/// Resets the device taking into account the reset after argument.
232232
pub fn reset_after(&mut self, is_stub: bool, chip: Chip) -> Result<(), Error> {
233233
let pid = self.usb_pid();
234234

@@ -291,7 +291,7 @@ impl Connection {
291291
}
292292
}
293293

294-
/// Reset the device to flash mode.
294+
/// Resets the device to flash mode.
295295
pub fn reset_to_flash(&mut self, extra_delay: bool) -> Result<(), Error> {
296296
if self.is_using_usb_serial_jtag() {
297297
UsbJtagSerialReset.reset(&mut self.serial)
@@ -308,25 +308,25 @@ impl Connection {
308308
}
309309
}
310310

311-
/// Set timeout for the serial port.
311+
/// Sets the timeout for the serial port.
312312
pub fn set_timeout(&mut self, timeout: Duration) -> Result<(), Error> {
313313
self.serial.set_timeout(timeout)?;
314314
Ok(())
315315
}
316316

317-
/// Set baud rate for the serial port.
317+
/// Sets the baud rate for the serial port.
318318
pub fn set_baud(&mut self, baud: u32) -> Result<(), Error> {
319319
self.serial.set_baud_rate(baud)?;
320320
self.baud = baud;
321321
Ok(())
322322
}
323323

324-
/// Get the current baud rate of the serial port.
324+
/// Returns the current baud rate of the serial port.
325325
pub fn baud(&self) -> Result<u32, Error> {
326326
Ok(self.serial.baud_rate()?)
327327
}
328328

329-
/// Run a command with a timeout defined by the command type.
329+
/// Runs a command with a timeout defined by the command type.
330330
pub fn with_timeout<T, F>(&mut self, timeout: Duration, mut f: F) -> Result<T, Error>
331331
where
332332
F: FnMut(&mut Connection) -> Result<T, Error>,
@@ -346,7 +346,7 @@ impl Connection {
346346
result
347347
}
348348

349-
/// Read the response from a serial port.
349+
/// Reads the response from a serial port.
350350
pub fn read_flash_response(&mut self) -> Result<Option<CommandResponse>, Error> {
351351
let mut response = Vec::new();
352352

@@ -369,7 +369,7 @@ impl Connection {
369369
Ok(Some(header))
370370
}
371371

372-
/// Read the response from a serial port.
372+
/// Reads the response from a serial port.
373373
pub fn read_response(&mut self) -> Result<Option<CommandResponse>, Error> {
374374
match self.read(10)? {
375375
None => Ok(None),
@@ -432,7 +432,7 @@ impl Connection {
432432
}
433433
}
434434

435-
/// Write raw data to the serial port.
435+
/// Writes raw data to the serial port.
436436
pub fn write_raw(&mut self, data: u32) -> Result<(), Error> {
437437
let mut binding = Box::new(&mut self.serial);
438438
let serial = binding.as_mut();
@@ -445,7 +445,7 @@ impl Connection {
445445
Ok(())
446446
}
447447

448-
/// Write a command to the serial port.
448+
/// Writes a command to the serial port.
449449
pub fn write_command(&mut self, command: Command<'_>) -> Result<(), Error> {
450450
debug!("Writing command: {command:02x?}");
451451
let mut binding = Box::new(&mut self.serial);
@@ -460,7 +460,7 @@ impl Connection {
460460
Ok(())
461461
}
462462

463-
/// Write a command and reads the response.
463+
/// Writes a command and reads the response.
464464
pub fn command(&mut self, command: Command<'_>) -> Result<CommandResponseValue, Error> {
465465
let ty = command.command_type();
466466
self.write_command(command).for_command(ty)?;
@@ -495,7 +495,7 @@ impl Connection {
495495
)))
496496
}
497497

498-
/// Read a register command with a timeout.
498+
/// Reads a register command with a timeout.
499499
pub fn read_reg(&mut self, addr: u32) -> Result<u32, Error> {
500500
let resp = self.with_timeout(CommandType::ReadReg.timeout(), |connection| {
501501
connection.command(Command::ReadReg { address: addr })
@@ -504,7 +504,7 @@ impl Connection {
504504
resp.try_into()
505505
}
506506

507-
/// Write a register command with a timeout.
507+
/// Writes a register command with a timeout.
508508
pub fn write_reg(&mut self, addr: u32, value: u32, mask: Option<u32>) -> Result<(), Error> {
509509
self.with_timeout(CommandType::WriteReg.timeout(), |connection| {
510510
connection.command(Command::WriteReg {
@@ -517,7 +517,7 @@ impl Connection {
517517
Ok(())
518518
}
519519

520-
/// Read a register command with a timeout.
520+
/// Reads a register command with a timeout.
521521
pub(crate) fn read(&mut self, len: usize) -> Result<Option<Vec<u8>>, Error> {
522522
let mut tmp = Vec::with_capacity(1024);
523523
loop {
@@ -528,18 +528,18 @@ impl Connection {
528528
}
529529
}
530530

531-
/// Flush the serial port.
531+
/// Flushes the serial port.
532532
pub fn flush(&mut self) -> Result<(), Error> {
533533
self.serial.flush()?;
534534
Ok(())
535535
}
536536

537-
/// Turn a serial port into a [Port].
537+
/// Turns a serial port into a [Port].
538538
pub fn into_serial(self) -> Port {
539539
self.serial
540540
}
541541

542-
/// Get the USB PID of the serial port.
542+
/// Returns the USB PID of the serial port.
543543
pub fn usb_pid(&self) -> u16 {
544544
self.port_info.pid
545545
}
@@ -559,7 +559,7 @@ impl Connection {
559559
self.before_operation
560560
}
561561

562-
/// Detect which chip is connected to this connection
562+
/// Detects which chip is connected to this connection.
563563
pub fn detect_chip(
564564
&mut self,
565565
use_stub: bool,
@@ -580,15 +580,24 @@ impl Connection {
580580
}
581581
}
582582

583+
impl From<Connection> for Port {
584+
fn from(conn: Connection) -> Self {
585+
conn.into_serial()
586+
}
587+
}
588+
583589
mod encoder {
584590
use std::io::Write;
585591

592+
use serde::Serialize;
593+
586594
const END: u8 = 0xC0;
587595
const ESC: u8 = 0xDB;
588596
const ESC_END: u8 = 0xDC;
589597
const ESC_ESC: u8 = 0xDD;
590598

591599
/// Encoder for the SLIP protocol.
600+
#[derive(Debug, PartialEq, Eq, Serialize, Hash)]
592601
pub struct SlipEncoder<'a, W: Write> {
593602
writer: &'a mut W,
594603
len: usize,
@@ -601,7 +610,7 @@ mod encoder {
601610
Ok(Self { writer, len })
602611
}
603612

604-
/// Finish the encoding.
613+
/// Finishes the encoding.
605614
pub fn finish(mut self) -> std::io::Result<usize> {
606615
self.len += self.writer.write(&[END])?;
607616
Ok(self.len)

0 commit comments

Comments
 (0)