Skip to content

Commit

Permalink
Use BufRead to avoid an intermediate copy
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Oct 23, 2023
1 parent 8df115d commit cc2be35
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 34 deletions.
5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ object-chain = "0.1.3"
bad-server = { path = "bad-server" }
defmt = { version = "=0.3.5" }
ufmt = "0.2.0"
slice-string = "0.7.0"
tinyvec = "1.6.0"

smoltcp = { version = "0.10.0", default-features = false, features = [
"dns-max-server-count-2",
Expand All @@ -54,7 +52,7 @@ smoltcp = { version = "0.10.0", default-features = false, features = [
[dependencies]
embassy-futures = { version = "0.1.0" }
embassy-executor = { workspace = true }
embassy-time = { version = "0.1.4", features = ["nightly", "unstable-traits"] }
embassy-time = { version = "0.1.5", features = ["nightly", "unstable-traits"] }

embedded-hal-old = { package = "embedded-hal", version = "0.2.7" }
embedded-io-async = { workspace = true }
Expand Down Expand Up @@ -135,7 +133,6 @@ norfs-esp32s3 = { workspace = true, optional = true, features = [
heapless = { workspace = true }
object-chain = { workspace = true }
ufmt = { workspace = true }
slice-string = { workspace = true, features = ["ufmt-impl"] }

logger = { workspace = true }
log = { workspace = true, optional = true }
Expand Down
39 changes: 18 additions & 21 deletions src/states/firmware_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::cell::Cell;

use embassy_futures::select::{select, Either};
use embassy_time::{Duration, Instant, Timer};
use embedded_io_async::Read;
use embedded_io_async::BufRead;
use reqwless::{request::Method, response::Status};
use ufmt::uwrite;

Expand Down Expand Up @@ -150,9 +150,7 @@ async fn do_update(context: &mut Context) -> UpdateResult {
};

let size = response.content_length;
let mut buffer = [0; 1024];

print_progress(context, &mut buffer, 0, size, None).await;
print_progress(context, 0, size, None).await;

if let Err(e) = ota.erase().await {
warn!("Failed to erase OTA: {}", e);
Expand All @@ -167,37 +165,37 @@ async fn do_update(context: &mut Context) -> UpdateResult {
let result = select(
async {
loop {
let received_buffer =
match Timeout::with(READ_TIMEOUT, reader.read(&mut buffer)).await {
Some(result) => match result {
Ok(0) => break None,
Ok(read) => &buffer[..read],
Err(e) => {
warn!("HTTP read error: {}", e);
break Some(UpdateError::DownloadFailed);
}
},
_ => break Some(UpdateError::DownloadTimeout),
};
let received_buffer = match Timeout::with(READ_TIMEOUT, reader.fill_buf()).await {
Some(result) => match result {
Ok(&[]) => break None,
Ok(read) => read,
Err(e) => {
warn!("HTTP read error: {}", e);
break Some(UpdateError::DownloadFailed);
}
},
_ => break Some(UpdateError::DownloadTimeout),
};

if let Err(e) = ota.write(received_buffer).await {
warn!("Failed to write OTA: {}", e);
break Some(UpdateError::WriteError);
}

received_since.set(received_since.get() + received_buffer.len())
let received_len = received_buffer.len();
received_since.set(received_since.get() + received_len);
reader.consume(received_len);
}
},
async {
let mut buffer = [0; 128];
loop {
Timer::after(Duration::from_millis(500)).await;
let received = received_since.take();
received_total += received;

let avg_speed = Throughput(received_total, started.elapsed());

print_progress(context, &mut buffer, received_total, size, Some(avg_speed)).await;
print_progress(context, received_total, size, Some(avg_speed)).await;
}
},
)
Expand All @@ -219,12 +217,11 @@ async fn do_update(context: &mut Context) -> UpdateResult {

async fn print_progress(
context: &mut Context,
message: &mut [u8],
current: usize,
size: Option<usize>,
speed: Option<Throughput>,
) {
let mut message = slice_string::SliceString::new(message);
let mut message = heapless::String::<128>::new();
if let Some(size) = size {
let progress = current * 100 / size;
unwrap!(uwrite!(message, "Downloading update: {}%", progress));
Expand Down
19 changes: 10 additions & 9 deletions src/states/throughput.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::cell::Cell;

use embassy_futures::select::{select, Either};
use embassy_time::{Duration, Instant, Timer};
use embedded_io_async::Read;
use embedded_io_async::BufRead;
use reqwless::{request::Method, response::Status};
use ufmt::{uwrite, uwriteln};

Expand Down Expand Up @@ -153,7 +153,6 @@ async fn run_test(context: &mut Context) -> TestResult {

let size = response.content_length;
let mut received_total = 0;
let mut buffer = [0; 1024];

let mut reader = response.body().reader();

Expand All @@ -162,10 +161,14 @@ async fn run_test(context: &mut Context) -> TestResult {
let result = select(
async {
loop {
match Timeout::with(READ_TIMEOUT, reader.read(&mut buffer)).await {
match Timeout::with(READ_TIMEOUT, reader.fill_buf()).await {
Some(result) => match result {
Ok(0) => break None,
Ok(read) => received_since.set(received_since.get() + read),
Ok(&[]) => break None,
Ok(read) => {
let read_len = read.len();
received_since.set(received_since.get() + read_len);
reader.consume(read_len);
}
Err(e) => {
warn!("HTTP read error: {}", e);
break Some(TestError::DownloadFailed);
Expand All @@ -177,7 +180,6 @@ async fn run_test(context: &mut Context) -> TestResult {
},
async {
let mut last_print = Instant::now();
let mut buffer = [0; 128];
loop {
Timer::after(Duration::from_millis(500)).await;
let received = received_since.take();
Expand All @@ -188,7 +190,7 @@ async fn run_test(context: &mut Context) -> TestResult {

last_print = Instant::now();

print_progress(context, &mut buffer, received_total, size, speed, avg_speed).await;
print_progress(context, received_total, size, speed, avg_speed).await;
}
},
)
Expand All @@ -206,13 +208,12 @@ async fn run_test(context: &mut Context) -> TestResult {

async fn print_progress(
context: &mut Context,
message: &mut [u8],
current: usize,
size: Option<usize>,
current_tp: Throughput,
average_tp: Throughput,
) {
let mut message = slice_string::SliceString::new(message);
let mut message = heapless::String::<128>::new();
if let Some(size) = size {
let progress = current * 100 / size;
unwrap!(uwriteln!(message, "Testing: {}%", progress));
Expand Down

0 comments on commit cc2be35

Please sign in to comment.