Skip to content

Commit 09a7d55

Browse files
authored
Merge branch 'develop' into impl-core-error
2 parents 556fee7 + 2851be4 commit 09a7d55

File tree

8 files changed

+103
-20
lines changed

8 files changed

+103
-20
lines changed

.github/workflows/rust.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@ jobs:
2727
toolchain: ${{ matrix.rust }}
2828
- name: Build
2929
run: cargo build --no-default-features --features ${{matrix.features}} --verbose
30+
env:
31+
DEFMT_LOG: debug
3032
- name: Run Tests
3133
run: cargo test --no-default-features --features ${{matrix.features}} --verbose

CHANGELOG.md

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
66

77
## [Unreleased]
88

9+
## [Version 0.9.0] - 2025-06-08
10+
911
### Changed
1012

1113
- __Breaking Change__: `VolumeManager` now uses interior-mutability (with a `RefCell`) and so most methods are now `&self`. This also makes it easier to open multiple `File`, `Directory` or `Volume` objects at once.
12-
- __Breaking Change__: The `VolumeManager`, `File`, `Directory` and `Volume` no longer implement `Send` or `Sync.
14+
- __Breaking Change__: The `VolumeManager`, `File`, `Directory` and `Volume` no longer implement `Send` or `Sync`.
1315
- `VolumeManager` uses an interior block cache of 512 bytes, increasing its size by about 520 bytes but hugely reducing stack space required at run-time.
1416
- __Breaking Change__: The `VolumeManager::device` method now takes a callback rather than giving you a reference to the underlying `BlockDevice`
1517
- __Breaking Change__: `Error:LockError` variant added.
1618
- __Breaking Change__: `SearchId` was renamed to `Handle`
19+
- Fixed writing at block start mid-file (previously overwrote subsequent file data with zeros up to the end of the block)
1720

1821
### Added
1922

@@ -25,6 +28,20 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
2528

2629
- __Breaking Change__: Removed the `reason: &str` argument from `BlockDevice`
2730

31+
## [Version 0.8.2] - 2025-06-07
32+
33+
### Changed
34+
35+
* Fixed writing at block start mid-file (previously overwrote subsequent file data with zeros up to the end of the block)
36+
37+
## [Version 0.8.1] - 2024-11-03
38+
39+
### Changed
40+
41+
* Second FAT is now updated, if it is present
42+
* When creating a directory `..` now points at the root directory correctly
43+
* The info block containing the free cluster count is now updated when unmounting a FAT32 volume.
44+
2845
## [Version 0.8.0] - 2024-07-12
2946

3047
### Changed
@@ -173,13 +190,16 @@ The format is based on [Keep a Changelog] and this project adheres to [Semantic
173190

174191
[Keep a Changelog]: http://keepachangelog.com/en/1.0.0/
175192
[Semantic Versioning]: http://semver.org/spec/v2.0.0.html
176-
[Unreleased]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.0...develop
177-
[Version 0.8.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.0...v0.7.0
178-
[Version 0.7.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.7.0...v0.6.0
179-
[Version 0.6.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.6.0...v0.5.0
180-
[Version 0.5.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.5.0...v0.4.0
181-
[Version 0.4.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.4.0...v0.3.0
182-
[Version 0.3.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.3.0...v0.2.1
183-
[Version 0.2.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.1...v0.2.0
184-
[Version 0.2.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.0...v0.1.1
193+
[Unreleased]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.9.0...develop
194+
[Version 0.9.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.2...v0.9.0
195+
[Version 0.8.2]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.1...v0.8.2
196+
[Version 0.8.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.8.0...v0.8.1
197+
[Version 0.8.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.7.0...v0.8.0
198+
[Version 0.7.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.6.0...v0.7.0
199+
[Version 0.6.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.5.0...v0.6.0
200+
[Version 0.5.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.4.0...v0.5.0
201+
[Version 0.4.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.3.0...v0.4.0
202+
[Version 0.3.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.1...v0.3.0
203+
[Version 0.2.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.2.0...v0.2.1
204+
[Version 0.2.0]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/compare/v0.1.1...v0.2.0
185205
[Version 0.1.1]: https://github.com/rust-embedded-community/embedded-sdmmc-rs/releases/tag/v0.1.1

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
88
name = "embedded-sdmmc"
99
readme = "README.md"
1010
repository = "https://github.com/rust-embedded-community/embedded-sdmmc-rs"
11-
version = "0.8.0"
11+
version = "0.9.0"
1212

1313
# Make sure to update the CI too!
1414
rust-version = "1.76"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ let cont: VolumeManager<_, _, 6, 12, 4> = VolumeManager::new_with_limits(block,
7070
* Delete files
7171
* Iterate root directory
7272
* Iterate sub-directories
73+
* Create directories
7374
* Log over defmt or the common log interface (feature flags).
7475

7576
## No-std usage
@@ -82,7 +83,6 @@ This repository houses no examples for no-std usage, however you can check out t
8283

8384
## Todo List (PRs welcome!)
8485

85-
* Create new dirs
8686
* Delete (empty) directories
8787
* Handle MS-DOS `/path/foo/bar.txt` style paths.
8888

src/fat/volume.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ impl FatVolume {
594594
debug!("LFN Contents {start} {sequence} {csum:02x} {buffer:04x?}");
595595
#[cfg(feature = "defmt-log")]
596596
debug!(
597-
"LFN Contents {=u8} {=u8} {=u8:02x} {=[?; 13]:#04x}",
597+
"LFN Contents {=bool} {=u8} {=u8:02x} {=[?; 13]:#04x}",
598598
start, sequence, csum, buffer
599599
);
600600
match (start, sequence, self) {

src/filesystem/files.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl<
190190
if buf.is_empty() {
191191
Ok(0)
192192
} else {
193-
self.read(buf)
193+
File::read(self, buf)
194194
}
195195
}
196196
}
@@ -207,7 +207,7 @@ impl<
207207
if buf.is_empty() {
208208
Ok(0)
209209
} else {
210-
self.write(buf)?;
210+
File::write(self, buf)?;
211211
Ok(buf.len())
212212
}
213213
}

src/volume_mgr.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ where
9494
}
9595

9696
/// Temporarily get access to the underlying block device.
97-
pub fn device<F>(&self, f: F) -> T
97+
pub fn device<R, F>(&self, f: F) -> R
9898
where
99-
F: FnOnce(&mut D) -> T,
99+
F: FnOnce(&mut D) -> R,
100100
{
101101
let mut data = self.data.borrow_mut();
102102
let result = f(data.block_cache.block_device());
@@ -878,13 +878,15 @@ where
878878
Err(e) => return Err(e),
879879
};
880880
let to_copy = core::cmp::min(block_avail, bytes_to_write - written);
881-
let block = if block_offset != 0 {
881+
let block = if (block_offset == 0) && (to_copy == block_avail) {
882+
// we're replacing the whole Block, so the previous contents
883+
// are irrelevant
884+
data.block_cache.blank_mut(block_idx)
885+
} else {
882886
debug!("Reading for partial block write");
883887
data.block_cache
884888
.read_mut(block_idx)
885889
.map_err(Error::DeviceError)?
886-
} else {
887-
data.block_cache.blank_mut(block_idx)
888890
};
889891
block[block_offset..block_offset + to_copy]
890892
.copy_from_slice(&buffer[written..written + to_copy]);

tests/write_file.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,65 @@ fn flush_file() {
102102
assert_eq!(entry.size, 64 * 3);
103103
}
104104

105+
#[test]
106+
fn random_access_write_file() {
107+
let time_source = utils::make_time_source();
108+
let disk = utils::make_block_device(utils::DISK_SOURCE).unwrap();
109+
let volume_mgr: VolumeManager<utils::RamDisk<Vec<u8>>, utils::TestTimeSource, 4, 2, 1> =
110+
VolumeManager::new_with_limits(disk, time_source, 0xAA00_0000);
111+
let volume = volume_mgr
112+
.open_raw_volume(VolumeIdx(0))
113+
.expect("open volume");
114+
let root_dir = volume_mgr.open_root_dir(volume).expect("open root dir");
115+
116+
// Open with string
117+
let f = volume_mgr
118+
.open_file_in_dir(root_dir, "README.TXT", Mode::ReadWriteTruncate)
119+
.expect("open file");
120+
121+
let test_data = vec![0xCC; 1024];
122+
volume_mgr.write(f, &test_data).expect("file write");
123+
124+
let length = volume_mgr.file_length(f).expect("get length");
125+
assert_eq!(length, 1024);
126+
127+
for seek_offset in [100, 0] {
128+
let mut expected_buffer = [0u8; 4];
129+
130+
// fetch some data at offset seek_offset
131+
volume_mgr
132+
.file_seek_from_start(f, seek_offset)
133+
.expect("Seeking");
134+
volume_mgr.read(f, &mut expected_buffer).expect("read file");
135+
136+
// modify first byte
137+
expected_buffer[0] ^= 0xff;
138+
139+
// write only first byte, expecting the rest to not change
140+
volume_mgr
141+
.file_seek_from_start(f, seek_offset)
142+
.expect("Seeking");
143+
volume_mgr
144+
.write(f, &expected_buffer[0..1])
145+
.expect("file write");
146+
volume_mgr.flush_file(f).expect("file flush");
147+
148+
// read and verify
149+
volume_mgr
150+
.file_seek_from_start(f, seek_offset)
151+
.expect("file seek");
152+
let mut read_buffer = [0xffu8, 0xff, 0xff, 0xff];
153+
volume_mgr.read(f, &mut read_buffer).expect("file read");
154+
assert_eq!(
155+
read_buffer, expected_buffer,
156+
"mismatch seek+write at offset {seek_offset} from start"
157+
);
158+
}
159+
160+
volume_mgr.close_file(f).expect("close file");
161+
volume_mgr.close_dir(root_dir).expect("close dir");
162+
volume_mgr.close_volume(volume).expect("close volume");
163+
}
105164
// ****************************************************************************
106165
//
107166
// End Of File

0 commit comments

Comments
 (0)