Skip to content

Commit e3b65bf

Browse files
committed
Create a FirmwareImageBuilder which allows setting flash parameters
1 parent b5d1e01 commit e3b65bf

File tree

7 files changed

+142
-38
lines changed

7 files changed

+142
-38
lines changed

cargo-espflash/src/main.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use espflash::{
1212
board_info, connect, flash_elf_image, monitor::monitor, save_elf_as_image, ConnectOpts,
1313
FlashOpts,
1414
},
15-
Chip, Config, ImageFormatId,
15+
Chip, Config, FlashFrequency, FlashMode, FlashSize, ImageFormatId,
1616
};
1717
use miette::{IntoDiagnostic, Result, WrapErr};
1818

@@ -86,7 +86,7 @@ pub struct BuildOpts {
8686
#[derive(Parser)]
8787
pub struct SaveImageOpts {
8888
#[clap(flatten)]
89-
pub build_args: BuildOpts,
89+
pub build_opts: BuildOpts,
9090
/// File name to save the generated image to
9191
pub file: PathBuf,
9292
}
@@ -154,12 +154,16 @@ fn flash(
154154
.transpose()?
155155
.or(metadata.format);
156156

157+
// FIXME
157158
flash_elf_image(
158159
&mut flasher,
159160
&elf_data,
160161
bootloader,
161162
partition_table,
162163
image_format,
164+
None,
165+
None,
166+
None,
163167
)?;
164168
}
165169

@@ -282,7 +286,6 @@ fn build(
282286

283287
// If no target artifact was found, we don't have a path to return.
284288
let target_artifact = target_artifact.ok_or(Error::NoArtifact)?;
285-
286289
let artifact_path = target_artifact.executable.unwrap().into();
287290

288291
Ok(artifact_path)
@@ -294,7 +297,7 @@ fn save_image(
294297
cargo_config: CargoConfig,
295298
) -> Result<()> {
296299
let target = opts
297-
.build_args
300+
.build_opts
298301
.target
299302
.as_deref()
300303
.or_else(|| cargo_config.target())
@@ -303,18 +306,19 @@ fn save_image(
303306

304307
let chip = Chip::from_target(target).ok_or_else(|| Error::UnknownTarget(target.into()))?;
305308

306-
let path = build(&opts.build_args, &cargo_config, Some(chip))?;
309+
let path = build(&opts.build_opts, &cargo_config, Some(chip))?;
307310
let elf_data = fs::read(path).into_diagnostic()?;
308311

309312
let image_format = opts
310-
.build_args
313+
.build_opts
311314
.format
312315
.as_deref()
313316
.map(ImageFormatId::from_str)
314317
.transpose()?
315318
.or(metadata.format);
316319

317-
save_elf_as_image(chip, &elf_data, opts.file, image_format)?;
320+
// FIXME
321+
save_elf_as_image(chip, &elf_data, opts.file, image_format, None, None, None)?;
318322

319323
Ok(())
320324
}

espflash/src/chip/esp32/esp32.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,12 @@ impl Esp32 {
183183
fn test_esp32_rom() {
184184
use std::fs::read;
185185

186+
use crate::elf::FirmwareImageBuilder;
187+
186188
let input_bytes = read("./tests/data/esp32").unwrap();
187189
let expected_bin = read("./tests/data/esp32.bin").unwrap();
188190

189-
let image = FirmwareImage::from_data(&input_bytes).unwrap();
191+
let image = FirmwareImageBuilder::new(&input_bytes).build().unwrap();
190192
let flash_image = Esp32BootloaderFormat::new(&image, Chip::Esp32, PARAMS, None, None).unwrap();
191193

192194
let segments = flash_image.flash_segments().collect::<Vec<_>>();

espflash/src/chip/esp8266.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,12 @@ impl ReadEFuse for Esp8266 {
9090
fn test_esp8266_rom() {
9191
use std::fs::read;
9292

93+
use crate::elf::FirmwareImageBuilder;
94+
9395
let input_bytes = read("./tests/data/esp8266").unwrap();
9496
let expected_bin = read("./tests/data/esp8266.bin").unwrap();
9597

96-
let image = FirmwareImage::from_data(&input_bytes).unwrap();
98+
let image = FirmwareImageBuilder::new(&input_bytes).build().unwrap();
9799
let flash_image = Esp8266Format::new(&image).unwrap();
98100

99101
let segments = flash_image.flash_segments().collect::<Vec<_>>();

espflash/src/cli/mod.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ use miette::{IntoDiagnostic, Result, WrapErr};
1313
use serialport::{FlowControl, SerialPortType};
1414

1515
use crate::{
16-
cli::serial::get_serial_port_info, error::Error, Chip, FirmwareImage, Flasher, ImageFormatId,
17-
PartitionTable,
16+
cli::serial::get_serial_port_info,
17+
elf::{FirmwareImageBuilder, FlashFrequency, FlashMode},
18+
error::Error,
19+
flasher::FlashSize,
20+
Chip, Flasher, ImageFormatId, PartitionTable,
1821
};
1922

2023
pub mod config;
@@ -82,8 +85,15 @@ pub fn save_elf_as_image(
8285
elf_data: &[u8],
8386
path: PathBuf,
8487
image_format: Option<ImageFormatId>,
88+
flash_mode: Option<FlashMode>,
89+
flash_size: Option<FlashSize>,
90+
flash_freq: Option<FlashFrequency>,
8591
) -> Result<()> {
86-
let image = FirmwareImage::from_data(elf_data)?;
92+
let image = FirmwareImageBuilder::new(elf_data)
93+
.flash_mode(flash_mode)
94+
.flash_size(flash_size)
95+
.flash_freq(flash_freq)
96+
.build()?;
8797

8898
let flash_image = chip.get_flash_image(&image, None, None, image_format, None)?;
8999
let parts: Vec<_> = flash_image.ota_segments().collect();
@@ -107,6 +117,9 @@ pub fn flash_elf_image(
107117
bootloader: Option<&Path>,
108118
partition_table: Option<&Path>,
109119
image_format: Option<ImageFormatId>,
120+
flash_mode: Option<FlashMode>,
121+
flash_size: Option<FlashSize>,
122+
flash_freq: Option<FlashFrequency>,
110123
) -> Result<()> {
111124
// If the '--bootloader' option is provided, load the binary file at the
112125
// specified path.
@@ -137,7 +150,15 @@ pub fn flash_elf_image(
137150

138151
// Load the ELF data, optionally using the provider bootloader/partition
139152
// table/image format, to the device's flash memory.
140-
flasher.load_elf_to_flash_with_format(elf_data, bootloader, partition_table, image_format)?;
153+
flasher.load_elf_to_flash_with_format(
154+
elf_data,
155+
bootloader,
156+
partition_table,
157+
image_format,
158+
flash_mode,
159+
flash_size,
160+
flash_freq,
161+
)?;
141162
println!("\nFlashing has completed!");
142163

143164
Ok(())

espflash/src/elf.rs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,18 +85,18 @@ pub struct FirmwareImage<'a> {
8585
}
8686

8787
impl<'a> FirmwareImage<'a> {
88-
pub fn from_data(data: &'a [u8]) -> Result<Self, Error> {
89-
let elf = ElfFile::new(data).map_err(ElfError::from)?;
90-
Ok(Self::from_elf(elf))
91-
}
92-
93-
pub fn from_elf(elf: ElfFile<'a>) -> Self {
94-
FirmwareImage {
88+
pub fn new(
89+
elf: ElfFile<'a>,
90+
flash_mode: FlashMode,
91+
flash_size: FlashSize,
92+
flash_frequency: FlashFrequency,
93+
) -> Self {
94+
Self {
9595
entry: elf.header.pt2.entry_point() as u32,
9696
elf,
97-
flash_mode: FlashMode::Dio,
98-
flash_size: FlashSize::Flash4Mb,
99-
flash_frequency: FlashFrequency::Flash40M,
97+
flash_mode,
98+
flash_size,
99+
flash_frequency,
100100
}
101101
}
102102

@@ -149,6 +149,51 @@ impl<'a> FirmwareImage<'a> {
149149
}
150150
}
151151

152+
pub struct FirmwareImageBuilder<'a> {
153+
data: &'a [u8],
154+
pub flash_mode: Option<FlashMode>,
155+
pub flash_size: Option<FlashSize>,
156+
pub flash_freq: Option<FlashFrequency>,
157+
}
158+
159+
impl<'a> FirmwareImageBuilder<'a> {
160+
pub fn new(data: &'a [u8]) -> Self {
161+
Self {
162+
data,
163+
flash_mode: None,
164+
flash_size: None,
165+
flash_freq: None,
166+
}
167+
}
168+
169+
pub fn flash_mode(mut self, flash_mode: Option<FlashMode>) -> Self {
170+
self.flash_mode = flash_mode;
171+
self
172+
}
173+
174+
pub fn flash_size(mut self, flash_size: Option<FlashSize>) -> Self {
175+
self.flash_size = flash_size;
176+
self
177+
}
178+
179+
pub fn flash_freq(mut self, flash_freq: Option<FlashFrequency>) -> Self {
180+
self.flash_freq = flash_freq;
181+
self
182+
}
183+
184+
pub fn build(&self) -> Result<FirmwareImage<'a>, Error> {
185+
let elf = ElfFile::new(self.data).map_err(ElfError::from)?;
186+
187+
let flash_mode = self.flash_mode.unwrap_or(FlashMode::Dio);
188+
let flash_size = self.flash_size.unwrap_or(FlashSize::Flash4Mb);
189+
let flash_freq = self.flash_freq.unwrap_or(FlashFrequency::Flash40M);
190+
191+
let image = FirmwareImage::new(elf, flash_mode, flash_size, flash_freq);
192+
193+
Ok(image)
194+
}
195+
}
196+
152197
#[derive(Eq, Clone, Default)]
153198
/// A segment of code from the source elf
154199
pub struct CodeSegment<'a> {
@@ -166,7 +211,8 @@ impl<'a> CodeSegment<'a> {
166211
segment
167212
}
168213

169-
/// Split of the first `count` bytes into a new segment, adjusting the remaining segment as needed
214+
/// Split of the first `count` bytes into a new segment, adjusting the
215+
/// remaining segment as needed
170216
pub fn split_off(&mut self, count: usize) -> Self {
171217
if count < self.data.len() {
172218
let (head, tail) = match take(&mut self.data) {

espflash/src/flasher.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
chip::Chip,
99
command::{Command, CommandType},
1010
connection::Connection,
11-
elf::{FirmwareImage, RomSegment},
11+
elf::{FirmwareImageBuilder, FlashFrequency, FlashMode, RomSegment},
1212
error::{ConnectionError, FlashDetectError, ResultExt},
1313
image_format::ImageFormatId,
1414
Error, PartitionTable,
@@ -376,15 +376,9 @@ impl Flasher {
376376
self.chip
377377
}
378378

379-
/// The flash size of the board that the flasher is connected to
380-
pub fn flash_size(&self) -> FlashSize {
381-
self.flash_size
382-
}
383-
384379
/// Read and print any information we can about the connected board
385380
pub fn board_info(&mut self) -> Result<(), Error> {
386381
let chip = self.chip();
387-
let size = self.flash_size();
388382

389383
let maybe_revision = chip.chip_revision(self.connection())?;
390384
let features = chip.chip_features(self.connection())?;
@@ -397,7 +391,7 @@ impl Flasher {
397391
None => println!(),
398392
}
399393
println!("Crystal frequency: {}MHz", freq);
400-
println!("Flash size: {}", size);
394+
println!("Flash size: {}", self.flash_size);
401395
println!("Features: {}", features.join(", "));
402396
println!("MAC address: {}", mac);
403397

@@ -408,7 +402,7 @@ impl Flasher {
408402
///
409403
/// Note that this will not touch the flash on the device
410404
pub fn load_elf_to_ram(&mut self, elf_data: &[u8]) -> Result<(), Error> {
411-
let image = FirmwareImage::from_data(elf_data)?;
405+
let image = FirmwareImageBuilder::new(elf_data).build()?;
412406

413407
let mut target = self.chip.ram_target();
414408
target.begin(&mut self.connection, &image).flashing()?;
@@ -439,9 +433,20 @@ impl Flasher {
439433
bootloader: Option<Vec<u8>>,
440434
partition_table: Option<PartitionTable>,
441435
image_format: Option<ImageFormatId>,
436+
flash_mode: Option<FlashMode>,
437+
flash_size: Option<FlashSize>,
438+
flash_freq: Option<FlashFrequency>,
442439
) -> Result<(), Error> {
443-
let mut image = FirmwareImage::from_data(elf_data)?;
444-
image.flash_size = self.flash_size();
440+
let mut builder = FirmwareImageBuilder::new(elf_data)
441+
.flash_mode(flash_mode)
442+
.flash_size(flash_size)
443+
.flash_freq(flash_freq);
444+
445+
if builder.flash_size.is_none() {
446+
builder = builder.flash_size(Some(self.flash_size));
447+
}
448+
449+
let image = builder.build()?;
445450

446451
let mut target = self.chip.flash_target(self.spi_params);
447452
target.begin(&mut self.connection, &image).flashing()?;
@@ -471,8 +476,19 @@ impl Flasher {
471476
elf_data: &[u8],
472477
bootloader: Option<Vec<u8>>,
473478
partition_table: Option<PartitionTable>,
479+
flash_mode: Option<FlashMode>,
480+
flash_size: Option<FlashSize>,
481+
flash_freq: Option<FlashFrequency>,
474482
) -> Result<(), Error> {
475-
self.load_elf_to_flash_with_format(elf_data, bootloader, partition_table, None)
483+
self.load_elf_to_flash_with_format(
484+
elf_data,
485+
bootloader,
486+
partition_table,
487+
None,
488+
flash_mode,
489+
flash_size,
490+
flash_freq,
491+
)
476492
}
477493

478494
pub fn change_baud(&mut self, speed: u32) -> Result<(), Error> {

espflash/src/main.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use espflash::{
66
board_info, connect, flash_elf_image, monitor::monitor, save_elf_as_image, ConnectOpts,
77
FlashOpts,
88
},
9-
Chip, Config, ImageFormatId,
9+
Chip, Config, FlashFrequency, FlashMode, FlashSize, ImageFormatId,
1010
};
1111
use miette::{IntoDiagnostic, Result, WrapErr};
1212

@@ -108,12 +108,16 @@ fn flash(opts: Opts, config: Config) -> Result<()> {
108108
.map(ImageFormatId::from_str)
109109
.transpose()?;
110110

111+
// FIXME
111112
flash_elf_image(
112113
&mut flasher,
113114
&elf_data,
114115
bootloader,
115116
partition_table,
116117
image_format,
118+
None,
119+
None,
120+
None,
117121
)?;
118122
}
119123

@@ -135,7 +139,16 @@ fn save_image(opts: SaveImageOpts) -> Result<()> {
135139
.map(ImageFormatId::from_str)
136140
.transpose()?;
137141

138-
save_elf_as_image(opts.chip, &elf_data, opts.file, image_format)?;
142+
// FIXME
143+
save_elf_as_image(
144+
opts.chip,
145+
&elf_data,
146+
opts.file,
147+
image_format,
148+
None,
149+
None,
150+
None,
151+
)?;
139152

140153
Ok(())
141154
}

0 commit comments

Comments
 (0)