Added format option + small cleanup

This commit is contained in:
Mateusz Faderewski 2024-09-27 20:19:25 +02:00
parent bf721acf5a
commit eef6198472
3 changed files with 95 additions and 54 deletions

View File

@ -30,7 +30,7 @@
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
#define FF_USE_MKFS 0 #define FF_USE_MKFS 1
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */

View File

@ -268,6 +268,10 @@ enum SDCommands {
/// Path to the file on the SD card /// Path to the file on the SD card
dst: Option<PathBuf>, dst: Option<PathBuf>,
}, },
/// Format the SD card
#[command(name = "mkfs")]
Format,
} }
#[derive(Subcommand)] #[derive(Subcommand)]
@ -854,12 +858,29 @@ fn handle_sd_command(connection: Connection, command: &SDCommands) -> Result<(),
match command { match command {
SDCommands::List { path } => { SDCommands::List { path } => {
for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? { for item in ff.list(path.clone().unwrap_or(PathBuf::from("/")))? {
println!("{item}"); 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}");
} }
} }
SDCommands::Stat { path } => { SDCommands::Stat { path } => {
let info = ff.stat(path)?; let sc64::ff::Entry {
println!("{info}"); 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}");
} }
SDCommands::Move { src, dst } => { SDCommands::Move { src, dst } => {
ff.rename(src, dst)?; ff.rename(src, dst)?;
@ -935,6 +956,20 @@ fn handle_sd_command(connection: Connection, command: &SDCommands) -> Result<(),
} }
println!("{}", "done!".bright_green()); 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(()) Ok(())

View File

@ -127,6 +127,20 @@ impl FF {
} }
} }
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<P: AsRef<std::path::Path>>(&self, path: P) -> Result<File, Error> { pub fn open<P: AsRef<std::path::Path>>(&self, path: P) -> Result<File, Error> {
File::open( File::open(
path, path,
@ -156,7 +170,7 @@ impl FF {
pub fn list<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Vec<Entry>, Error> { pub fn list<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Vec<Entry>, Error> {
let mut dir = self.opendir(path)?; let mut dir = self.opendir(path)?;
let mut list = Vec::<Entry>::new(); let mut list = vec![];
while let Some(entry) = dir.read()? { while let Some(entry) = dir.read()? {
list.push(entry); list.push(entry);
@ -187,42 +201,41 @@ impl FF {
error => Err(error.into()), error => Err(error.into()),
} }
} }
}
pub fn run<F: FnOnce(FF) -> Result<(), super::Error>>( pub fn mkfs(&self) -> Result<(), Error> {
driver: impl FFDriver + 'static, let mut work = [0u8; 16 * 1024];
runner: F, match unsafe {
) -> Result<(), super::Error> { fatfs::f_mkfs(
let fs = start(driver)?; fatfs::path("")?.as_ptr(),
let result = runner(fs); std::ptr::null(),
stop()?; work.as_mut_ptr().cast(),
result size_of_val(&work) as u32,
} )
} {
fn start(fatfs_driver: impl FFDriver + 'static) -> Result<FF, Error> { fatfs::FRESULT_FR_OK => Ok(()),
driver_install(fatfs_driver)?; error => Err(error.into()),
let mut ff = FF::new();
match unsafe { fatfs::f_mount(&mut *ff.fs, fatfs::path("")?.as_ptr(), 1) } {
fatfs::FRESULT_FR_OK => Ok(ff),
error => {
driver_uninstall().ok();
Err(error.into())
} }
} }
} }
fn stop() -> Result<(), Error> { pub fn run<F: FnOnce(&mut FF) -> Result<(), super::Error>>(
match unsafe { fatfs::f_mount(std::ptr::null_mut(), fatfs::path("")?.as_ptr(), 0) } { driver: impl FFDriver + 'static,
fatfs::FRESULT_FR_OK => driver_uninstall(), runner: F,
error => Err(error.into()), ) -> 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 driver_install(new_driver: impl FFDriver + 'static) -> Result<(), Error> { fn install_driver(driver: impl FFDriver + 'static) -> Result<(), Error> {
match unsafe { DRIVER.lock() } { match unsafe { DRIVER.lock() } {
Ok(mut driver) => { Ok(mut d) => {
if driver.is_none() { if d.is_none() {
driver.replace(Box::new(new_driver)); d.replace(Box::new(driver));
Ok(()) Ok(())
} else { } else {
Err(Error::IntErr) Err(Error::IntErr)
@ -232,11 +245,11 @@ fn driver_install(new_driver: impl FFDriver + 'static) -> Result<(), Error> {
} }
} }
fn driver_uninstall() -> Result<(), Error> { fn uninstall_driver() -> Result<(), Error> {
match unsafe { DRIVER.lock() } { match unsafe { DRIVER.lock() } {
Ok(mut driver) => { Ok(mut d) => {
if let Some(mut driver) = driver.take() { if let Some(mut d) = d.take() {
driver.deinit(); d.deinit();
Ok(()) Ok(())
} else { } else {
Err(Error::IntErr) Err(Error::IntErr)
@ -427,7 +440,7 @@ unsafe extern "C" fn disk_ioctl(
return result; return result;
} }
} }
fatfs::DRESULT_RES_OK fatfs::DRESULT_RES_ERROR
} }
#[no_mangle] #[no_mangle]
@ -470,7 +483,7 @@ impl PartialOrd for EntryInfo {
} }
} }
impl std::fmt::Display for Entry { impl std::fmt::Display for EntryInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let size_formatter = |size: u64| -> String { let size_formatter = |size: u64| -> String {
const UNITS: [&str; 4] = ["K", "M", "G", "T"]; const UNITS: [&str; 4] = ["K", "M", "G", "T"];
@ -490,18 +503,11 @@ impl std::fmt::Display for Entry {
format!("{:>3.0}{}", reduced_size, reduced_unit) format!("{:>3.0}{}", reduced_size, reduced_unit)
} }
}; };
Ok(match self.info { Ok(match self {
EntryInfo::Directory => f.write_fmt(format_args!( EntryInfo::Directory => f.write_fmt(format_args!("d ----",))?,
"d ---- {} | {}", EntryInfo::File { size } => {
self.datetime, f.write_fmt(format_args!("f {}", size_formatter(*size),))?
format!("/{}", self.name) }
))?,
EntryInfo::File { size } => f.write_fmt(format_args!(
"f {} {} | {}",
size_formatter(size),
self.datetime,
self.name
))?,
}) })
} }
} }
@ -544,7 +550,7 @@ pub struct Directory {
impl Directory { impl Directory {
fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Error> { fn open<P: AsRef<std::path::Path>>(path: P) -> Result<Self, Error> {
let mut dir: fatfs::DIR = unsafe { std::mem::zeroed() }; let mut dir = unsafe { std::mem::zeroed() };
match unsafe { fatfs::f_opendir(&mut dir, fatfs::path(path)?.as_ptr()) } { match unsafe { fatfs::f_opendir(&mut dir, fatfs::path(path)?.as_ptr()) } {
fatfs::FRESULT_FR_OK => Ok(Self { dir }), fatfs::FRESULT_FR_OK => Ok(Self { dir }),
error => Err(error.into()), error => Err(error.into()),
@ -552,7 +558,7 @@ impl Directory {
} }
pub fn read(&mut self) -> Result<Option<Entry>, Error> { pub fn read(&mut self) -> Result<Option<Entry>, Error> {
let mut fno: fatfs::FILINFO = unsafe { std::mem::zeroed() }; let mut fno = unsafe { std::mem::zeroed() };
match unsafe { fatfs::f_readdir(&mut self.dir, &mut fno) } { match unsafe { fatfs::f_readdir(&mut self.dir, &mut fno) } {
fatfs::FRESULT_FR_OK => { fatfs::FRESULT_FR_OK => {
if fno.fname[0] == 0 { if fno.fname[0] == 0 {
@ -578,7 +584,7 @@ pub struct File {
impl File { impl File {
fn open<P: AsRef<std::path::Path>>(path: P, mode: u32) -> Result<File, Error> { fn open<P: AsRef<std::path::Path>>(path: P, mode: u32) -> Result<File, Error> {
let mut fil: fatfs::FIL = unsafe { std::mem::zeroed() }; let mut fil = unsafe { std::mem::zeroed() };
match unsafe { fatfs::f_open(&mut fil, fatfs::path(path)?.as_ptr(), mode as u8) } { match unsafe { fatfs::f_open(&mut fil, fatfs::path(path)?.as_ptr(), mode as u8) } {
fatfs::FRESULT_FR_OK => Ok(File { fil }), fatfs::FRESULT_FR_OK => Ok(File { fil }),
error => Err(error.into()), error => Err(error.into()),