diff --git a/README.md b/README.md index 0c3a735..9bd06b1 100644 --- a/README.md +++ b/README.md @@ -11,22 +11,23 @@ designed for readability and simplicity over performance. You will need something that implements the `BlockDevice` trait, which can read and write the 512-byte blocks (or sectors) from your card. If you were to implement this over USB Mass Storage, there's no reason this crate couldn't work with a USB Thumb Drive, but we only supply a `BlockDevice` suitable for reading SD and SDHC cards over SPI. ```rust +use embedded_sdmmc::{SdCard, VolumeManager, Mode, VolumeIdx}; // Build an SD Card interface out of an SPI device, a chip-select pin and the delay object -let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, delay); +let sdcard = SdCard::new(sdmmc_spi, delay); // Get the card size (this also triggers card initialisation because it's not been done yet) println!("Card size is {} bytes", sdcard.num_bytes()?); // Now let's look for volumes (also known as partitions) on our block device. // To do this we need a Volume Manager. It will take ownership of the block device. -let volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); +let volume_mgr = VolumeManager::new(sdcard, time_source); // Try and access Volume 0 (i.e. the first partition). // The volume object holds information about the filesystem on that volume. -let volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; +let volume0 = volume_mgr.open_volume(VolumeIdx(0))?; println!("Volume 0: {:?}", volume0); // Open the root directory (mutably borrows from the volume). let root_dir = volume0.open_root_dir()?; // Open a file called "MY_FILE.TXT" in the root directory // This mutably borrows the directory. -let my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; +let my_file = root_dir.open_file_in_dir("MY_FILE.TXT", Mode::ReadOnly)?; // Print the contents of the file, assuming it's in ISO-8859-1 encoding while !my_file.is_eof() { let mut buffer = [0u8; 32]; diff --git a/examples/append_file.rs b/examples/append_file.rs index 2c7dd8e..54b7577 100644 --- a/examples/append_file.rs +++ b/examples/append_file.rs @@ -5,18 +5,15 @@ //! $ cargo run --example append_file -- /dev/mmcblk0 //! ``` //! -//! If you pass a block device it should be unmounted. No testing has been -//! performed with Windows raw block devices - please report back if you try -//! this! There is a gzipped example disk image which you can gunzip and test -//! with if you don't have a suitable block device. +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. //! //! ```bash //! zcat ./tests/disk.img.gz > ./disk.img //! $ cargo run --example append_file -- ./disk.img //! ``` -extern crate embedded_sdmmc; - mod linux; use linux::*; @@ -26,7 +23,7 @@ use embedded_sdmmc::{Error, Mode, VolumeIdx}; type VolumeManager = embedded_sdmmc::VolumeManager; -fn main() -> Result<(), embedded_sdmmc::Error> { +fn main() -> Result<(), Error> { env_logger::init(); let mut args = std::env::args().skip(1); let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into()); diff --git a/examples/big_dir.rs b/examples/big_dir.rs index a017026..bfc7e83 100644 --- a/examples/big_dir.rs +++ b/examples/big_dir.rs @@ -1,22 +1,38 @@ -extern crate embedded_sdmmc; +//! Big Directory Example. +//! +//! Attempts to create an infinite number of files in the root directory of the +//! first volume of the given block device. This is basically to see what +//! happens when the root directory runs out of space. +//! +//! ```bash +//! $ cargo run --example big_dir -- ./disk.img +//! $ cargo run --example big_dir -- /dev/mmcblk0 +//! ``` +//! +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. +//! +//! ```bash +//! zcat ./tests/disk.img.gz > ./disk.img +//! $ cargo run --example big_dir -- ./disk.img +//! ``` mod linux; use linux::*; -use embedded_sdmmc::Error; +use embedded_sdmmc::{Error, Mode, VolumeIdx}; type VolumeManager = embedded_sdmmc::VolumeManager; -fn main() -> Result<(), embedded_sdmmc::Error> { +fn main() -> Result<(), Error> { env_logger::init(); let mut args = std::env::args().skip(1); let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into()); let print_blocks = args.find(|x| x == "-v").map(|_| true).unwrap_or(false); let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?; let volume_mgr: VolumeManager = VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000); - let volume = volume_mgr - .open_volume(embedded_sdmmc::VolumeIdx(1)) - .unwrap(); + let volume = volume_mgr.open_volume(VolumeIdx(0)).unwrap(); println!("Volume: {:?}", volume); let root_dir = volume.open_root_dir().unwrap(); @@ -26,10 +42,7 @@ fn main() -> Result<(), embedded_sdmmc::Error> { let file_name = format!("{}.da", file_num); println!("opening file {file_name} for writing"); let file = root_dir - .open_file_in_dir( - file_name.as_str(), - embedded_sdmmc::Mode::ReadWriteCreateOrTruncate, - ) + .open_file_in_dir(file_name.as_str(), Mode::ReadWriteCreateOrTruncate) .unwrap(); let buf = b"hello world, from rust"; println!("writing to file"); diff --git a/examples/create_file.rs b/examples/create_file.rs index cc8b193..7f3cfb4 100644 --- a/examples/create_file.rs +++ b/examples/create_file.rs @@ -5,18 +5,15 @@ //! $ cargo run --example create_file -- /dev/mmcblk0 //! ``` //! -//! If you pass a block device it should be unmounted. No testing has been -//! performed with Windows raw block devices - please report back if you try -//! this! There is a gzipped example disk image which you can gunzip and test -//! with if you don't have a suitable block device. +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. //! //! ```bash //! zcat ./tests/disk.img.gz > ./disk.img //! $ cargo run --example create_file -- ./disk.img //! ``` -extern crate embedded_sdmmc; - mod linux; use linux::*; @@ -26,7 +23,7 @@ use embedded_sdmmc::{Error, Mode, VolumeIdx}; type VolumeManager = embedded_sdmmc::VolumeManager; -fn main() -> Result<(), embedded_sdmmc::Error> { +fn main() -> Result<(), Error> { env_logger::init(); let mut args = std::env::args().skip(1); let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into()); diff --git a/examples/delete_file.rs b/examples/delete_file.rs index 4d88213..3df1978 100644 --- a/examples/delete_file.rs +++ b/examples/delete_file.rs @@ -8,18 +8,15 @@ //! NOTE: THIS EXAMPLE DELETES A FILE CALLED README.TXT. IF YOU DO NOT WANT THAT //! FILE DELETED FROM YOUR DISK IMAGE, DO NOT RUN THIS EXAMPLE. //! -//! If you pass a block device it should be unmounted. No testing has been -//! performed with Windows raw block devices - please report back if you try -//! this! There is a gzipped example disk image which you can gunzip and test -//! with if you don't have a suitable block device. +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. //! //! ```bash //! zcat ./tests/disk.img.gz > ./disk.img //! $ cargo run --example delete_file -- ./disk.img //! ``` -extern crate embedded_sdmmc; - mod linux; use linux::*; @@ -29,7 +26,7 @@ use embedded_sdmmc::{Error, VolumeIdx}; type VolumeManager = embedded_sdmmc::VolumeManager; -fn main() -> Result<(), embedded_sdmmc::Error> { +fn main() -> Result<(), Error> { env_logger::init(); let mut args = std::env::args().skip(1); let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into()); diff --git a/examples/list_dir.rs b/examples/list_dir.rs index 0057849..e12807a 100644 --- a/examples/list_dir.rs +++ b/examples/list_dir.rs @@ -22,10 +22,9 @@ //! $ //! ``` //! -//! If you pass a block device it should be unmounted. No testing has been -//! performed with Windows raw block devices - please report back if you try -//! this! There is a gzipped example disk image which you can gunzip and test -//! with if you don't have a suitable block device. +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. //! //! ```bash //! zcat ./tests/disk.img.gz > ./disk.img diff --git a/examples/read_file.rs b/examples/read_file.rs index e8d900c..0800de9 100644 --- a/examples/read_file.rs +++ b/examples/read_file.rs @@ -22,18 +22,15 @@ //! 00000100 [54, 0a, 0d] |T...............| //! ``` //! -//! If you pass a block device it should be unmounted. No testing has been -//! performed with Windows raw block devices - please report back if you try -//! this! There is a gzipped example disk image which you can gunzip and test -//! with if you don't have a suitable block device. +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. //! //! ```bash //! zcat ./tests/disk.img.gz > ./disk.img //! $ cargo run --example read_file -- ./disk.img //! ``` -extern crate embedded_sdmmc; - mod linux; use linux::*; @@ -43,7 +40,7 @@ use embedded_sdmmc::{Error, Mode, VolumeIdx}; type VolumeManager = embedded_sdmmc::VolumeManager; -fn main() -> Result<(), embedded_sdmmc::Error> { +fn main() -> Result<(), Error> { env_logger::init(); let mut args = std::env::args().skip(1); let filename = args.next().unwrap_or_else(|| "/dev/mmcblk0".into()); diff --git a/examples/readme_test.rs b/examples/readme_test.rs index fd86780..0d63d80 100644 --- a/examples/readme_test.rs +++ b/examples/readme_test.rs @@ -7,6 +7,8 @@ use core::cell::RefCell; +use embedded_sdmmc::{Error, SdCardError, TimeSource, Timestamp}; + pub struct DummyCsPin; impl embedded_hal::digital::ErrorType for DummyCsPin { @@ -80,9 +82,9 @@ impl embedded_hal::delay::DelayNs for FakeDelayer { struct FakeTimesource(); -impl embedded_sdmmc::TimeSource for FakeTimesource { - fn get_timestamp(&self) -> embedded_sdmmc::Timestamp { - embedded_sdmmc::Timestamp { +impl TimeSource for FakeTimesource { + fn get_timestamp(&self) -> Timestamp { + Timestamp { year_since_1970: 0, zero_indexed_month: 0, zero_indexed_day: 0, @@ -94,24 +96,24 @@ impl embedded_sdmmc::TimeSource for FakeTimesource { } #[derive(Debug, Clone)] -enum Error { - Filesystem(embedded_sdmmc::Error), - Disk(embedded_sdmmc::SdCardError), +enum MyError { + Filesystem(Error), + Disk(SdCardError), } -impl From> for Error { - fn from(value: embedded_sdmmc::Error) -> Error { - Error::Filesystem(value) +impl From> for MyError { + fn from(value: Error) -> MyError { + MyError::Filesystem(value) } } -impl From for Error { - fn from(value: embedded_sdmmc::SdCardError) -> Error { - Error::Disk(value) +impl From for MyError { + fn from(value: SdCardError) -> MyError { + MyError::Disk(value) } } -fn main() -> Result<(), Error> { +fn main() -> Result<(), MyError> { // BEGIN Fake stuff that will be replaced with real peripherals let spi_bus = RefCell::new(FakeSpiBus()); let delay = FakeDelayer(); @@ -119,22 +121,23 @@ fn main() -> Result<(), Error> { let time_source = FakeTimesource(); // END Fake stuff that will be replaced with real peripherals + use embedded_sdmmc::{Mode, SdCard, VolumeIdx, VolumeManager}; // Build an SD Card interface out of an SPI device, a chip-select pin and the delay object - let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, delay); + let sdcard = SdCard::new(sdmmc_spi, delay); // Get the card size (this also triggers card initialisation because it's not been done yet) println!("Card size is {} bytes", sdcard.num_bytes()?); // Now let's look for volumes (also known as partitions) on our block device. // To do this we need a Volume Manager. It will take ownership of the block device. - let volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source); + let volume_mgr = VolumeManager::new(sdcard, time_source); // Try and access Volume 0 (i.e. the first partition). // The volume object holds information about the filesystem on that volume. - let volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?; + let volume0 = volume_mgr.open_volume(VolumeIdx(0))?; println!("Volume 0: {:?}", volume0); // Open the root directory (mutably borrows from the volume). let root_dir = volume0.open_root_dir()?; // Open a file called "MY_FILE.TXT" in the root directory // This mutably borrows the directory. - let my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?; + let my_file = root_dir.open_file_in_dir("MY_FILE.TXT", Mode::ReadOnly)?; // Print the contents of the file, assuming it's in ISO-8859-1 encoding while !my_file.is_eof() { let mut buffer = [0u8; 32]; @@ -143,6 +146,7 @@ fn main() -> Result<(), Error> { print!("{}", *b as char); } } + Ok(()) } diff --git a/examples/shell.rs b/examples/shell.rs index 5c6b0e5..4268276 100644 --- a/examples/shell.rs +++ b/examples/shell.rs @@ -3,6 +3,20 @@ //! Presents a basic command prompt which implements some basic MS-DOS style //! shell commands. //! +//! ```bash +//! $ cargo run --example shell -- ./disk.img +//! $ cargo run --example shell -- /dev/mmcblk0 +//! ``` +//! +//! If you pass a block device it should be unmounted. There is a gzipped +//! example disk image which you can gunzip and test with if you don't have a +//! suitable block device. +//! +//! ```bash +//! zcat ./tests/disk.img.gz > ./disk.img +//! $ cargo run --example shell -- ./disk.img +//! ``` +//! //! Note that `embedded_sdmmc` itself does not care about 'paths' - only //! accessing files and directories on on disk, relative to some previously //! opened directory. A 'path' is an operating-system level construct, and can @@ -72,7 +86,7 @@ use std::{cell::RefCell, io::prelude::*}; use embedded_sdmmc::{ - Error as EsError, LfnBuffer, RawDirectory, RawVolume, ShortFileName, VolumeIdx, + Error as EsError, LfnBuffer, Mode, RawDirectory, RawVolume, ShortFileName, VolumeIdx, }; type VolumeManager = embedded_sdmmc::VolumeManager; @@ -324,7 +338,7 @@ impl Context { /// print a text file fn cat(&self, filename: &Path) -> Result<(), Error> { let (dir, filename) = self.resolve_filename(filename)?; - let f = dir.open_file_in_dir(filename, embedded_sdmmc::Mode::ReadOnly)?; + let f = dir.open_file_in_dir(filename, Mode::ReadOnly)?; let mut data = Vec::new(); while !f.is_eof() { let mut buffer = vec![0u8; 65536]; @@ -344,7 +358,7 @@ impl Context { /// print a binary file fn hexdump(&self, filename: &Path) -> Result<(), Error> { let (dir, filename) = self.resolve_filename(filename)?; - let f = dir.open_file_in_dir(filename, embedded_sdmmc::Mode::ReadOnly)?; + let f = dir.open_file_in_dir(filename, Mode::ReadOnly)?; let mut data = Vec::new(); while !f.is_eof() { let mut buffer = vec![0u8; 65536];