Skip to content

Commit

Permalink
add support for async BlockDevice
Browse files Browse the repository at this point in the history
  • Loading branch information
brunob45 committed Oct 19, 2024
1 parent 1b9fa5c commit a0fb123
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 152 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ byteorder = {version = "1", default-features = false}
defmt = {version = "0.3", optional = true}
embedded-hal = "1.0.0"
embedded-io = "0.6.1"
embedded-io-async = "0.6.1"
heapless = "^0.8"
log = {version = "0.4", default-features = false, optional = true}
maybe-async = {version="0.2"}

[dev-dependencies]
chrono = "0.4"
Expand All @@ -27,6 +29,7 @@ hex-literal = "0.4.1"
sha2 = "0.10"

[features]
default = ["log"]
default = ["log", "is_sync"]
defmt-log = ["dep:defmt"]
log = ["dep:log"]
is_sync = ["maybe-async/is_sync"]
21 changes: 13 additions & 8 deletions src/blockdevice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ impl Default for Block {

/// A block device - a device which can read and write blocks (or
/// sectors). Only supports devices which are <= 2 TiB in size.
#[allow(async_fn_in_trait)]
#[maybe_async::maybe_async(AFIT)]
pub trait BlockDevice {
/// The errors that the `BlockDevice` can return. Must be debug formattable.
type Error: core::fmt::Debug;
/// Read one or more blocks, starting at the given block index.
fn read(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
async fn read(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
/// Write one or more blocks, starting at the given block index.
fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
async fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
/// Determine how many blocks this device can hold.
fn num_blocks(&self) -> Result<BlockCount, Self::Error>;
}
Expand Down Expand Up @@ -110,31 +112,34 @@ where
}

/// Read a block, and return a reference to it.
pub fn read(&mut self, block_idx: BlockIdx) -> Result<&Block, D::Error> {
#[maybe_async::maybe_async]
pub async fn read(&mut self, block_idx: BlockIdx) -> Result<&Block, D::Error> {
if self.block_idx != Some(block_idx) {
self.block_idx = None;
self.block_device.read(&mut self.block, block_idx)?;
self.block_device.read(&mut self.block, block_idx).await?;
self.block_idx = Some(block_idx);
}
Ok(&self.block[0])
}

/// Read a block, and return a reference to it.
pub fn read_mut(&mut self, block_idx: BlockIdx) -> Result<&mut Block, D::Error> {
#[maybe_async::maybe_async]
pub async fn read_mut(&mut self, block_idx: BlockIdx) -> Result<&mut Block, D::Error> {
if self.block_idx != Some(block_idx) {
self.block_idx = None;
self.block_device.read(&mut self.block, block_idx)?;
self.block_device.read(&mut self.block, block_idx).await?;
self.block_idx = Some(block_idx);
}
Ok(&mut self.block[0])
}

/// Write back a block you read with [`Self::read_mut`] and then modified.
pub fn write_back(&mut self) -> Result<(), D::Error> {
#[maybe_async::maybe_async]
pub async fn write_back(&mut self) -> Result<(), D::Error> {
self.block_device.write(
&self.block,
self.block_idx.expect("write_back with no read"),
)
).await
}

/// Access a blank sector
Expand Down
Loading

0 comments on commit a0fb123

Please sign in to comment.