ota is back
This commit is contained in:
		| @@ -20,8 +20,9 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||||
| use embassy_sync::mutex::{Mutex, MutexGuard}; | ||||
| use embassy_sync::once_lock::OnceLock; | ||||
| use embassy_time::{Duration, Timer}; | ||||
| use embedded_storage::nor_flash::ReadNorFlash; | ||||
| use embedded_storage::nor_flash::{NorFlash, ReadNorFlash}; | ||||
| use esp_bootloader_esp_idf::ota::{Ota, OtaImageState}; | ||||
| use esp_bootloader_esp_idf::ota::OtaImageState::Valid; | ||||
| use esp_bootloader_esp_idf::partitions::FlashRegion; | ||||
| use esp_hal::gpio::{Input, RtcPinWithResistors}; | ||||
| use esp_hal::rng::Rng; | ||||
| @@ -29,6 +30,7 @@ use esp_hal::rtc_cntl::{ | ||||
|     sleep::{TimerWakeupSource, WakeupLevel}, | ||||
|     Rtc, | ||||
| }; | ||||
| use esp_hal::sha::Digest; | ||||
| use esp_hal::system::software_reset; | ||||
| use esp_println::println; | ||||
| use esp_storage::FlashStorage; | ||||
| @@ -127,7 +129,7 @@ pub struct Esp<'a> { | ||||
|     pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>, | ||||
|  | ||||
|     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 | ||||
| @@ -234,6 +236,28 @@ impl Esp<'_> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub(crate) async fn write_ota( | ||||
|         &mut self, | ||||
|         offset: u32, | ||||
|         buf: &[u8], | ||||
|     ) -> Result<(), FatError> { | ||||
|         self.ota_next.write(offset, buf)?; | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub(crate) async fn finalize_ota( | ||||
|         &mut self, | ||||
|     ) -> Result<(), FatError> { | ||||
|         let current_state = self.ota.current_ota_state()?; | ||||
|         let current_slot = self.ota.current_slot()?; | ||||
|         if current_state == OtaImageState::PendingVerify { | ||||
|             self.ota.set_current_ota_state(Valid)?; | ||||
|         } | ||||
|         self.ota.set_current_slot(current_slot.next())?; | ||||
|         self.set_restart_to_conf(true); | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     // let current = ota.current_slot()?; | ||||
|     // println!( | ||||
|     //     "current image state {:?} (only relevant if the bootloader was built with auto-rollback support)", | ||||
|   | ||||
| @@ -70,14 +70,12 @@ use eeprom24x::{Eeprom24x, SlaveAddr, Storage}; | ||||
| use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; | ||||
| use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | ||||
| use embassy_sync::blocking_mutex::CriticalSectionMutex; | ||||
| use esp_bootloader_esp_idf::partitions::{ | ||||
|     AppPartitionSubType, DataPartitionSubType, FlashRegion, PartitionEntry, | ||||
| }; | ||||
| use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, DataPartitionSubType, Error, FlashRegion, PartitionEntry}; | ||||
| use esp_hal::clock::CpuClock; | ||||
| use esp_hal::gpio::{Input, InputConfig, Pull}; | ||||
| use measurements::{Current, Voltage}; | ||||
|  | ||||
| use crate::fat_error::{FatError, FatResult}; | ||||
| use crate::fat_error::{ContextExt, FatError, FatResult}; | ||||
| use crate::hal::battery::{print_battery_bq34z100, BQ34Z100G1}; | ||||
| use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem; | ||||
| use crate::hal::water::TankSensor; | ||||
| @@ -87,6 +85,7 @@ use embassy_sync::once_lock::OnceLock; | ||||
| use esp_alloc as _; | ||||
| use esp_backtrace as _; | ||||
| use esp_bootloader_esp_idf::ota::Slot; | ||||
| use esp_bootloader_esp_idf::ota::Slot::{Slot0, Slot1}; | ||||
| use esp_hal::delay::Delay; | ||||
| use esp_hal::i2c::master::{BusTimeout, Config, I2c}; | ||||
| use esp_hal::pcnt::unit::Unit; | ||||
| @@ -323,23 +322,23 @@ impl PlantHal { | ||||
|  | ||||
|         let mut ota = esp_bootloader_esp_idf::ota::Ota::new(ota_data)?; | ||||
|  | ||||
|         let ota_partition = match ota.current_slot()? { | ||||
|         let next_slot = ota.current_slot()?.next(); | ||||
|         let ota_next = match next_slot { | ||||
|             Slot::None => { | ||||
|                 panic!("No OTA slot active?"); | ||||
|             } | ||||
|             Slot::Slot0 => pt | ||||
|                 .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App( | ||||
|                     AppPartitionSubType::Ota0, | ||||
|                 ))? | ||||
|                 .expect("No OTA slot0 found"), | ||||
|                 ))?.context("Partition table invalid no ota0")?, | ||||
|             Slot::Slot1 => pt | ||||
|                 .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App( | ||||
|                     AppPartitionSubType::Ota1, | ||||
|                 ))? | ||||
|                 .expect("No OTA slot1 found"), | ||||
|                 ))?.context("Partition table invalid no ota1")? | ||||
|                 , | ||||
|         }; | ||||
|  | ||||
|         let ota_next = mk_static!(PartitionEntry, ota_partition); | ||||
|         let ota_next = mk_static!(PartitionEntry, ota_next); | ||||
|         let storage_ota = mk_static!(FlashStorage, FlashStorage::new()); | ||||
|         let ota_next = mk_static!( | ||||
|             FlashRegion<FlashStorage>, | ||||
| @@ -388,7 +387,7 @@ impl PlantHal { | ||||
|             boot_button, | ||||
|             wake_gpio1, | ||||
|             ota, | ||||
|             ota_next, | ||||
|             ota_next | ||||
|         }; | ||||
|  | ||||
|         //init,reset rtc memory depending on cause | ||||
| @@ -589,4 +588,4 @@ pub async fn esp_set_time(time: DateTime<FixedOffset>) -> FatResult<()> { | ||||
|         .get_rtc_module() | ||||
|         .set_rtc_time(&time.to_utc()) | ||||
|         .await | ||||
| } | ||||
| } | ||||
| @@ -6,6 +6,7 @@ mod get_json; | ||||
| mod get_log; | ||||
| mod get_static; | ||||
| mod post_json; | ||||
| mod ota; | ||||
|  | ||||
| use crate::fat_error::{FatError, FatResult}; | ||||
| use crate::webserver::backup_manager::{backup_config, backup_info, get_backup_config}; | ||||
| @@ -36,7 +37,7 @@ use embassy_net::Stack; | ||||
| use embassy_time::Instant; | ||||
| use embedded_io_async::{Read, Write}; | ||||
| use log::info; | ||||
|  | ||||
| use crate::webserver::ota::ota_operations; | ||||
| // fn ota( | ||||
| //     request: &mut Request<&mut EspHttpConnection>, | ||||
| // ) -> Result<Option<std::string::String>, anyhow::Error> { | ||||
| @@ -107,6 +108,8 @@ impl Handler for HTTPRequestRouter { | ||||
|         let prefix = "/file?filename="; | ||||
|         let status = if path.starts_with(prefix) { | ||||
|             file_operations(conn, method, &path, &prefix).await? | ||||
|         } else if path == "/ota" { | ||||
|             ota_operations(conn,method).await? | ||||
|         } else { | ||||
|             match method { | ||||
|                 Method::Get => match path { | ||||
|   | ||||
							
								
								
									
										76
									
								
								rust/src/webserver/ota.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								rust/src/webserver/ota.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| use alloc::borrow::ToOwned; | ||||
| use alloc::format; | ||||
| use edge_http::io::server::Connection; | ||||
| use edge_http::Method; | ||||
| use embedded_io_async::{Read, Write}; | ||||
| use log::info; | ||||
| use crate::BOARD_ACCESS; | ||||
| use crate::fat_error::FatError; | ||||
|  | ||||
| pub(crate) async fn ota_operations<T, const N: usize>( | ||||
|     conn: &mut Connection<'_, T, { N }>, | ||||
|     method: Method | ||||
| ) -> Result<Option<u32>, FatError> | ||||
| where | ||||
|     T: Read + Write, | ||||
| { | ||||
|     Ok(match method { | ||||
|         Method::Options => { | ||||
|             conn.initiate_response( | ||||
|                 200, | ||||
|                 Some("OK"), | ||||
|                 &[ | ||||
|                     ("Access-Control-Allow-Origin", "*"), | ||||
|                     ("Access-Control-Allow-Headers", "*"), | ||||
|                     ("Access-Control-Allow-Methods", "*"), | ||||
|                 ], | ||||
|             ) | ||||
|                 .await?; | ||||
|             Some(200) | ||||
|         } | ||||
|         Method::Post => { | ||||
|             let mut offset = 0_usize; | ||||
|             let mut chunk = 0; | ||||
|             loop { | ||||
|                 let mut buf = [0_u8; 1024]; | ||||
|                 let to_write = conn.read(&mut buf).await?; | ||||
|                 if to_write == 0 { | ||||
|                     info!("file request for  ota finished"); | ||||
|                     let mut board = BOARD_ACCESS.get().await.lock().await; | ||||
|                     board.board_hal.get_esp().finalize_ota().await?; | ||||
|                     break; | ||||
|                 } else { | ||||
|                     let mut board = BOARD_ACCESS.get().await.lock().await; | ||||
|                     board.board_hal.progress(chunk as u32).await; | ||||
|                     board | ||||
|                         .board_hal | ||||
|                         .get_esp() | ||||
|                         .write_ota(offset as u32, &buf[0..to_write]) | ||||
|                         .await?; | ||||
|                 } | ||||
|                 offset = offset + to_write; | ||||
|                 chunk = chunk + 1; | ||||
|             } | ||||
|             BOARD_ACCESS | ||||
|                 .get() | ||||
|                 .await | ||||
|                 .lock() | ||||
|                 .await | ||||
|                 .board_hal | ||||
|                 .clear_progress() | ||||
|                 .await; | ||||
|             conn.initiate_response( | ||||
|                 200, | ||||
|                 Some("OK"), | ||||
|                 &[ | ||||
|                     ("Access-Control-Allow-Origin", "*"), | ||||
|                     ("Access-Control-Allow-Headers", "*"), | ||||
|                     ("Access-Control-Allow-Methods", "*"), | ||||
|                 ], | ||||
|             ) | ||||
|                 .await?; | ||||
|             Some(200) | ||||
|         } | ||||
|         _ => None, | ||||
|     }) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user