Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Examples for no_std usage? #55

Open
Sven65 opened this issue Dec 28, 2021 · 9 comments
Open

Examples for no_std usage? #55

Sven65 opened this issue Dec 28, 2021 · 9 comments

Comments

@Sven65
Copy link

Sven65 commented Dec 28, 2021

Are there any plans on adding examples on how to use this with no_std?

@rafalh
Copy link
Owner

rafalh commented Dec 29, 2021

I think it is a good idea! Probably something basic, not a complete app for a specific microcontroller. I don't really have much experience with no_std in Rust. I think it would be best if someone with such experience contributed it.

@Dentosal
Copy link

Dentosal commented Jan 9, 2022

I'm just working on integrating this to my operating system, so I could probably write an example. How concrete are we talking about?

Here is some code (unfinished, untested, uncommented) that might become a part of an example:

#[derive(Debug)]
struct AtaError;

fn ata_read(start_sector: u64, sector_count: u8) -> Result<Vec<u8>, AtaError> {
    todo!("This is platform dependent");
}


#[derive(Debug)]
enum DiskCursorIoError {
    UnexpectedEof,
    WriteZero,
}
impl fatfs::IoError for DiskCursorIoError {
    fn is_interrupted(&self) -> bool {
        false
    }

    fn new_unexpected_eof_error() -> Self {
        Self::UnexpectedEof
    }

    fn new_write_zero_error() -> Self {
        Self::WriteZero
    }
}

struct DiskCursor {
    sector: u64,
    offset: usize,
}

impl DiskCursor {
    fn get_position(&self) -> usize {
        (self.sector * 0x200) as usize + self.offset
    }

    fn set_position(&mut self, position: usize) {
        self.sector = (position / 0x200) as u64;
        self.offset = position % 0x200;
    }

    fn move_cursor(&mut self, amount: usize) {
        self.set_position(self.get_position() + amount)
    }
}

impl fatfs::IoBase for DiskCursor {
    type Error = DiskCursorIoError;
}

impl fatfs::Read for DiskCursor {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, DiskCursorIoError> {
        let mut i = 0;
        while i < buf.len() {
            let data: Vec<u8> =
                ata_read(self.sector, ((buf.len() - i) / 0x200).max(1)).expect("ata error");
            let data = &data[self.offset..];
            if data.len() == 0 {
                break;
            }
            let end = (i + data.len()).min(buf.len());
            let len = end - i;
            buf[i..end].copy_from_slice(&data[..len]);
            i += len;
            self.move_cursor(i);
        }
        Ok(i)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DiskCursorIoError> {
        let n = self.read(buf)?;
        assert!(n == buf.len(), "TODO: Error");
        Ok(())
    }
}

impl fatfs::Write for DiskCursor {
    fn write(&mut self, buf: &[u8]) -> Result<usize, DiskCursorIoError> {
        todo!("Write");
    }

    fn write_all(&mut self, buf: &[u8]) -> Result<(), DiskCursorIoError> {
        todo!("Write");
    }

    fn flush(&mut self) -> Result<(), DiskCursorIoError> {
        Ok(())
    }
}

impl fatfs::Seek for DiskCursor {
    fn seek(&mut self, pos: fatfs::SeekFrom) -> Result<u64, DiskCursorIoError> {
        match pos {
            fatfs::SeekFrom::Start(i) => {
                self.set_position(i as usize);
                Ok(i)
            }
            fatfs::SeekFrom::End(i) => {
                todo!("Seek from end")
            }
            fatfs::SeekFrom::Current(i) => {
                let new_pos = (self.get_position() as i64) + i;
                self.set_position(new_pos as usize);
                Ok(new_pos as u64)
            }
        }
    }
}

pub fn ls_dir(path: &str) {
    let c = DiskCursor {
        sector: 0,
        offset: 0,
    };

    let fs = fatfs::FileSystem::new(c, fatfs::FsOptions::new()).expect("open fs");
    let mut cursor = fs.root_dir().open_dir(path).expect("move to dir");

    let mut result = Vec::new();
    for entry in cursor.iter() {
        let entry = entry.expect("Entry");
        raw_println!("{}", entry;)
    }
}

@rafalh
Copy link
Owner

rafalh commented Feb 1, 2022

Looks good to me :) Write support would be nice, are you planning to add it to?
Perhaps there should be some main function so it compiles fine when put into examples folder.

@x37v
Copy link

x37v commented Apr 25, 2022

It doesn't seem like it would be too much to implement Read Write and Seek like fscommon::BufStream but using sdmmc
Maybe someone already has?

@reitermarkus
Copy link
Contributor

@x37v, I'm currently trying to implement it for the STM32 L4 HAL, but I'm getting a CorruptedFileSystem error from the BootSector::validate function.

@x37v
Copy link

x37v commented May 2, 2022

@x37v, I'm currently trying to implement it for the STM32 L4 HAL, but I'm getting a CorruptedFileSystem error from the BootSector::validate function.

hey @reitermarkus , cool that you're doing this, I'd love to see your work in progress if you're willing/able to share. I hope to try this out with the stm32h7xx_hal when I get some chance.. I imagine it wouldn't be a whole lot different than what you're doing.

@reitermarkus
Copy link
Contributor

It's here stm32-rs/stm32l4xx-hal#315.

@x37v
Copy link

x37v commented May 2, 2022

It's here stm32-rs/stm32l4xx-hal#315.

@reitermarkus I added a comment into your PR.. not sure that it will solve things but I'm curious.

@x37v
Copy link

x37v commented May 30, 2022

Following up on this, @reitermarkus told me that the fatfs support works in this branch: https://github.com/reitermarkus/stm32l4xx-hal/tree/sdmmc

I've addapted that code for stm32h7xx-hal in a branch and have successfully run some example code on the stm32h750.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants