Skip to content

Commit

Permalink
Add more tests, and more changes.
Browse files Browse the repository at this point in the history
- Cluster is now ClusterId
- Helper method for turning bytes to a block count
- Removed unsafe open_dir_entry API
  • Loading branch information
jonathanpallant committed Sep 22, 2023
1 parent c63688f commit 457de81
Show file tree
Hide file tree
Showing 17 changed files with 351 additions and 188 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Calling `SdCard::get_card_type` will now perform card initialisation ([#87] and [#90]).
- Removed warning about unused arguments.
- Types are now documented at the top level ([#86]).
- Renamed `Cluster` to `ClusterId` and stopped you adding two together

[#72]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/issues/72
[#86]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/issues/86
Expand All @@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Removed

- __Breaking Change__: `Controller` alias for `VolumeManager` removed.
- __Breaking Change__: `VolumeManager::open_dir_entry` removed, as it was unsafe to the user to randomly pick a starting cluster.
- Old examples `create_test`, `test_mount`, `write_test`, `delete_test`

## [Version 0.5.0](https://github.com/rust-embedded-community/embedded-sdmmc-rs/releases/tag/v0.5.0) - 2023-05-20
Expand Down Expand Up @@ -60,7 +62,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Optionally use [defmt](https://github.com/knurling-rs/defmt) for logging.
Controlled by `defmt-log` feature flag.
- __Breaking Change__: Use SPI blocking traits instead to ease SPI peripheral sharing.
See: https://github.com/rust-embedded-community/embedded-sdmmc-rs/issues/28
See: <https://github.com/rust-embedded-community/embedded-sdmmc-rs/issues/28>
- Added `Controller::has_open_handles` and `Controller::free` methods.
- __Breaking Change__: Changed interface to enforce correct SD state at compile time.
- __Breaking Change__: Added custom error type for `File` operations.
Expand All @@ -81,7 +83,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added `Info_Sector` tracking for FAT32.
- Change directory iteration to look in all the directory's clusters.
- Added `write_test` and `create_test`.
- De-duplicated FAT16 and FAT32 code (https://github.com/thejpster/embedded-sdmmc-rs/issues/10)
- De-duplicated FAT16 and FAT32 code (<https://github.com/thejpster/embedded-sdmmc-rs/issues/10>)

## [Version 0.2.1](https://github.com/rust-embedded-community/embedded-sdmmc-rs/releases/tag/v0.2.1) - 2019-02-19

Expand Down
20 changes: 19 additions & 1 deletion src/blockdevice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,24 @@ impl BlockIdx {
}

impl BlockCount {
/// How many blocks are required to hold this many bytes.
///
/// ```
/// # use embedded_sdmmc::BlockCount;
/// assert_eq!(BlockCount::from_bytes(511), BlockCount(1));
/// assert_eq!(BlockCount::from_bytes(512), BlockCount(1));
/// assert_eq!(BlockCount::from_bytes(513), BlockCount(2));
/// assert_eq!(BlockCount::from_bytes(1024), BlockCount(2));
/// assert_eq!(BlockCount::from_bytes(1025), BlockCount(3));
/// ```
pub const fn from_bytes(byte_count: u32) -> BlockCount {
let mut count = byte_count / Block::LEN_U32;
if (count * Block::LEN_U32) != byte_count {
count += 1;
}
BlockCount(count)
}

/// Take a number of blocks and increment by the integer number of blocks
/// required to get to the block that holds the byte at the given offset.
pub fn offset_bytes(self, offset: u32) -> Self {
Expand All @@ -187,7 +205,7 @@ impl BlockCount {
impl BlockIter {
/// Create a new `BlockIter`, from the given start block, through (and
/// including) the given end block.
pub fn new(start: BlockIdx, inclusive_end: BlockIdx) -> BlockIter {
pub const fn new(start: BlockIdx, inclusive_end: BlockIdx) -> BlockIter {
BlockIter {
inclusive_end,
current: start,
Expand Down
15 changes: 7 additions & 8 deletions src/fat/bpb.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Boot Parameter Block

use crate::{
blockdevice::{Block, BlockCount},
blockdevice::BlockCount,
fat::{FatType, OnDiskDirEntry},
};
use byteorder::{ByteOrder, LittleEndian};
Expand Down Expand Up @@ -29,13 +29,12 @@ impl<'a> Bpb<'a> {
return Err("Bad BPB footer");
}

let root_dir_blocks = ((u32::from(bpb.root_entries_count()) * OnDiskDirEntry::LEN_U32)
+ (Block::LEN_U32 - 1))
/ Block::LEN_U32;
let data_blocks = bpb.total_blocks()
- (u32::from(bpb.reserved_block_count())
+ (u32::from(bpb.num_fats()) * bpb.fat_size())
+ root_dir_blocks);
let root_dir_blocks =
BlockCount::from_bytes(u32::from(bpb.root_entries_count()) * OnDiskDirEntry::LEN_U32).0;
let non_data_blocks = u32::from(bpb.reserved_block_count())
+ (u32::from(bpb.num_fats()) * bpb.fat_size())
+ root_dir_blocks;
let data_blocks = bpb.total_blocks() - non_data_blocks;
bpb.cluster_count = data_blocks / u32::from(bpb.blocks_per_cluster());
if bpb.cluster_count < 4085 {
return Err("FAT12 is unsupported");
Expand Down
8 changes: 4 additions & 4 deletions src/fat/info.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{BlockCount, BlockIdx, Cluster};
use crate::{BlockCount, BlockIdx, ClusterId};
use byteorder::{ByteOrder, LittleEndian};

/// Indentifies the supported types of FAT format
Expand All @@ -17,7 +17,7 @@ pub enum FatSpecificInfo {
pub struct Fat32Info {
/// The root directory does not have a reserved area in FAT32. This is the
/// cluster it starts in (nominally 2).
pub(crate) first_root_dir_cluster: Cluster,
pub(crate) first_root_dir_cluster: ClusterId,
/// Block idx of the info sector
pub(crate) info_location: BlockIdx,
}
Expand Down Expand Up @@ -78,11 +78,11 @@ impl<'a> InfoSector<'a> {
}

/// Return the number of the next free cluster, if known.
pub fn next_free_cluster(&self) -> Option<Cluster> {
pub fn next_free_cluster(&self) -> Option<ClusterId> {
match self.next_free() {
// 0 and 1 are reserved clusters
0xFFFF_FFFF | 0 | 1 => None,
n => Some(Cluster(n)),
n => Some(ClusterId(n)),
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/fat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use crate::{Block, BlockDevice, BlockIdx, Error};
mod test {

use super::*;
use crate::{Attributes, BlockIdx, Cluster, DirEntry, ShortFileName, Timestamp};
use crate::{Attributes, BlockIdx, ClusterId, DirEntry, ShortFileName, Timestamp};

fn parse(input: &str) -> Vec<u8> {
let mut output = Vec::new();
Expand Down Expand Up @@ -143,7 +143,7 @@ mod test {
mtime: Timestamp::from_calendar(2015, 11, 21, 19, 35, 18).unwrap(),
ctime: Timestamp::from_calendar(2015, 11, 21, 19, 35, 18).unwrap(),
attributes: Attributes::create_from_fat(Attributes::VOLUME),
cluster: Cluster(0),
cluster: ClusterId(0),
size: 0,
entry_block: BlockIdx(0),
entry_offset: 0,
Expand All @@ -161,7 +161,7 @@ mod test {
mtime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 54).unwrap(),
ctime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 54).unwrap(),
attributes: Attributes::create_from_fat(Attributes::DIRECTORY),
cluster: Cluster(3),
cluster: ClusterId(3),
size: 0,
entry_block: BlockIdx(0),
entry_offset: 0,
Expand All @@ -186,7 +186,7 @@ mod test {
mtime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 34).unwrap(),
ctime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 34).unwrap(),
attributes: Attributes::create_from_fat(Attributes::ARCHIVE),
cluster: Cluster(9),
cluster: ClusterId(9),
size: 11120,
entry_block: BlockIdx(0),
entry_offset: 0,
Expand All @@ -203,7 +203,7 @@ mod test {
mtime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 30).unwrap(),
ctime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 30).unwrap(),
attributes: Attributes::create_from_fat(Attributes::ARCHIVE),
cluster: Cluster(5),
cluster: ClusterId(5),
size: 18693,
entry_block: BlockIdx(0),
entry_offset: 0,
Expand All @@ -228,7 +228,7 @@ mod test {
mtime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 34).unwrap(),
ctime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 34).unwrap(),
attributes: Attributes::create_from_fat(Attributes::ARCHIVE),
cluster: Cluster(8),
cluster: ClusterId(8),
size: 1494,
entry_block: BlockIdx(0),
entry_offset: 0,
Expand All @@ -253,7 +253,7 @@ mod test {
mtime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 36).unwrap(),
ctime: Timestamp::from_calendar(2016, 3, 1, 19, 56, 36).unwrap(),
attributes: Attributes::create_from_fat(Attributes::ARCHIVE),
cluster: Cluster(15),
cluster: ClusterId(15),
size: 12108,
entry_block: BlockIdx(0),
entry_offset: 0,
Expand Down
10 changes: 5 additions & 5 deletions src/fat/ondiskdirentry.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Directory Entry as stored on-disk

use crate::{fat::FatType, Attributes, BlockIdx, Cluster, DirEntry, ShortFileName, Timestamp};
use crate::{fat::FatType, Attributes, BlockIdx, ClusterId, DirEntry, ShortFileName, Timestamp};
use byteorder::{ByteOrder, LittleEndian};

/// Represents a 32-byte directory entry as stored on-disk in a directory file.
Expand Down Expand Up @@ -129,16 +129,16 @@ impl<'a> OnDiskDirEntry<'a> {
}

/// Which cluster, if any, does this file start at? Assumes this is from a FAT32 volume.
pub fn first_cluster_fat32(&self) -> Cluster {
pub fn first_cluster_fat32(&self) -> ClusterId {
let cluster_no =
(u32::from(self.first_cluster_hi()) << 16) | u32::from(self.first_cluster_lo());
Cluster(cluster_no)
ClusterId(cluster_no)
}

/// Which cluster, if any, does this file start at? Assumes this is from a FAT16 volume.
fn first_cluster_fat16(&self) -> Cluster {
fn first_cluster_fat16(&self) -> ClusterId {
let cluster_no = u32::from(self.first_cluster_lo());
Cluster(cluster_no)
ClusterId(cluster_no)
}

/// Convert the on-disk format into a DirEntry
Expand Down
Loading

0 comments on commit 457de81

Please sign in to comment.