Skip to content

Commit f454fb7

Browse files
committed
Refactor filesystem and volume manager to support async operations
- Updated methods in `directory.rs`, `files.rs`, `lib.rs`, `mod.rs`, and `volume_mgr.rs` to be async. - Added `maybe_async` attributes to conditionally compile sync/async versions based on feature flags. - Modified method implementations to await asynchronous calls where necessary. - Ensured compatibility with both async and sync contexts throughout the filesystem and volume management code.
1 parent c629f38 commit f454fb7

File tree

8 files changed

+466
-212
lines changed

8 files changed

+466
-212
lines changed

Cargo.toml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
[package]
2-
authors = ["Jonathan 'theJPster' Pallant <[email protected]>", "Rust Embedded Community Developers"]
2+
authors = [
3+
"Jonathan 'theJPster' Pallant <[email protected]>",
4+
"Rust Embedded Community Developers",
5+
]
36
categories = ["embedded", "no-std"]
47
description = "A basic SD/MMC driver for Embedded Rust."
58
edition = "2021"
@@ -14,12 +17,14 @@ version = "0.9.0"
1417
rust-version = "1.86"
1518

1619
[dependencies]
17-
byteorder = {version = "1", default-features = false}
18-
defmt = {version = "1.0.1", optional = true}
20+
byteorder = { version = "1", default-features = false }
21+
defmt = { version = "1.0.1", optional = true }
1922
embedded-hal = "1.0.0"
2023
embedded-io = "0.6.1"
24+
embedded-io-async = "0.6.1"
2125
heapless = "0.9.1"
22-
log = {version = "0.4", default-features = false, optional = true}
26+
log = { version = "0.4", default-features = false, optional = true }
27+
maybe-async = "0.2.10"
2328

2429
[dev-dependencies]
2530
chrono = "0.4"
@@ -30,7 +35,8 @@ hex-literal = "1.0.0"
3035
sha2 = "0.10"
3136

3237
[features]
33-
default = ["log"]
38+
default = ["log", "async"]
3439
defmt-log = ["dep:defmt"]
3540
log = ["dep:log"]
41+
async = []
3642
core-error = []

src/blockdevice.rs

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ impl Default for Block {
7575

7676
/// A block device - a device which can read and write blocks (or
7777
/// sectors). Only supports devices which are <= 2 TiB in size.
78+
#[cfg(not(feature = "async"))]
7879
pub trait BlockDevice {
7980
/// The errors that the `BlockDevice` can return. Must be debug formattable.
8081
type Error: core::fmt::Debug;
@@ -86,6 +87,30 @@ pub trait BlockDevice {
8687
fn num_blocks(&self) -> Result<BlockCount, Self::Error>;
8788
}
8889

90+
/// A block device - a device which can read and write blocks (or
91+
/// sectors). Only supports devices which are <= 2 TiB in size.
92+
#[cfg(feature = "async")]
93+
pub trait BlockDevice {
94+
/// The errors that the `BlockDevice` can return. Must be debug formattable.
95+
type Error: core::fmt::Debug;
96+
/// Read one or more blocks, starting at the given block index.
97+
fn read(
98+
&self,
99+
blocks: &mut [Block],
100+
start_block_idx: BlockIdx,
101+
) -> impl core::future::Future<Output = Result<(), Self::Error>> + Send;
102+
/// Write one or more blocks, starting at the given block index.
103+
fn write(
104+
&self,
105+
blocks: &[Block],
106+
start_block_idx: BlockIdx,
107+
) -> impl core::future::Future<Output = Result<(), Self::Error>> + Send;
108+
/// Determine how many blocks this device can hold.
109+
fn num_blocks(
110+
&self,
111+
) -> impl core::future::Future<Output = Result<BlockCount, Self::Error>> + Send;
112+
}
113+
89114
/// A caching layer for block devices
90115
///
91116
/// Caches a single block.
@@ -110,42 +135,54 @@ where
110135
}
111136

112137
/// Read a block, and return a reference to it.
113-
pub fn read(&mut self, block_idx: BlockIdx) -> Result<&Block, D::Error> {
138+
#[cfg_attr(feature = "async", maybe_async::must_be_async)]
139+
#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
140+
pub async fn read(&mut self, block_idx: BlockIdx) -> Result<&Block, D::Error> {
114141
if self.block_idx != Some(block_idx) {
115142
self.block_idx = None;
116-
self.block_device.read(&mut self.block, block_idx)?;
143+
self.block_device.read(&mut self.block, block_idx).await?;
117144
self.block_idx = Some(block_idx);
118145
}
119146
Ok(&self.block[0])
120147
}
121148

122149
/// Read a block, and return a reference to it.
123-
pub fn read_mut(&mut self, block_idx: BlockIdx) -> Result<&mut Block, D::Error> {
150+
#[cfg_attr(feature = "async", maybe_async::must_be_async)]
151+
#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
152+
pub async fn read_mut(&mut self, block_idx: BlockIdx) -> Result<&mut Block, D::Error> {
124153
if self.block_idx != Some(block_idx) {
125154
self.block_idx = None;
126-
self.block_device.read(&mut self.block, block_idx)?;
155+
self.block_device.read(&mut self.block, block_idx).await?;
127156
self.block_idx = Some(block_idx);
128157
}
129158
Ok(&mut self.block[0])
130159
}
131160

132161
/// Write back a block you read with [`Self::read_mut`] and then modified.
133-
pub fn write_back(&mut self) -> Result<(), D::Error> {
134-
self.block_device.write(
135-
&self.block,
136-
self.block_idx.expect("write_back with no read"),
137-
)
162+
#[cfg_attr(feature = "async", maybe_async::must_be_async)]
163+
#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
164+
pub async fn write_back(&mut self) -> Result<(), D::Error> {
165+
self.block_device
166+
.write(
167+
&self.block,
168+
self.block_idx.expect("write_back with no read"),
169+
)
170+
.await
138171
}
139172

140173
/// Write back a block you read with [`Self::read_mut`] and then modified, but to two locations.
141174
///
142175
/// This is useful for updating two File Allocation Tables.
143-
pub fn write_back_with_duplicate(&mut self, duplicate: BlockIdx) -> Result<(), D::Error> {
144-
self.block_device.write(
145-
&self.block,
146-
self.block_idx.expect("write_back with no read"),
147-
)?;
148-
self.block_device.write(&self.block, duplicate)?;
176+
#[cfg_attr(feature = "async", maybe_async::must_be_async)]
177+
#[cfg_attr(not(feature = "async"), maybe_async::must_be_sync)]
178+
pub async fn write_back_with_duplicate(&mut self, duplicate: BlockIdx) -> Result<(), D::Error> {
179+
self.block_device
180+
.write(
181+
&self.block,
182+
self.block_idx.expect("write_back with no read"),
183+
)
184+
.await?;
185+
self.block_device.write(&self.block, duplicate).await?;
149186
Ok(())
150187
}
151188

0 commit comments

Comments
 (0)