Skip to content

Commit 1b23853

Browse files
[cargo-espflash]: Add write-bin subcommand (#789)
* feat: Add write-bin subcommand * docs: Update changelog * docs: Add docstring
1 parent e41be4f commit 1b23853

File tree

5 files changed

+48
-46
lines changed

5 files changed

+48
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Add `no-reset` flag to `monitor` subcommands (#737)
1414
- Add an environment variable to set monitoring baudrate (`MONITOR_BAUD`) (#737)
1515
- Add list-ports command to list available serial ports. (#761)
16+
- [cargo-espflash]: Add `write-bin` subcommand (#789)
1617

1718
### Changed
1819

cargo-espflash/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Commands:
7171
read-flash Read SPI flash content
7272
reset Reset the target device
7373
save-image Generate a binary application image and save it to a local disk
74+
write-bin Write a binary file to a specific address in a target device's flash
7475
help Print this message or the help of the given subcommand(s)
7576
7677
Options:

cargo-espflash/src/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ enum Commands {
117117
/// Otherwise, each segment will be saved as individual binaries, prefixed
118118
/// with their intended addresses in flash.
119119
SaveImage(SaveImageArgs),
120+
/// Write a binary file to a specific address in a target device's flash
121+
WriteBin(WriteBinArgs),
120122
}
121123

122124
#[derive(Debug, Args)]
@@ -240,6 +242,7 @@ fn main() -> Result<()> {
240242
Commands::ReadFlash(args) => read_flash(args, &config),
241243
Commands::Reset(args) => reset(args, &config),
242244
Commands::SaveImage(args) => save_image(args, &config),
245+
Commands::WriteBin(args) => write_bin(args, &config),
243246
}
244247
}
245248

espflash/src/bin/espflash.rs

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use std::{
2-
fs::{self, File},
3-
io::Read,
4-
path::PathBuf,
5-
};
1+
use std::{fs, path::PathBuf};
62

73
use clap::{Args, CommandFactory, Parser, Subcommand};
84
use espflash::{
@@ -140,20 +136,6 @@ struct SaveImageArgs {
140136
save_image_args: cli::SaveImageArgs,
141137
}
142138

143-
/// Writes a binary file to a specific address in the chip's flash
144-
#[derive(Debug, Args)]
145-
#[non_exhaustive]
146-
struct WriteBinArgs {
147-
/// Address at which to write the binary file
148-
#[arg(value_parser = parse_u32)]
149-
pub address: u32,
150-
/// File containing the binary data to write
151-
pub file: String,
152-
/// Connection configuration
153-
#[clap(flatten)]
154-
connect_args: ConnectArgs,
155-
}
156-
157139
fn main() -> Result<()> {
158140
miette::set_panic_hook();
159141
initialize_logger(LevelFilter::Info);
@@ -341,28 +323,3 @@ fn save_image(args: SaveImageArgs, config: &Config) -> Result<()> {
341323

342324
Ok(())
343325
}
344-
345-
fn write_bin(args: WriteBinArgs, config: &Config) -> Result<()> {
346-
let mut flasher = connect(&args.connect_args, config, false, false)?;
347-
print_board_info(&mut flasher)?;
348-
349-
let mut f = File::open(&args.file).into_diagnostic()?;
350-
351-
// If the file size is not divisible by 4, we need to pad `FF` bytes to the end
352-
let size = f.metadata().into_diagnostic()?.len();
353-
let mut padded_bytes = 0;
354-
if size % 4 != 0 {
355-
padded_bytes = 4 - (size % 4);
356-
}
357-
let mut buffer = Vec::with_capacity(size.try_into().into_diagnostic()?);
358-
f.read_to_end(&mut buffer).into_diagnostic()?;
359-
buffer.extend(std::iter::repeat(0xFF).take(padded_bytes as usize));
360-
361-
flasher.write_bin_to_flash(
362-
args.address,
363-
&buffer,
364-
Some(&mut EspflashProgress::default()),
365-
)?;
366-
367-
Ok(())
368-
}

espflash/src/cli/mod.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
1313
use std::{
1414
collections::HashMap,
15-
fs,
16-
io::Write,
15+
fs::{self, File},
16+
io::{Read, Write},
1717
num::ParseIntError,
1818
path::{Path, PathBuf},
1919
};
@@ -315,6 +315,20 @@ pub struct ListPortsArgs {
315315
pub name_only: bool,
316316
}
317317

318+
/// Writes a binary file to a specific address in the chip's flash
319+
#[derive(Debug, Args)]
320+
#[non_exhaustive]
321+
pub struct WriteBinArgs {
322+
/// Address at which to write the binary file
323+
#[arg(value_parser = parse_u32)]
324+
pub address: u32,
325+
/// File containing the binary data to write
326+
pub file: String,
327+
/// Connection configuration
328+
#[clap(flatten)]
329+
connect_args: ConnectArgs,
330+
}
331+
318332
/// Parses an integer, in base-10 or hexadecimal format, into a [u32]
319333
pub fn parse_u32(input: &str) -> Result<u32, ParseIntError> {
320334
let input: &str = &input.replace('_', "");
@@ -972,6 +986,32 @@ pub fn make_flash_data(
972986
)
973987
}
974988

989+
/// Write a binary to the flash memory of a target device
990+
pub fn write_bin(args: WriteBinArgs, config: &Config) -> Result<()> {
991+
let mut flasher = connect(&args.connect_args, config, false, false)?;
992+
print_board_info(&mut flasher)?;
993+
994+
let mut f = File::open(&args.file).into_diagnostic()?;
995+
996+
// If the file size is not divisible by 4, we need to pad `FF` bytes to the end
997+
let size = f.metadata().into_diagnostic()?.len();
998+
let mut padded_bytes = 0;
999+
if size % 4 != 0 {
1000+
padded_bytes = 4 - (size % 4);
1001+
}
1002+
let mut buffer = Vec::with_capacity(size.try_into().into_diagnostic()?);
1003+
f.read_to_end(&mut buffer).into_diagnostic()?;
1004+
buffer.extend(std::iter::repeat(0xFF).take(padded_bytes as usize));
1005+
1006+
flasher.write_bin_to_flash(
1007+
args.address,
1008+
&buffer,
1009+
Some(&mut EspflashProgress::default()),
1010+
)?;
1011+
1012+
Ok(())
1013+
}
1014+
9751015
mod test {
9761016
use clap::Parser;
9771017

0 commit comments

Comments
 (0)