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

Release/v0.7.0 #116

Merged
merged 47 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
dd8835c
Merge pull request #105 from rust-embedded-community/main
thejpster Oct 20, 2023
d41d41d
Add Raw/Smart Handles for Volume/Directory/File
thejpster Oct 7, 2023
06af669
Switch from sha256 to sha2.
thejpster Oct 7, 2023
6c3fa0a
Fix defmt logging.
thejpster Oct 7, 2023
d18fefa
Update embedded hal
Oct 22, 2023
df3b86a
Fix doctests
Oct 22, 2023
62fb7be
Remove duplicate where clauses
Oct 23, 2023
db74a65
Update CHANGELOG
thejpster Oct 28, 2023
2f14459
Merge pull request #103 from rust-embedded-community/handles-own-volu…
thejpster Oct 28, 2023
7fc0c6f
Update embedded hal
Oct 22, 2023
a5eb765
Fix doctests
Oct 22, 2023
69d8047
Remove duplicate where clauses
Oct 23, 2023
4d3aa31
Create and document DummyCsPin for use with e-h1.0
fu5ha Oct 30, 2023
b1db2b4
Merge branch 'dummy-cs' into update-embedded-hal
Oct 30, 2023
5d31339
Fix doctest
Oct 30, 2023
f2a6ae1
Linked no-std examples
Nereuxofficial Nov 8, 2023
d4195ba
Added pygamer example
Nereuxofficial Nov 8, 2023
df8559c
Merge pull request #108 from Nereuxofficial/patch-1
eldruin Nov 9, 2023
eb59b66
Fix struct reference in documentation
yanorei32 Dec 5, 2023
799b803
Update src/filesystem/directory.rs
yanorei32 Dec 6, 2023
3a459d7
Merge pull request #109 from yanorei32/fix-struct-reference-in-docume…
thejpster Dec 6, 2023
fec3af5
Add example which tries to totally fill the root directory.
thejpster Dec 17, 2023
819a624
Fix issue #74
thejpster Dec 17, 2023
85d32e6
Merge pull request #110 from rust-embedded-community/fix-issue-74
thejpster Dec 17, 2023
2c557b0
Clippy lints for list_dir
thejpster Dec 17, 2023
054af87
Support making new directories.
thejpster Dec 17, 2023
43f9281
Update CHANGELOG.
thejpster Dec 17, 2023
3b5c026
Merge pull request #111 from rust-embedded-community/mkdir
thejpster Dec 18, 2023
5fe01bf
lib: update dependency embedded-hal to 1.0.0
jakezhu9 Jan 10, 2024
6414fa7
Merge pull request #2 from jakezhu9/update-embedded-hal
AnyTimeTraveler Jan 11, 2024
bca6ceb
Merge branch 'develop' into update-embedded-hal
AnyTimeTraveler Jan 11, 2024
1371292
Fix doc warnings
Jan 11, 2024
7e33906
Annotate readme_test.rs to make section clearer
Jan 11, 2024
fe739b4
Commented in doctest
Jan 11, 2024
4c31f43
Improve formatting of doctest
Jan 11, 2024
959b670
Clean up example code.
jonathanpallant Jan 12, 2024
e7ef46f
Merge pull request #106 from AnyTimeTraveler/update-embedded-hal
jonathanpallant Jan 12, 2024
d8bcdf7
Rename FileNotFound to NotFound
thejpster Dec 19, 2023
b173f7b
Tools for relative path handling.
thejpster Dec 19, 2023
fdd59dc
Clean up shell.
thejpster Dec 19, 2023
2b07077
Shell supports relative paths.
thejpster Dec 19, 2023
d68a73f
cd now has path support.
thejpster Dec 19, 2023
69c48fd
Add tree command.
thejpster Dec 19, 2023
2fab549
Fix example volume names.
thejpster Dec 20, 2023
8f0e37c
Update CHANGELOG
thejpster Dec 20, 2023
ae5e116
Merge pull request #112 from rust-embedded-community/enhanced-shell
thejpster Jan 14, 2024
afdcec7
Updated to 0.7.0
thejpster Feb 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,32 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic

* None

## [Version 0.7.0] - 2024-02-04

## Changed

- __Breaking Change__: `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.
- __Breaking Change__: Renamed the old types to `RawVolume`, `RawDirectory` and `RawFile`
- __Breaking Change__: Renamed `Error::FileNotFound` to `Error::NotFound`
- Fixed long-standing bug that caused an integer overflow when a FAT32 directory was longer than one cluster ([#74])
- You can now open directories multiple times without error
- Updated to [embedded-hal] 1.0

## Added

- `RawVolume`, `RawDirectory` and `RawFile` types (like the old `Volume`, `Directory` and `File` types)
- New method `make_dir_in_dir`
- Empty strings and `"."` convert to `ShortFileName::this_dir()`
- New API `change_dir` which changes a directory to point to some child directory (or the parent) without opening a new directory.
- Updated 'shell' example to support `mkdir`, `tree` and relative/absolute paths

## Removed

* None

[#74]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/issues/74
[embedded-hal]: https://crates.io/crates/embedded-hal

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

### Changed
Expand Down Expand Up @@ -111,7 +137,8 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic

[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
[Semantic Versioning]: http://semver.org/spec/v2.0.0.html
[Unreleased]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.6.0...develop
[Unreleased]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.7.0...develop
[Version 0.7.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.7.0...v0.6.0
[Version 0.6.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.6.0...v0.5.0
[Version 0.5.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.5.0...v0.4.0
[Version 0.4.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.4.0...v0.3.0
Expand Down
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ license = "MIT OR Apache-2.0"
name = "embedded-sdmmc"
readme = "README.md"
repository = "https://github.com/rust-embedded-community/embedded-sdmmc-rs"
version = "0.6.0"
version = "0.7.0"

[dependencies]
byteorder = {version = "1", default-features = false}
defmt = {version = "0.3", optional = true}
embedded-hal = "0.2.3"
embedded-hal = "1.0.0"
heapless = "0.7"
log = {version = "0.4", default-features = false, optional = true}

[dev-dependencies]
env_logger = "0.9"
hex-literal = "0.3"
flate2 = "1.0"
sha256 = "1.4"
chrono = "0.4"
embedded-hal-bus = "0.1.0"
env_logger = "0.10.0"
flate2 = "1.0"
hex-literal = "0.4.1"
sha2 = "0.10"

[features]
default = ["log"]
defmt-log = ["defmt"]
defmt-log = ["dep:defmt"]
log = ["dep:log"]
30 changes: 14 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ 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
// Build an SD Card interface out of an SPI device, a chip-select pin and a delay object
// 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, sdmmc_cs, 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()?);
Expand All @@ -20,29 +20,21 @@ println!("Card size is {} bytes", sdcard.num_bytes()?);
let mut volume_mgr = embedded_sdmmc::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.
// It doesn't hold a reference to the Volume Manager and so must be passed back
// to every Volume Manager API call. This makes it easier to handle multiple
// volumes in parallel.
let volume0 = volume_mgr.get_volume(embedded_sdmmc::VolumeIdx(0))?;
let mut volume0 = volume_mgr.open_volume(embedded_sdmmc::VolumeIdx(0))?;
println!("Volume 0: {:?}", volume0);
// Open the root directory (passing in the volume we're using).
let root_dir = volume_mgr.open_root_dir(&volume0)?;
// Open the root directory (mutably borrows from the volume).
let mut root_dir = volume0.open_root_dir()?;
// Open a file called "MY_FILE.TXT" in the root directory
let my_file = volume_mgr.open_file_in_dir(
root_dir,
"MY_FILE.TXT",
embedded_sdmmc::Mode::ReadOnly,
)?;
// This mutably borrows the directory.
let mut my_file = root_dir.open_file_in_dir("MY_FILE.TXT", embedded_sdmmc::Mode::ReadOnly)?;
// Print the contents of the file
while !volume_manager.file_eof(my_file).unwrap() {
while !my_file.is_eof() {
let mut buffer = [0u8; 32];
let num_read = volume_mgr.read(&volume0, &mut my_file, &mut buffer)?;
let num_read = my_file.read(&mut buffer)?;
for b in &buffer[0..num_read] {
print!("{}", *b as char);
}
}
volume_mgr.close_file(my_file)?;
volume_mgr.close_dir(root_dir)?;
```

### Open directories and files
Expand All @@ -66,6 +58,12 @@ let mut cont: VolumeManager<_, _, 6, 12, 4> = VolumeManager::new_with_limits(blo
* Iterate sub-directories
* Log over defmt or the common log interface (feature flags).

## No-std usage
This repository houses no examples for no-std usage, however you can check out the following examples:
- [Pi Pico](https://github.com/rp-rs/rp-hal-boards/blob/main/boards/rp-pico/examples/pico_spi_sd_card.rs)
- [STM32H7XX](https://github.com/stm32-rs/stm32h7xx-hal/blob/master/examples/sdmmc_fat.rs)
- [atsamd(pygamer)](https://github.com/atsamd-rs/atsamd/blob/master/boards/pygamer/examples/sd_card.rs)

## Todo List (PRs welcome!)

* Create new dirs
Expand Down
10 changes: 4 additions & 6 deletions examples/append_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume_mgr.open_root_dir(volume)?;
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
let mut root_dir = volume.open_root_dir()?;
println!("\nCreating file {}...", FILE_TO_APPEND);
let f = volume_mgr.open_file_in_dir(root_dir, FILE_TO_APPEND, Mode::ReadWriteAppend)?;
volume_mgr.write(f, b"\r\n\r\nThis has been added to your file.\r\n")?;
volume_mgr.close_file(f)?;
volume_mgr.close_dir(root_dir)?;
let mut f = root_dir.open_file_in_dir(FILE_TO_APPEND, Mode::ReadWriteAppend)?;
f.write(b"\r\n\r\nThis has been added to your file.\r\n")?;
Ok(())
}

Expand Down
39 changes: 39 additions & 0 deletions examples/big_dir.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
extern crate embedded_sdmmc;

mod linux;
use linux::*;

use embedded_sdmmc::{Error, VolumeManager};

fn main() -> Result<(), embedded_sdmmc::Error<std::io::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 mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let mut volume = volume_mgr
.open_volume(embedded_sdmmc::VolumeIdx(1))
.unwrap();
println!("Volume: {:?}", volume);
let mut root_dir = volume.open_root_dir().unwrap();

let mut file_num = 0;
loop {
file_num += 1;
let file_name = format!("{}.da", file_num);
println!("opening file {file_name} for writing");
let mut file = root_dir
.open_file_in_dir(
file_name.as_str(),
embedded_sdmmc::Mode::ReadWriteCreateOrTruncate,
)
.unwrap();
let buf = b"hello world, from rust";
println!("writing to file");
file.write(&buf[..]).unwrap();
println!("closing file");
drop(file);
}
}
10 changes: 4 additions & 6 deletions examples/create_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume_mgr.open_root_dir(volume)?;
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
let mut root_dir = volume.open_root_dir()?;
println!("\nCreating file {}...", FILE_TO_CREATE);
// This will panic if the file already exists: use ReadWriteCreateOrAppend
// or ReadWriteCreateOrTruncate instead if you want to modify an existing
// file.
let f = volume_mgr.open_file_in_dir(root_dir, FILE_TO_CREATE, Mode::ReadWriteCreate)?;
volume_mgr.write(f, b"Hello, this is a new file on disk\r\n")?;
volume_mgr.close_file(f)?;
volume_mgr.close_dir(root_dir)?;
let mut f = root_dir.open_file_in_dir(FILE_TO_CREATE, Mode::ReadWriteCreate)?;
f.write(b"Hello, this is a new file on disk\r\n")?;
Ok(())
}

Expand Down
7 changes: 3 additions & 4 deletions examples/delete_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,11 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume_mgr.open_root_dir(volume)?;
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
let mut root_dir = volume.open_root_dir()?;
println!("Deleting file {}...", FILE_TO_DELETE);
volume_mgr.delete_file_in_dir(root_dir, FILE_TO_DELETE)?;
root_dir.delete_file_in_dir(FILE_TO_DELETE)?;
println!("Deleted!");
volume_mgr.close_dir(root_dir)?;
Ok(())
}

Expand Down
28 changes: 12 additions & 16 deletions examples/list_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,22 @@ fn main() -> Result<(), Error> {
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume_mgr.open_root_dir(volume)?;
list_dir(&mut volume_mgr, root_dir, "/")?;
volume_mgr.close_dir(root_dir)?;
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume.open_root_dir()?;
list_dir(root_dir, "/")?;
Ok(())
}

/// Recursively print a directory listing for the open directory given.
///
/// The path is for display purposes only.
fn list_dir(
volume_mgr: &mut VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4>,
directory: Directory,
mut directory: Directory<LinuxBlockDevice, Clock, 8, 8, 4>,
path: &str,
) -> Result<(), Error> {
println!("Listing {}", path);
let mut children = Vec::new();
volume_mgr.iterate_dir(directory, |entry| {
directory.iterate_dir(|entry| {
println!(
"{:12} {:9} {} {}",
entry.name,
Expand All @@ -78,23 +76,21 @@ fn list_dir(
""
}
);
if entry.attributes.is_directory() {
if entry.name != embedded_sdmmc::ShortFileName::parent_dir()
&& entry.name != embedded_sdmmc::ShortFileName::this_dir()
{
children.push(entry.name.clone());
}
if entry.attributes.is_directory()
&& entry.name != embedded_sdmmc::ShortFileName::parent_dir()
&& entry.name != embedded_sdmmc::ShortFileName::this_dir()
{
children.push(entry.name.clone());
}
})?;
for child_name in children {
let child_dir = volume_mgr.open_dir(directory, &child_name)?;
let child_dir = directory.open_dir(&child_name)?;
let child_path = if path == "/" {
format!("/{}", child_name)
} else {
format!("{}/{}", path, child_name)
};
list_dir(volume_mgr, child_dir, &child_path)?;
volume_mgr.close_dir(child_dir)?;
list_dir(child_dir, &child_path)?;
}
Ok(())
}
Expand Down
14 changes: 6 additions & 8 deletions examples/read_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
let lbd = LinuxBlockDevice::new(filename, print_blocks).map_err(Error::DeviceError)?;
let mut volume_mgr: VolumeManager<LinuxBlockDevice, Clock, 8, 8, 4> =
VolumeManager::new_with_limits(lbd, Clock, 0xAA00_0000);
let volume = volume_mgr.open_volume(VolumeIdx(0))?;
let root_dir = volume_mgr.open_root_dir(volume)?;
let mut volume = volume_mgr.open_volume(VolumeIdx(0))?;
let mut root_dir = volume.open_root_dir()?;
println!("\nReading file {}...", FILE_TO_READ);
let f = volume_mgr.open_file_in_dir(root_dir, FILE_TO_READ, Mode::ReadOnly)?;
volume_mgr.close_dir(root_dir)?;
while !volume_mgr.file_eof(f)? {
let mut f = root_dir.open_file_in_dir(FILE_TO_READ, Mode::ReadOnly)?;
while !f.is_eof() {
let mut buffer = [0u8; 16];
let offset = volume_mgr.file_offset(f)?;
let mut len = volume_mgr.read(f, &mut buffer)?;
let offset = f.offset();
let mut len = f.read(&mut buffer)?;
print!("{:08x} {:02x?}", offset, &buffer[0..len]);
while len < buffer.len() {
print!(" ");
Expand All @@ -74,7 +73,6 @@ fn main() -> Result<(), embedded_sdmmc::Error<std::io::Error>> {
}
println!("|");
}
volume_mgr.close_file(f)?;
Ok(())
}

Expand Down
Loading