From 802e882b13b3320e7b88d189b69479c5c166218b Mon Sep 17 00:00:00 2001 From: Mateusz Faderewski Date: Sun, 29 Sep 2024 20:42:17 +0200 Subject: [PATCH] little cleanup --- sw/deployer/src/main.rs | 207 +++++++++++++++++---------------- sw/deployer/src/sc64/ff.rs | 228 ++++++++++++++++++------------------- 2 files changed, 215 insertions(+), 220 deletions(-) diff --git a/sw/deployer/src/main.rs b/sw/deployer/src/main.rs index d203c5b..7ed78e1 100644 --- a/sw/deployer/src/main.rs +++ b/sw/deployer/src/main.rs @@ -874,126 +874,123 @@ fn handle_sd_command(connection: Connection, command: &SDCommands) -> Result<(), sc64.reset_state()?; - sc64::ff::run(sc64, |ff| { - match command { - SDCommands::List { path } => { - for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? { - let sc64::ff::Entry { - info, - datetime, - name, - } = item; - let name = match info { - sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(), - sc64::ff::EntryInfo::File { size: _ } => name.bright_green(), - }; - println!("{info} {datetime} | {}", name.bold()); - } - } - SDCommands::Stat { path } => { + let mut ff = sc64::ff::FatFs::new(sc64)?; + + match command { + SDCommands::List { path } => { + for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? { let sc64::ff::Entry { info, datetime, name, - } = ff.stat(path)?; + } = item; let name = match info { sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(), sc64::ff::EntryInfo::File { size: _ } => name.bright_green(), }; println!("{info} {datetime} | {}", name.bold()); } - SDCommands::Move { src, dst } => { - ff.rename(src, dst)?; - println!( - "Successfully moved {} to {}", + } + SDCommands::Stat { path } => { + let sc64::ff::Entry { + info, + datetime, + name, + } = ff.stat(path)?; + let name = match info { + sc64::ff::EntryInfo::Directory => ("/".to_owned() + &name).bright_blue(), + sc64::ff::EntryInfo::File { size: _ } => name.bright_green(), + }; + println!("{info} {datetime} | {}", name.bold()); + } + SDCommands::Move { src, dst } => { + ff.rename(src, dst)?; + println!( + "Successfully moved {} to {}", + src.to_str().unwrap_or_default().bright_green(), + dst.to_str().unwrap_or_default().bright_green() + ); + } + SDCommands::Delete { path } => { + ff.delete(path)?; + println!( + "Successfully deleted {}", + path.to_str().unwrap_or_default().bright_green() + ); + } + SDCommands::CreateDirectory { path } => { + ff.mkdir(path)?; + println!( + "Successfully created {}", + path.to_str().unwrap_or_default().bright_green() + ); + } + SDCommands::Download { src, dst } => { + let dst = &dst.clone().unwrap_or( + src.file_name() + .map(PathBuf::from) + .ok_or(sc64::ff::Error::InvalidParameter)?, + ); + let mut src_file = ff.open(src)?; + let mut dst_file = std::fs::File::create(dst)?; + let mut buffer = vec![0; 128 * 1024]; + log_wait( + format!( + "Downloading {} to {}", src.to_str().unwrap_or_default().bright_green(), dst.to_str().unwrap_or_default().bright_green() - ); - } - SDCommands::Delete { path } => { - ff.delete(path)?; - println!( - "Successfully deleted {}", - path.to_str().unwrap_or_default().bright_green() - ); - } - SDCommands::CreateDirectory { path } => { - ff.mkdir(path)?; - println!( - "Successfully created {}", - path.to_str().unwrap_or_default().bright_green() - ); - } - SDCommands::Download { src, dst } => { - let dst = &dst.clone().unwrap_or( - src.file_name() - .map(PathBuf::from) - .ok_or(sc64::ff::Error::InvalidParameter)?, - ); - let mut src_file = ff.open(src)?; - let mut dst_file = std::fs::File::create(dst)?; - let mut buffer = vec![0; 128 * 1024]; - print!( - "{}", - format!( - "Downloading {} to {}... ", - src.to_str().unwrap_or_default().bright_green(), - dst.to_str().unwrap_or_default().bright_green() - ) - ); - stdout().flush().unwrap(); - loop { + ), + || loop { match src_file.read(&mut buffer)? { - 0 => break, - bytes => dst_file.write_all(&buffer[0..bytes])?, + 0 => return Ok(()), + bytes => { + if let Err(e) = dst_file.write_all(&buffer[0..bytes]) { + return Err(e); + } + } } - } - println!("{}", "done!".bright_green()); - } - SDCommands::Upload { src, dst } => { - let dst = &dst.clone().unwrap_or( - src.file_name() - .map(PathBuf::from) - .ok_or(sc64::ff::Error::InvalidParameter)?, - ); - let mut src_file = std::fs::File::open(src)?; - let mut dst_file = ff.create(dst)?; - let mut buffer = vec![0; 128 * 1024]; - print!( - "{}", - format!( - "Uploading {} to {}... ", - src.to_str().unwrap_or_default().bright_green(), - dst.to_str().unwrap_or_default().bright_green() - ) - ); - stdout().flush().unwrap(); - loop { - match src_file.read(&mut buffer)? { - 0 => break, - bytes => dst_file.write_all(&buffer[0..bytes])?, - } - } - println!("{}", "done!".bright_green()); - } - SDCommands::Format => { - let answer = prompt(format!( - "{}", - "Do you really want to format the SD card? [y/N] ".bold() - )); - if answer.to_ascii_lowercase() != "y" { - println!("{}", "Format operation aborted".red()); - return Ok(()); - } - print!("Formatting the SD card... ",); - stdout().flush().unwrap(); - ff.mkfs()?; - println!("{}", "done!".bright_green()); - } + }, + )?; } - - Ok(()) - })?; + SDCommands::Upload { src, dst } => { + let dst = &dst.clone().unwrap_or( + src.file_name() + .map(PathBuf::from) + .ok_or(sc64::ff::Error::InvalidParameter)?, + ); + let mut src_file = std::fs::File::open(src)?; + let mut dst_file = ff.create(dst)?; + let mut buffer = vec![0; 128 * 1024]; + log_wait( + format!( + "Uploading {} to {}", + src.to_str().unwrap_or_default().bright_green(), + dst.to_str().unwrap_or_default().bright_green() + ), + || loop { + match src_file.read(&mut buffer)? { + 0 => return Ok(()), + bytes => { + if let Err(e) = dst_file.write_all(&buffer[0..bytes]) { + return Err(e); + } + } + } + }, + )?; + } + SDCommands::Format => { + let answer = prompt(format!( + "{}", + "Do you really want to format the SD card? [y/N] ".bold() + )); + if answer.to_ascii_lowercase() != "y" { + println!("{}", "Format operation aborted".red()); + return Ok(()); + } + log_wait(format!("Formatting the SD card"), || ff.mkfs())?; + } + } Ok(()) } diff --git a/sw/deployer/src/sc64/ff.rs b/sw/deployer/src/sc64/ff.rs index 6582797..855bddf 100644 --- a/sw/deployer/src/sc64/ff.rs +++ b/sw/deployer/src/sc64/ff.rs @@ -120,121 +120,6 @@ pub type Error = fatfs::Error; static mut DRIVER: std::sync::Mutex>> = std::sync::Mutex::new(None); -pub struct FF { - fs: Box, -} - -impl FF { - fn new() -> Self { - Self { - fs: Box::new(unsafe { std::mem::zeroed() }), - } - } - - fn mount(&mut self) -> Result<(), Error> { - match unsafe { fatfs::f_mount(&mut *self.fs, fatfs::path("")?.as_ptr(), 0) } { - fatfs::FRESULT_FR_OK => Ok(()), - error => Err(error.into()), - } - } - - fn unmount(&self) -> Result<(), Error> { - match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } { - fatfs::FRESULT_FR_OK => Ok(()), - error => Err(error.into()), - } - } - - pub fn open>(&self, path: P) -> Result { - File::open( - path, - fatfs::FA_OPEN_EXISTING | fatfs::FA_READ | fatfs::FA_WRITE, - ) - } - - pub fn create>(&self, path: P) -> Result { - File::open( - path, - fatfs::FA_CREATE_ALWAYS | fatfs::FA_READ | fatfs::FA_WRITE, - ) - } - - pub fn stat>(&self, path: P) -> Result { - let mut fno = unsafe { std::mem::zeroed() }; - match unsafe { fatfs::f_stat(fatfs::path(path)?.as_ptr(), &mut fno) } { - fatfs::FRESULT_FR_OK => Ok(fno.into()), - error => Err(error.into()), - } - } - - pub fn opendir>(&self, path: P) -> Result { - Directory::open(path) - } - - pub fn list>(&self, path: P) -> Result, Error> { - let mut dir = self.opendir(path)?; - - let mut list = vec![]; - - while let Some(entry) = dir.read()? { - list.push(entry); - } - - list.sort_by_key(|k| (k.info, k.name.to_lowercase())); - - Ok(list) - } - - pub fn mkdir>(&self, path: P) -> Result<(), Error> { - match unsafe { fatfs::f_mkdir(fatfs::path(path)?.as_ptr()) } { - fatfs::FRESULT_FR_OK => Ok(()), - error => Err(error.into()), - } - } - - pub fn delete>(&self, path: P) -> Result<(), Error> { - match unsafe { fatfs::f_unlink(fatfs::path(path)?.as_ptr()) } { - fatfs::FRESULT_FR_OK => Ok(()), - error => Err(error.into()), - } - } - - pub fn rename>(&self, old: P, new: P) -> Result<(), Error> { - match unsafe { fatfs::f_rename(fatfs::path(old)?.as_ptr(), fatfs::path(new)?.as_ptr()) } { - fatfs::FRESULT_FR_OK => Ok(()), - error => Err(error.into()), - } - } - - pub fn mkfs(&self) -> Result<(), Error> { - let mut work = [0u8; 16 * 1024]; - match unsafe { - fatfs::f_mkfs( - fatfs::path("")?.as_ptr(), - std::ptr::null(), - work.as_mut_ptr().cast(), - size_of_val(&work) as u32, - ) - } { - fatfs::FRESULT_FR_OK => Ok(()), - error => Err(error.into()), - } - } -} - -pub fn run Result<(), super::Error>>( - driver: impl FFDriver + 'static, - runner: F, -) -> Result<(), super::Error> { - install_driver(driver)?; - let mut ff = FF::new(); - ff.mount()?; - let result = runner(&mut ff); - ff.unmount().ok(); - uninstall_driver().ok(); - result -} - fn install_driver(driver: impl FFDriver + 'static) -> Result<(), Error> { let mut d = unsafe { DRIVER.lock().unwrap() }; if d.is_some() { @@ -253,6 +138,119 @@ fn uninstall_driver() -> Result<(), Error> { Ok(()) } +pub struct FatFs { + fs: Box, +} + +impl FatFs { + pub fn new(driver: impl FFDriver + 'static) -> Result { + install_driver(driver)?; + let mut ff = Self { + fs: Box::new(unsafe { std::mem::zeroed() }), + }; + ff.mount(false)?; + Ok(ff) + } + + fn mount(&mut self, force: bool) -> Result<(), Error> { + let opt = if force { 1 } else { 0 }; + match unsafe { fatfs::f_mount(&mut *self.fs, fatfs::path("")?.as_ptr(), opt) } { + fatfs::FRESULT_FR_OK => Ok(()), + error => Err(error.into()), + } + } + + fn unmount(&mut self) -> Result<(), Error> { + match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } { + fatfs::FRESULT_FR_OK => Ok(()), + error => Err(error.into()), + } + } + + pub fn open>(&mut self, path: P) -> Result { + File::open( + path, + fatfs::FA_OPEN_EXISTING | fatfs::FA_READ | fatfs::FA_WRITE, + ) + } + + pub fn create>(&mut self, path: P) -> Result { + File::open( + path, + fatfs::FA_CREATE_ALWAYS | fatfs::FA_READ | fatfs::FA_WRITE, + ) + } + + pub fn stat>(&mut self, path: P) -> Result { + let mut fno = unsafe { std::mem::zeroed() }; + match unsafe { fatfs::f_stat(fatfs::path(path)?.as_ptr(), &mut fno) } { + fatfs::FRESULT_FR_OK => Ok(fno.into()), + error => Err(error.into()), + } + } + + pub fn opendir>(&mut self, path: P) -> Result { + Directory::open(path) + } + + pub fn list>(&mut self, path: P) -> Result, Error> { + let mut dir = self.opendir(path)?; + + let mut list = vec![]; + + while let Some(entry) = dir.read()? { + list.push(entry); + } + + list.sort_by_key(|k| (k.info, k.name.to_lowercase())); + + Ok(list) + } + + pub fn mkdir>(&mut self, path: P) -> Result<(), Error> { + match unsafe { fatfs::f_mkdir(fatfs::path(path)?.as_ptr()) } { + fatfs::FRESULT_FR_OK => Ok(()), + error => Err(error.into()), + } + } + + pub fn delete>(&mut self, path: P) -> Result<(), Error> { + match unsafe { fatfs::f_unlink(fatfs::path(path)?.as_ptr()) } { + fatfs::FRESULT_FR_OK => Ok(()), + error => Err(error.into()), + } + } + + pub fn rename>(&mut self, old: P, new: P) -> Result<(), Error> { + match unsafe { fatfs::f_rename(fatfs::path(old)?.as_ptr(), fatfs::path(new)?.as_ptr()) } { + fatfs::FRESULT_FR_OK => Ok(()), + error => Err(error.into()), + } + } + + pub fn mkfs(&mut self) -> Result<(), Error> { + let mut work = [0u8; 16 * 1024]; + match unsafe { + fatfs::f_mkfs( + fatfs::path("")?.as_ptr(), + std::ptr::null(), + work.as_mut_ptr().cast(), + size_of_val(&work) as u32, + ) + } { + fatfs::FRESULT_FR_OK => Ok(()), + error => Err(error.into()), + } + } +} + +impl Drop for FatFs { + fn drop(&mut self) { + self.unmount().ok(); + uninstall_driver().ok(); + } +} + pub enum IOCtl { Sync, GetSectorCount(fatfs::LBA_t),