fix some ota stuff
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use crate::{bail};
|
use crate::bail;
|
||||||
use crate::config::{NetworkConfig, PlantControllerConfig};
|
use crate::config::{NetworkConfig, PlantControllerConfig};
|
||||||
use crate::hal::{get_next_slot, PLANT_COUNT, TIME_ACCESS};
|
use crate::hal::{get_next_slot, PLANT_COUNT, TIME_ACCESS};
|
||||||
use crate::log::{LogMessage, LOG_ACCESS};
|
use crate::log::{LogMessage, LOG_ACCESS};
|
||||||
@@ -9,7 +9,7 @@ use crate::fat_error::{ContextExt, FatError, FatResult};
|
|||||||
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
|
use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem;
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use alloc::{format, string::String, vec::Vec};
|
use alloc::{format, string::String, vec, vec::Vec};
|
||||||
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use core::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
@@ -21,8 +21,8 @@ use embassy_sync::mutex::{Mutex, MutexGuard};
|
|||||||
use embassy_sync::once_lock::OnceLock;
|
use embassy_sync::once_lock::OnceLock;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash};
|
use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash};
|
||||||
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
|
|
||||||
use esp_bootloader_esp_idf::ota::OtaImageState::Valid;
|
use esp_bootloader_esp_idf::ota::OtaImageState::Valid;
|
||||||
|
use esp_bootloader_esp_idf::ota::{Ota, OtaImageState};
|
||||||
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
use esp_bootloader_esp_idf::partitions::FlashRegion;
|
||||||
use esp_hal::gpio::{Input, RtcPinWithResistors};
|
use esp_hal::gpio::{Input, RtcPinWithResistors};
|
||||||
use esp_hal::rng::Rng;
|
use esp_hal::rng::Rng;
|
||||||
@@ -128,7 +128,7 @@ pub struct Esp<'a> {
|
|||||||
pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>,
|
pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>,
|
||||||
|
|
||||||
pub ota: Ota<'static, FlashStorage>,
|
pub ota: Ota<'static, FlashStorage>,
|
||||||
pub ota_next: &'static mut FlashRegion<'static, FlashStorage>
|
pub ota_next: &'static mut FlashRegion<'static, FlashStorage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: On this target we never move Esp across OS threads; the firmware runs single-core
|
// SAFETY: On this target we never move Esp across OS threads; the firmware runs single-core
|
||||||
@@ -235,53 +235,32 @@ impl Esp<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn write_ota(
|
pub(crate) async fn write_ota(&mut self, offset: u32, buf: &[u8]) -> Result<(), FatError> {
|
||||||
&mut self,
|
|
||||||
offset: u32,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Result<(), FatError> {
|
|
||||||
if self.ota.current_ota_state() == Ok(OtaImageState::Invalid) {
|
if self.ota.current_ota_state() == Ok(OtaImageState::Invalid) {
|
||||||
bail!("Invalid OTA state, refusing ota write")
|
bail!("Invalid OTA state, refusing ota write")
|
||||||
}
|
}
|
||||||
if self.ota.current_ota_state() == Ok(OtaImageState::Undefined) {
|
if self.ota.current_ota_state() == Ok(OtaImageState::Undefined) {
|
||||||
bail!("Invalid OTA state, refusing ota write")
|
bail!("Invalid OTA state, refusing ota write")
|
||||||
}
|
}
|
||||||
|
let _ = check_erase(self.ota_next, offset, offset + 4096);
|
||||||
|
self.ota_next.erase(offset, offset + 4096)?;
|
||||||
|
|
||||||
let mut read_back = [0_u8; 1024];
|
let mut temp = vec![0; buf.len()];
|
||||||
let useful = &mut read_back[..buf.len()];
|
let read_back = temp.as_mut_slice();
|
||||||
//change to nor flash, align writes!
|
//change to nor flash, align writes!
|
||||||
self.ota_next.write(offset, buf)?;
|
self.ota_next.write(offset, buf)?;
|
||||||
self.ota_next.read(offset, useful)?;
|
self.ota_next.read(offset, read_back)?;
|
||||||
if buf != useful {
|
if buf != read_back {
|
||||||
info!("Expected {:?} but got {:?}", buf, useful);
|
info!("Expected {:?} but got {:?}", buf, read_back);
|
||||||
bail!("Flash error, read back does not match write buffer at offset {:x}", offset)
|
bail!(
|
||||||
|
"Flash error, read back does not match write buffer at offset {:x}",
|
||||||
|
offset
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn ota_erase(&mut self, block_start: u32) -> FatResult<()> {
|
pub(crate) async fn finalize_ota(&mut self) -> Result<(), FatError> {
|
||||||
// Ensure 4K block size and alignment
|
|
||||||
if self.ota_next.capacity() % 4096 != 0 {
|
|
||||||
bail!("Partition size is not a multiple of 4096")
|
|
||||||
}
|
|
||||||
if block_start % 4096 != 0 {
|
|
||||||
bail!("ota_erase called with unaligned block_start: {:x}", block_start)
|
|
||||||
}
|
|
||||||
let capacity = self.ota_next.capacity() as u32;
|
|
||||||
if block_start >= capacity {
|
|
||||||
bail!("ota_erase block_start out of range: {:x}", block_start)
|
|
||||||
}
|
|
||||||
let end = core::cmp::min(block_start + 4096, capacity);
|
|
||||||
// Check current erase state (will error if not erased); we ignore the result and erase anyway
|
|
||||||
let _ = check_erase(self.ota_next, block_start, end);
|
|
||||||
info!("erasing block {:x}-{:x}", block_start, end);
|
|
||||||
self.ota_next.erase(block_start, end)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn finalize_ota(
|
|
||||||
&mut self,
|
|
||||||
) -> Result<(), FatError> {
|
|
||||||
if self.ota.current_ota_state() == Ok(OtaImageState::Invalid) {
|
if self.ota.current_ota_state() == Ok(OtaImageState::Invalid) {
|
||||||
bail!("Invalid OTA state, refusing ota write")
|
bail!("Invalid OTA state, refusing ota write")
|
||||||
}
|
}
|
||||||
@@ -289,20 +268,19 @@ impl Esp<'_> {
|
|||||||
bail!("Invalid OTA state, refusing ota write")
|
bail!("Invalid OTA state, refusing ota write")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let current_state = self.ota.current_ota_state()?;
|
let current_state = self.ota.current_ota_state()?;
|
||||||
info!("current state {:?}", current_state);
|
info!("current state {:?}", current_state);
|
||||||
let next_slot = get_next_slot(&mut self.ota)?;
|
let next_slot = get_next_slot(&mut self.ota)?;
|
||||||
info!("current slot {:?}", next_slot.next());
|
info!("current slot {:?}", next_slot.next());
|
||||||
if current_state == OtaImageState::PendingVerify {
|
if current_state == OtaImageState::PendingVerify {
|
||||||
info!("verifying ota image from pending");
|
info!("verifying ota image from pending");
|
||||||
self.ota.set_current_ota_state(Valid)?;
|
self.ota.set_current_ota_state(Valid)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ota.set_current_slot(next_slot)?;
|
self.ota.set_current_slot(next_slot)?;
|
||||||
info!("switched slot");
|
info!("switched slot");
|
||||||
self.ota.set_current_ota_state(OtaImageState::New)?;
|
self.ota.set_current_ota_state(OtaImageState::New)?;
|
||||||
info!("switched state for new partition");
|
info!("switched state for new partition");
|
||||||
let state_new = self.ota.current_ota_state()?;
|
let state_new = self.ota.current_ota_state()?;
|
||||||
info!("state on new partition now {:?}", state_new);
|
info!("state on new partition now {:?}", state_new);
|
||||||
//determine nextslot crc
|
//determine nextslot crc
|
||||||
@@ -344,6 +322,7 @@ impl Esp<'_> {
|
|||||||
if ntp_addrs.is_empty() {
|
if ntp_addrs.is_empty() {
|
||||||
bail!("Failed to resolve DNS");
|
bail!("Failed to resolve DNS");
|
||||||
}
|
}
|
||||||
|
info!("NTP server: {:?}", ntp_addrs);
|
||||||
|
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
loop {
|
loop {
|
||||||
@@ -368,7 +347,6 @@ impl Esp<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub(crate) async fn wifi_scan(&mut self) -> FatResult<Vec<AccessPointInfo>> {
|
pub(crate) async fn wifi_scan(&mut self) -> FatResult<Vec<AccessPointInfo>> {
|
||||||
info!("start wifi scan");
|
info!("start wifi scan");
|
||||||
let mut lock = self.controller.try_lock()?;
|
let mut lock = self.controller.try_lock()?;
|
||||||
|
@@ -69,7 +69,9 @@ use eeprom24x::{Eeprom24x, SlaveAddr, Storage};
|
|||||||
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::blocking_mutex::CriticalSectionMutex;
|
use embassy_sync::blocking_mutex::CriticalSectionMutex;
|
||||||
use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry};
|
use esp_bootloader_esp_idf::partitions::{
|
||||||
|
AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry,
|
||||||
|
};
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
use esp_hal::gpio::{Input, InputConfig, Pull};
|
use esp_hal::gpio::{Input, InputConfig, Pull};
|
||||||
use measurements::{Current, Voltage};
|
use measurements::{Current, Voltage};
|
||||||
@@ -318,13 +320,12 @@ impl PlantHal {
|
|||||||
ota_data.as_embedded_storage(storage_ota)
|
ota_data.as_embedded_storage(storage_ota)
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut ota = esp_bootloader_esp_idf::ota::Ota::new(ota_data)?;
|
let mut ota = Ota::new(ota_data)?;
|
||||||
|
|
||||||
let state = ota.current_ota_state().unwrap_or_default();
|
let state = ota.current_ota_state().unwrap_or_default();
|
||||||
info!("Current OTA state: {:?}", state);
|
info!("Current OTA state: {:?}", state);
|
||||||
|
|
||||||
|
|
||||||
let next_slot = get_next_slot(&mut ota)?;
|
let next_slot = get_next_slot(&mut ota)?;
|
||||||
|
info!("Next OTA slot: {:?}", next_slot);
|
||||||
let ota_next = match next_slot {
|
let ota_next = match next_slot {
|
||||||
Slot::None => {
|
Slot::None => {
|
||||||
panic!("No OTA slot active?");
|
panic!("No OTA slot active?");
|
||||||
@@ -332,12 +333,13 @@ impl PlantHal {
|
|||||||
Slot::Slot0 => pt
|
Slot::Slot0 => pt
|
||||||
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||||
AppPartitionSubType::Ota0,
|
AppPartitionSubType::Ota0,
|
||||||
))?.context("Partition table invalid no ota0")?,
|
))?
|
||||||
|
.context("Partition table invalid no ota0")?,
|
||||||
Slot::Slot1 => pt
|
Slot::Slot1 => pt
|
||||||
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
.find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App(
|
||||||
AppPartitionSubType::Ota1,
|
AppPartitionSubType::Ota1,
|
||||||
))?.context("Partition table invalid no ota1")?
|
))?
|
||||||
,
|
.context("Partition table invalid no ota1")?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let ota_next = mk_static!(PartitionEntry, ota_next);
|
let ota_next = mk_static!(PartitionEntry, ota_next);
|
||||||
@@ -389,7 +391,7 @@ impl PlantHal {
|
|||||||
boot_button,
|
boot_button,
|
||||||
wake_gpio1,
|
wake_gpio1,
|
||||||
ota,
|
ota,
|
||||||
ota_next
|
ota_next,
|
||||||
};
|
};
|
||||||
|
|
||||||
//init,reset rtc memory depending on cause
|
//init,reset rtc memory depending on cause
|
||||||
@@ -569,24 +571,16 @@ impl PlantHal {
|
|||||||
|
|
||||||
Ok(Mutex::new(hal))
|
Ok(Mutex::new(hal))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_next_slot(ota: &mut Ota<FlashStorage>) -> Result<Slot, FatError> {
|
fn get_next_slot(ota: &mut Ota<FlashStorage>) -> Result<Slot, FatError> {
|
||||||
let next_slot = {
|
let next_slot = {
|
||||||
let state = ota.current_ota_state().unwrap_or_default();
|
let state = ota.current_ota_state().unwrap_or_default();
|
||||||
let current = ota.current_slot()?;
|
let current = ota.current_slot()?;
|
||||||
match state {
|
match state {
|
||||||
OtaImageState::New => {
|
OtaImageState::New => current.next(),
|
||||||
current.next()
|
OtaImageState::PendingVerify => current.next(),
|
||||||
}
|
OtaImageState::Valid => current.next(),
|
||||||
OtaImageState::PendingVerify => {
|
|
||||||
current.next()
|
|
||||||
}
|
|
||||||
OtaImageState::Valid => {
|
|
||||||
current.next()
|
|
||||||
}
|
|
||||||
OtaImageState::Invalid => {
|
OtaImageState::Invalid => {
|
||||||
//we actually booted other slot, than partition table assumes
|
//we actually booted other slot, than partition table assumes
|
||||||
current
|
current
|
||||||
@@ -623,4 +617,4 @@ pub async fn esp_set_time(time: DateTime<FixedOffset>) -> FatResult<()> {
|
|||||||
.get_rtc_module()
|
.get_rtc_module()
|
||||||
.set_rtc_time(&time.to_utc())
|
.set_rtc_time(&time.to_utc())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@@ -1096,6 +1096,7 @@ async fn get_version(
|
|||||||
let hash = &env!("VERGEN_GIT_SHA")[0..8];
|
let hash = &env!("VERGEN_GIT_SHA")[0..8];
|
||||||
|
|
||||||
let board = board.board_hal.get_esp();
|
let board = board.board_hal.get_esp();
|
||||||
|
|
||||||
let ota_slot = board.get_current_ota_slot();
|
let ota_slot = board.get_current_ota_slot();
|
||||||
let ota_state = board.get_ota_state();
|
let ota_state = board.get_ota_state();
|
||||||
VersionInfo {
|
VersionInfo {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
use crate::fat_error::{FatError, FatResult};
|
use crate::fat_error::{FatError, FatResult};
|
||||||
|
use crate::webserver::read_up_to_bytes_from_request;
|
||||||
use crate::BOARD_ACCESS;
|
use crate::BOARD_ACCESS;
|
||||||
use alloc::borrow::ToOwned;
|
use alloc::borrow::ToOwned;
|
||||||
use alloc::format;
|
use alloc::format;
|
||||||
@@ -118,9 +119,8 @@ where
|
|||||||
let mut offset = 0_usize;
|
let mut offset = 0_usize;
|
||||||
let mut chunk = 0;
|
let mut chunk = 0;
|
||||||
loop {
|
loop {
|
||||||
let mut buf = [0_u8; 4096];
|
let buf = read_up_to_bytes_from_request(conn, Some(4096)).await?;
|
||||||
let to_write = conn.read(&mut buf).await?;
|
if buf.len() == 0 {
|
||||||
if to_write == 0 {
|
|
||||||
info!("file request for {} finished", filename);
|
info!("file request for {} finished", filename);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -129,10 +129,10 @@ where
|
|||||||
board
|
board
|
||||||
.board_hal
|
.board_hal
|
||||||
.get_esp()
|
.get_esp()
|
||||||
.write_file(filename.to_owned(), offset as u32, &buf[0..to_write])
|
.write_file(filename.to_owned(), offset as u32, &buf)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
offset = offset + to_write;
|
offset = offset + buf.len();
|
||||||
chunk = chunk + 1;
|
chunk = chunk + 1;
|
||||||
}
|
}
|
||||||
BOARD_ACCESS
|
BOARD_ACCESS
|
||||||
|
@@ -5,8 +5,8 @@ mod file_manager;
|
|||||||
mod get_json;
|
mod get_json;
|
||||||
mod get_log;
|
mod get_log;
|
||||||
mod get_static;
|
mod get_static;
|
||||||
mod post_json;
|
|
||||||
mod ota;
|
mod ota;
|
||||||
|
mod post_json;
|
||||||
|
|
||||||
use crate::fat_error::{FatError, FatResult};
|
use crate::fat_error::{FatError, FatResult};
|
||||||
use crate::webserver::backup_manager::{backup_config, backup_info, get_backup_config};
|
use crate::webserver::backup_manager::{backup_config, backup_info, get_backup_config};
|
||||||
@@ -17,6 +17,7 @@ use crate::webserver::get_json::{
|
|||||||
};
|
};
|
||||||
use crate::webserver::get_log::get_log;
|
use crate::webserver::get_log::get_log;
|
||||||
use crate::webserver::get_static::{serve_bundle, serve_favicon, serve_index};
|
use crate::webserver::get_static::{serve_bundle, serve_favicon, serve_index};
|
||||||
|
use crate::webserver::ota::ota_operations;
|
||||||
use crate::webserver::post_json::{
|
use crate::webserver::post_json::{
|
||||||
board_test, night_lamp_test, pump_test, set_config, wifi_scan, write_time,
|
board_test, night_lamp_test, pump_test, set_config, wifi_scan, write_time,
|
||||||
};
|
};
|
||||||
@@ -37,7 +38,6 @@ use embassy_net::Stack;
|
|||||||
use embassy_time::Instant;
|
use embassy_time::Instant;
|
||||||
use embedded_io_async::{Read, Write};
|
use embedded_io_async::{Read, Write};
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use crate::webserver::ota::ota_operations;
|
|
||||||
// fn ota(
|
// fn ota(
|
||||||
// request: &mut Request<&mut EspHttpConnection>,
|
// request: &mut Request<&mut EspHttpConnection>,
|
||||||
// ) -> Result<Option<std::string::String>, anyhow::Error> {
|
// ) -> Result<Option<std::string::String>, anyhow::Error> {
|
||||||
@@ -109,11 +109,10 @@ impl Handler for HTTPRequestRouter {
|
|||||||
let status = if path.starts_with(prefix) {
|
let status = if path.starts_with(prefix) {
|
||||||
file_operations(conn, method, &path, &prefix).await?
|
file_operations(conn, method, &path, &prefix).await?
|
||||||
} else if path == "/ota" {
|
} else if path == "/ota" {
|
||||||
ota_operations(conn,method).await.map_err(|e| {
|
ota_operations(conn, method).await.map_err(|e| {
|
||||||
error!("Error handling ota: {}", e);
|
error!("Error handling ota: {}", e);
|
||||||
e
|
e
|
||||||
}
|
})?
|
||||||
)?
|
|
||||||
} else {
|
} else {
|
||||||
match method {
|
match method {
|
||||||
Method::Get => match path {
|
Method::Get => match path {
|
||||||
@@ -202,12 +201,18 @@ where
|
|||||||
let mut data_store = Vec::new();
|
let mut data_store = Vec::new();
|
||||||
let mut total_read = 0;
|
let mut total_read = 0;
|
||||||
loop {
|
loop {
|
||||||
|
let left = max_read - total_read;
|
||||||
let mut buf = [0_u8; 64];
|
let mut buf = [0_u8; 64];
|
||||||
let read = request.read(&mut buf).await?;
|
let s_buf = if buf.len() <= left {
|
||||||
|
&mut buf
|
||||||
|
} else {
|
||||||
|
&mut buf[0..left]
|
||||||
|
};
|
||||||
|
let read = request.read(s_buf).await?;
|
||||||
if read == 0 {
|
if read == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let actual_data = &buf[0..read];
|
let actual_data = &s_buf[0..read];
|
||||||
total_read += read;
|
total_read += read;
|
||||||
if total_read > max_read {
|
if total_read > max_read {
|
||||||
bail!("Request too large {total_read} > {max_read}");
|
bail!("Request too large {total_read} > {max_read}");
|
||||||
|
@@ -1,13 +1,14 @@
|
|||||||
|
use crate::fat_error::FatError;
|
||||||
|
use crate::webserver::read_up_to_bytes_from_request;
|
||||||
|
use crate::BOARD_ACCESS;
|
||||||
use edge_http::io::server::Connection;
|
use edge_http::io::server::Connection;
|
||||||
use edge_http::Method;
|
use edge_http::Method;
|
||||||
use embedded_io_async::{Read, Write};
|
use embedded_io_async::{Read, Write};
|
||||||
use log::info;
|
use log::info;
|
||||||
use crate::BOARD_ACCESS;
|
|
||||||
use crate::fat_error::FatError;
|
|
||||||
|
|
||||||
pub(crate) async fn ota_operations<T, const N: usize>(
|
pub(crate) async fn ota_operations<T, const N: usize>(
|
||||||
conn: &mut Connection<'_, T, { N }>,
|
conn: &mut Connection<'_, T, { N }>,
|
||||||
method: Method
|
method: Method,
|
||||||
) -> Result<Option<u32>, FatError>
|
) -> Result<Option<u32>, FatError>
|
||||||
where
|
where
|
||||||
T: Read + Write,
|
T: Read + Write,
|
||||||
@@ -23,7 +24,7 @@ where
|
|||||||
("Access-Control-Allow-Methods", "*"),
|
("Access-Control-Allow-Methods", "*"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Some(200)
|
Some(200)
|
||||||
}
|
}
|
||||||
Method::Post => {
|
Method::Post => {
|
||||||
@@ -33,9 +34,8 @@ where
|
|||||||
// Erase only a single 4K block right before writing into it.
|
// Erase only a single 4K block right before writing into it.
|
||||||
// The first block will be erased when offset == 0 below.
|
// The first block will be erased when offset == 0 below.
|
||||||
loop {
|
loop {
|
||||||
let mut buf = [0_u8; 1024];
|
let buf = read_up_to_bytes_from_request(conn, Some(4096)).await?;
|
||||||
let to_write = conn.read(&mut buf).await?;
|
if buf.len() == 0 {
|
||||||
if to_write == 0 {
|
|
||||||
info!("file request for ota finished");
|
info!("file request for ota finished");
|
||||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||||
board.board_hal.get_esp().finalize_ota().await?;
|
board.board_hal.get_esp().finalize_ota().await?;
|
||||||
@@ -44,17 +44,14 @@ where
|
|||||||
let mut board = BOARD_ACCESS.get().await.lock().await;
|
let mut board = BOARD_ACCESS.get().await.lock().await;
|
||||||
board.board_hal.progress(chunk as u32).await;
|
board.board_hal.progress(chunk as u32).await;
|
||||||
// Erase next block if we are at a 4K boundary (including the first block at offset 0)
|
// Erase next block if we are at a 4K boundary (including the first block at offset 0)
|
||||||
if offset % 4096 >= offset+to_write % 4096 {
|
info!("erasing and writing block 0x{offset:x}");
|
||||||
info!("erasing block {} during write between {} with size {}", offset / 4096, offset, to_write);
|
|
||||||
board.board_hal.get_esp().ota_erase(offset as u32).await?;
|
|
||||||
}
|
|
||||||
board
|
board
|
||||||
.board_hal
|
.board_hal
|
||||||
.get_esp()
|
.get_esp()
|
||||||
.write_ota(offset as u32, &buf[0..to_write])
|
.write_ota(offset as u32, &*buf)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
offset = offset + to_write;
|
offset = offset + buf.len();
|
||||||
chunk = chunk + 1;
|
chunk = chunk + 1;
|
||||||
}
|
}
|
||||||
BOARD_ACCESS
|
BOARD_ACCESS
|
||||||
@@ -74,7 +71,7 @@ where
|
|||||||
("Access-Control-Allow-Methods", "*"),
|
("Access-Control-Allow-Methods", "*"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Some(200)
|
Some(200)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
Reference in New Issue
Block a user