Skip to content

Commit 2f14459

Browse files
authored
Merge pull request #103 from rust-embedded-community/handles-own-volume-mgr
Smart Handles
2 parents dd8835c + db74a65 commit 2f14459

20 files changed

+835
-335
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
66

77
## [Unreleased]
88

9-
* None
9+
* `Volume`, `Directory` and `File` are now smart! They hold references to the thing they were made from, and will clean themselves up when dropped. The trade-off is you can can't open multiple volumes, directories or files at the same time.
10+
* Renamed the old types to `RawVolume`, `RawDirectory` and `RawFile`
1011

1112
## [Version 0.6.0] - 2023-10-20
1213

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ log = {version = "0.4", default-features = false, optional = true}
2121
env_logger = "0.9"
2222
hex-literal = "0.3"
2323
flate2 = "1.0"
24-
sha256 = "1.4"
24+
sha2 = "0.10"
2525
chrono = "0.4"
2626

2727
[features]
2828
default = ["log"]
29-
defmt-log = ["defmt"]
29+
defmt-log = ["dep:defmt"]
30+
log = ["dep:log"]

README.md

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ designed for readability and simplicity over performance.
1111
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.
1212

1313
```rust
14-
// Build an SD Card interface out of an SPI device, a chip-select pin and a delay object
14+
// Build an SD Card interface out of an SPI device, a chip-select pin and the delay object
1515
let sdcard = embedded_sdmmc::SdCard::new(sdmmc_spi, sdmmc_cs, delay);
1616
// Get the card size (this also triggers card initialisation because it's not been done yet)
1717
println!("Card size is {} bytes", sdcard.num_bytes()?);
@@ -20,29 +20,21 @@ println!("Card size is {} bytes", sdcard.num_bytes()?);
2020
let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source);
2121
// Try and access Volume 0 (i.e. the first partition).
2222
// The volume object holds information about the filesystem on that volume.
23-
// It doesn't hold a reference to the Volume Manager and so must be passed back
24-
// to every Volume Manager API call. This makes it easier to handle multiple
25-
// volumes in parallel.
26-
let volume0 = volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0))?;
23+
let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?;
2724
println!("Volume 0: {:?}", volume0);
28-
// Open the root directory (passing in the volume we're using).
29-
let root_dir = volume_mgr.open_root_dir(&volume0)?;
25+
// Open the root directory (mutably borrows from the volume).
26+
let mut root_dir = volume0.open_root_dir()?;
3027
// Open a file called "MY_FILE.TXT" in the root directory
31-
let my_file = volume_mgr.open_file_in_dir(
32-
root_dir,
33-
"MY_FILE.TXT",
34-
embedded_sdmmc::Mode::ReadOnly,
35-
)?;
28+
// This mutably borrows the directory.
29+
let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?;
3630
// Print the contents of the file
37-
while !volume_manager.file_eof(my_file).unwrap() {
31+
while !my_file.is_eof() {
3832
let mut buffer = [0u8; 32];
39-
let num_read = volume_mgr.read(&volume0, &mut my_file, &mut buffer)?;
33+
let num_read = my_file.read(&mut buffer)?;
4034
for b in &buffer[0..num_read] {
4135
print!("{}", *b as char);
4236
}
4337
}
44-
volume_mgr.close_file(my_file)?;
45-
volume_mgr.close_dir(root_dir)?;
4638
```
4739

4840
### Open directories and files

examples/append_file.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,11 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
3232
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
3333
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
3434
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
35-
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
36-
let root_dir = volume_mgr.open_root_dir(volume)?;
35+
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
36+
let mut root_dir = volume.open_root_dir()?;
3737
println!("\nCreating file {}...", FILE_TO_APPEND);
38-
let f = volume_mgr.open_file_in_dir(root_dir, FILE_TO_APPEND, Mode::ReadWriteAppend)?;
39-
volume_mgr.write(f, b"\r\n\r\nThis has been added to your file.\r\n")?;
40-
volume_mgr.close_file(f)?;
41-
volume_mgr.close_dir(root_dir)?;
38+
let mut f = root_dir.open_file_in_dir(FILE_TO_APPEND, Mode::ReadWriteAppend)?;
39+
f.write(b"\r\n\r\nThis has been added to your file.\r\n")?;
4240
Ok(())
4341
}
4442

examples/create_file.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,14 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
3232
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
3333
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
3434
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
35-
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
36-
let root_dir = volume_mgr.open_root_dir(volume)?;
35+
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
36+
let mut root_dir = volume.open_root_dir()?;
3737
println!("\nCreating file {}...", FILE_TO_CREATE);
3838
// This will panic if the file already exists: use ReadWriteCreateOrAppend
3939
// or ReadWriteCreateOrTruncate instead if you want to modify an existing
4040
// file.
41-
let f = volume_mgr.open_file_in_dir(root_dir, FILE_TO_CREATE, Mode::ReadWriteCreate)?;
42-
volume_mgr.write(f, b"Hello, this is a new file on disk\r\n")?;
43-
volume_mgr.close_file(f)?;
44-
volume_mgr.close_dir(root_dir)?;
41+
let mut f = root_dir.open_file_in_dir(FILE_TO_CREATE, Mode::ReadWriteCreate)?;
42+
f.write(b"Hello, this is a new file on disk\r\n")?;
4543
Ok(())
4644
}
4745

examples/delete_file.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
3535
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
3636
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
3737
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
38-
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
39-
let root_dir = volume_mgr.open_root_dir(volume)?;
38+
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
39+
let mut root_dir = volume.open_root_dir()?;
4040
println!("Deleting file {}...", FILE_TO_DELETE);
41-
volume_mgr.delete_file_in_dir(root_dir, FILE_TO_DELETE)?;
41+
root_dir.delete_file_in_dir(FILE_TO_DELETE)?;
4242
println!("Deleted!");
43-
volume_mgr.close_dir(root_dir)?;
4443
Ok(())
4544
}
4645

examples/list_dir.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,22 @@ fn main() -> Result<(), Error> {
4949
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
5050
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
5151
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
52-
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
53-
let root_dir = volume_mgr.open_root_dir(volume)?;
54-
list_dir(&mut volume_mgr, root_dir, "/")?;
55-
volume_mgr.close_dir(root_dir)?;
52+
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
53+
let root_dir = volume.open_root_dir()?;
54+
list_dir(root_dir, "/")?;
5655
Ok(())
5756
}
5857

5958
/// Recursively print a directory listing for the open directory given.
6059
///
6160
/// The path is for display purposes only.
6261
fn list_dir(
63-
volume_mgr: &mut VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4>,
64-
directory: Directory,
62+
mut directory: Directory<LinuxBlockDevice, Clock, 8, 8, 4>,
6563
path: &str,
6664
) -> Result<(), Error> {
6765
println!("Listing {}", path);
6866
let mut children = Vec::new();
69-
volume_mgr.iterate_dir(directory, |entry| {
67+
directory.iterate_dir(|entry| {
7068
println!(
7169
"{:12} {:9} {} {}",
7270
entry.name,
@@ -87,14 +85,13 @@ fn list_dir(
8785
}
8886
})?;
8987
for child_name in children {
90-
let child_dir = volume_mgr.open_dir(directory, &child_name)?;
88+
let child_dir = directory.open_dir(&child_name)?;
9189
let child_path = if path == "/" {
9290
format!("/{}", child_name)
9391
} else {
9492
format!("{}/{}", path, child_name)
9593
};
96-
list_dir(volume_mgr, child_dir, &child_path)?;
97-
volume_mgr.close_dir(child_dir)?;
94+
list_dir(child_dir, &child_path)?;
9895
}
9996
Ok(())
10097
}

examples/read_file.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,14 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
4949
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
5050
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
5151
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
52-
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
53-
let root_dir = volume_mgr.open_root_dir(volume)?;
52+
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
53+
let mut root_dir = volume.open_root_dir()?;
5454
println!("\nReading file {}...", FILE_TO_READ);
55-
let f = volume_mgr.open_file_in_dir(root_dir, FILE_TO_READ, Mode::ReadOnly)?;
56-
volume_mgr.close_dir(root_dir)?;
57-
while !volume_mgr.file_eof(f)? {
55+
let mut f = root_dir.open_file_in_dir(FILE_TO_READ, Mode::ReadOnly)?;
56+
while !f.is_eof() {
5857
let mut buffer = [0u8; 16];
59-
let offset = volume_mgr.file_offset(f)?;
60-
let mut len = volume_mgr.read(f, &mut buffer)?;
58+
let offset = f.offset();
59+
let mut len = f.read(&mut buffer)?;
6160
print!("{:08x} {:02x?}", offset, &buffer[0..len]);
6261
while len < buffer.len() {
6362
print!(" ");
@@ -74,7 +73,6 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
7473
}
7574
println!("|");
7675
}
77-
volume_mgr.close_file(f)?;
7876
Ok(())
7977
}
8078

examples/readme_test.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,21 @@ fn main() -> Result<(), Error> {
8787
let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, time_source);
8888
// Try and access Volume 0 (i.e. the first partition).
8989
// The volume object holds information about the filesystem on that volume.
90-
// It doesn't hold a reference to the Volume Manager and so must be passed back
91-
// to every Volume Manager API call. This makes it easier to handle multiple
92-
// volumes in parallel.
93-
let volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?;
90+
let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?;
9491
println!("Volume 0: {:?}", volume0);
95-
// Open the root directory (passing in the volume we're using).
96-
let root_dir = volume_mgr.open_root_dir(volume0)?;
92+
// Open the root directory (mutably borrows from the volume).
93+
let mut root_dir = volume0.open_root_dir()?;
9794
// Open a file called "MY_FILE.TXT" in the root directory
98-
let my_file =
99-
volume_mgr.open_file_in_dir(root_dir, "MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?;
95+
// This mutably borrows the directory.
96+
let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?;
10097
// Print the contents of the file
101-
while !volume_mgr.file_eof(my_file).unwrap() {
98+
while !my_file.is_eof() {
10299
let mut buffer = [0u8; 32];
103-
let num_read = volume_mgr.read(my_file, &mut buffer)?;
100+
let num_read = my_file.read(&mut buffer)?;
104101
for b in &buffer[0..num_read] {
105102
print!("{}", *b as char);
106103
}
107104
}
108-
volume_mgr.close_file(my_file)?;
109-
volume_mgr.close_dir(root_dir)?;
110105
Ok(())
111106
}
112107

0 commit comments

Comments
 (0)