diff --git a/cfg.toml b/cfg.toml index 89828222..27211555 100644 --- a/cfg.toml +++ b/cfg.toml @@ -1,12 +1,12 @@ [esp-wifi] -rx_queue_size = 15 +rx_queue_size = 20 tx_queue_size = 5 -static_rx_buf_num = 8 +static_rx_buf_num = 32 dynamic_rx_buf_num = 16 static_tx_buf_num = 8 dynamic_tx_buf_num = 16 ampdu_rx_enable = 1 ampdu_tx_enable = 1 -rx_ba_win = 16 -max_burst_size = 4 +rx_ba_win = 32 +max_burst_size = 8 tick_rate_hz = 200 diff --git a/src/states/firmware_update.rs b/src/states/firmware_update.rs index acfdc7d3..ca57e075 100644 --- a/src/states/firmware_update.rs +++ b/src/states/firmware_update.rs @@ -1,4 +1,7 @@ -use embassy_time::{Duration, Instant}; +use core::cell::Cell; + +use embassy_futures::select::{select, Either}; +use embassy_time::{Duration, Instant, Timer}; use embedded_io::asynch::Read; use reqwless::{request::Method, response::Status}; use ufmt::uwrite; @@ -147,10 +150,9 @@ async fn do_update(context: &mut Context) -> UpdateResult { }; let size = response.content_length; - let mut total = 0; let mut buffer = [0; 512]; - print_progress(context, &mut buffer, total, size, None).await; + print_progress(context, &mut buffer, 0, size, None).await; if let Err(e) = ota.erase().await { warn!("Failed to erase OTA: {}", e); @@ -160,53 +162,59 @@ async fn do_update(context: &mut Context) -> UpdateResult { let mut reader = response.body().reader(); let started = Instant::now(); - let mut last_print = Instant::now(); - let mut received_1s = 0; - loop { - let received_buffer = match Timeout::with(READ_TIMEOUT, reader.read(&mut buffer)).await { - Some(result) => match result { - Ok(0) => break, - Ok(read) => &buffer[..read], - Err(e) => { - warn!("HTTP read error: {}", e); - return UpdateResult::Failed(UpdateError::DownloadFailed); + let received_since = Cell::new(0); + let mut received_total = 0; + 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), + }; + + if let Err(e) = ota.write(received_buffer).await { + warn!("Failed to write OTA: {}", e); + break Some(UpdateError::WriteError); } - }, - _ => return UpdateResult::Failed(UpdateError::DownloadTimeout), - }; - - if let Err(e) = ota.write(received_buffer).await { - warn!("Failed to write OTA: {}", e); - return UpdateResult::Failed(UpdateError::WriteError); - } - - total += received_buffer.len(); - received_1s += received_buffer.len(); - let elapsed = last_print.elapsed(); - if elapsed.as_millis() > 500 { - let speed = Throughput(received_1s, elapsed); - let avg_speed = Throughput(total, started.elapsed()); + received_since.set(received_since.get() + received_buffer.len()) + } + }, + async { + let mut buffer = [0; 128]; + loop { + Timer::after(Duration::from_millis(500)).await; + let received = received_since.take(); + received_total += received; - debug!( - "got {}B in {}ms {}", - received_1s, - elapsed.as_millis(), - speed - ); - last_print = Instant::now(); - received_1s = 0; + let avg_speed = Throughput(received_total, started.elapsed()); - print_progress(context, &mut buffer, total, size, Some(avg_speed)).await; + print_progress(context, &mut buffer, received_total, size, Some(avg_speed)).await; + } + }, + ) + .await; + + match result { + Either::First(Some(error)) => UpdateResult::Failed(error), + Either::First(None) => { + if let Err(e) = ota.activate().await { + warn!("Failed to activate OTA: {}", e); + UpdateResult::Failed(UpdateError::ActivateFailed) + } else { + UpdateResult::Success + } } + Either::Second(_) => unreachable!(), } - - if let Err(e) = ota.activate().await { - warn!("Failed to activate OTA: {}", e); - return UpdateResult::Failed(UpdateError::ActivateFailed); - } - - UpdateResult::Success } async fn print_progress( diff --git a/src/states/throughput.rs b/src/states/throughput.rs index 4ac11265..c7e93ca2 100644 --- a/src/states/throughput.rs +++ b/src/states/throughput.rs @@ -1,5 +1,7 @@ +use core::cell::Cell; + use embassy_futures::select::{select, Either}; -use embassy_time::{Duration, Instant}; +use embassy_time::{Duration, Instant, Timer}; use embedded_io::asynch::Read; use reqwless::{request::Method, response::Status}; use ufmt::{uwrite, uwriteln}; @@ -42,7 +44,7 @@ pub async fn throughput(context: &mut Context) -> AppState { TestResult::Success(speed) => { unwrap!(uwrite!( &mut message, - "Test complete. Average speed: {} KiB/s", + "Test complete. Average speed: {}", speed )); &message @@ -146,38 +148,50 @@ async fn run_test(context: &mut Context) -> TestResult { let mut reader = response.body().reader(); let started = Instant::now(); - let mut last_print = Instant::now(); - let mut received_1s = 0; - loop { - let received_len = match Timeout::with(READ_TIMEOUT, reader.read(&mut buffer)).await { - Some(result) => match result { - Ok(0) => break, - Ok(read) => read, - Err(e) => { - warn!("HTTP read error: {}", e); - return TestResult::Failed(TestError::DownloadFailed); - } - }, - _ => return TestResult::Failed(TestError::DownloadTimeout), - }; - - received_1s += received_len; - - let elapsed = last_print.elapsed(); - if elapsed.as_millis() > 500 { - received_total += received_1s; - - let speed = Throughput(received_1s, elapsed); - let avg_speed = Throughput(received_total, started.elapsed()); - - received_1s = 0; - last_print = Instant::now(); - - print_progress(context, &mut buffer, received_total, size, speed, avg_speed).await; - } - } + let received_since = Cell::new(0); + let result = select( + async { + loop { + match Timeout::with(READ_TIMEOUT, reader.read(&mut buffer)).await { + Some(result) => match result { + Ok(0) => break None, + Ok(read) => received_since.set(received_since.get() + read), + Err(e) => { + warn!("HTTP read error: {}", e); + break Some(TestError::DownloadFailed); + } + }, + _ => break Some(TestError::DownloadTimeout), + }; + } + }, + 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(); + received_total += received; - TestResult::Success(Throughput(received_total, started.elapsed())) + let speed = Throughput(received, last_print.elapsed()); + let avg_speed = Throughput(received_total, started.elapsed()); + + last_print = Instant::now(); + + print_progress(context, &mut buffer, received_total, size, speed, avg_speed).await; + } + }, + ) + .await; + + match result { + Either::First(Some(error)) => TestResult::Failed(error), + Either::First(None) => TestResult::Success(Throughput( + received_total + received_since.get(), + started.elapsed(), + )), + Either::Second(_) => unreachable!(), + } } async fn print_progress(