Skip to content

Commit d2706c7

Browse files
committed
Use embedded-storage BlockDevice trait.
This will allow both the SD card driver and the FAT32 implementation to be used with filesystem or block device drivers respectively.
1 parent 1b9fa5c commit d2706c7

File tree

8 files changed

+313
-312
lines changed

8 files changed

+313
-312
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ byteorder = {version = "1", default-features = false}
1515
defmt = {version = "0.3", optional = true}
1616
embedded-hal = "1.0.0"
1717
embedded-io = "0.6.1"
18+
embedded-storage = { git = "https://github.com/qwandor/embedded-storage", branch = "block" }
1819
heapless = "^0.8"
1920
log = {version = "0.4", default-features = false, optional = true}
2021

src/blockdevice.rs

Lines changed: 29 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -3,88 +3,27 @@
33
//! Generic code for handling block devices, such as types for identifying
44
//! a particular block on a block device by its index.
55
6+
use embedded_storage::BlockDevice;
7+
68
/// A standard 512 byte block (also known as a sector).
79
///
810
/// IBM PC formatted 5.25" and 3.5" floppy disks, IDE/SATA Hard Drives up to
911
/// about 2 TiB, and almost all SD/MMC cards have 512 byte blocks.
1012
///
1113
/// This library does not support devices with a block size other than 512
1214
/// bytes.
13-
#[derive(Clone)]
14-
pub struct Block {
15-
/// The 512 bytes in this block (or sector).
16-
pub contents: [u8; Block::LEN],
17-
}
15+
pub type Block = [u8; BLOCK_LEN];
1816

19-
impl Block {
20-
/// All our blocks are a fixed length of 512 bytes. We do not support
21-
/// 'Advanced Format' Hard Drives with 4 KiB blocks, nor weird old
22-
/// pre-3.5-inch floppy disk formats.
23-
pub const LEN: usize = 512;
17+
/// All our blocks are a fixed length of 512 bytes. We do not support
18+
/// 'Advanced Format' Hard Drives with 4 KiB blocks, nor weird old
19+
/// pre-3.5-inch floppy disk formats.
20+
pub const BLOCK_LEN: usize = 512;
2421

25-
/// Sometimes we want `LEN` as a `u32` and the casts don't look nice.
26-
pub const LEN_U32: u32 = 512;
22+
/// Sometimes we want `LEN` as a `u32` and the casts don't look nice.
23+
pub const BLOCK_LEN_U32: u32 = 512;
2724

28-
/// Create a new block full of zeros.
29-
pub fn new() -> Block {
30-
Block {
31-
contents: [0u8; Self::LEN],
32-
}
33-
}
34-
}
35-
36-
impl core::ops::Deref for Block {
37-
type Target = [u8; 512];
38-
fn deref(&self) -> &[u8; 512] {
39-
&self.contents
40-
}
41-
}
42-
43-
impl core::ops::DerefMut for Block {
44-
fn deref_mut(&mut self) -> &mut [u8; 512] {
45-
&mut self.contents
46-
}
47-
}
48-
49-
impl core::fmt::Debug for Block {
50-
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
51-
writeln!(fmt, "Block:")?;
52-
for line in self.contents.chunks(32) {
53-
for b in line {
54-
write!(fmt, "{:02x}", b)?;
55-
}
56-
write!(fmt, " ")?;
57-
for &b in line {
58-
if (0x20..=0x7F).contains(&b) {
59-
write!(fmt, "{}", b as char)?;
60-
} else {
61-
write!(fmt, ".")?;
62-
}
63-
}
64-
writeln!(fmt)?;
65-
}
66-
Ok(())
67-
}
68-
}
69-
70-
impl Default for Block {
71-
fn default() -> Self {
72-
Self::new()
73-
}
74-
}
75-
76-
/// A block device - a device which can read and write blocks (or
77-
/// sectors). Only supports devices which are <= 2 TiB in size.
78-
pub trait BlockDevice {
79-
/// The errors that the `BlockDevice` can return. Must be debug formattable.
80-
type Error: core::fmt::Debug;
81-
/// Read one or more blocks, starting at the given block index.
82-
fn read(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
83-
/// Write one or more blocks, starting at the given block index.
84-
fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
85-
/// Determine how many blocks this device can hold.
86-
fn num_blocks(&self) -> Result<BlockCount, Self::Error>;
87-
}
25+
/// Sometimes we want `LEN` as a `u64` and the casts don't look nice.
26+
pub const BLOCK_LEN_U64: u64 = 512;
8827

8928
/// A caching layer for block devices
9029
///
@@ -93,7 +32,7 @@ pub trait BlockDevice {
9332
pub struct BlockCache<D> {
9433
block_device: D,
9534
block: [Block; 1],
96-
block_idx: Option<BlockIdx>,
35+
block_idx: Option<u64>,
9736
}
9837

9938
impl<D> BlockCache<D>
@@ -104,26 +43,26 @@ where
10443
pub fn new(block_device: D) -> BlockCache<D> {
10544
BlockCache {
10645
block_device,
107-
block: [Block::new()],
46+
block: [[0; BLOCK_LEN]],
10847
block_idx: None,
10948
}
11049
}
11150

11251
/// Read a block, and return a reference to it.
113-
pub fn read(&mut self, block_idx: BlockIdx) -> Result<&Block, D::Error> {
52+
pub fn read(&mut self, block_idx: u64) -> Result<&Block, D::Error> {
11453
if self.block_idx != Some(block_idx) {
11554
self.block_idx = None;
116-
self.block_device.read(&mut self.block, block_idx)?;
55+
self.block_device.read(block_idx, &mut self.block)?;
11756
self.block_idx = Some(block_idx);
11857
}
11958
Ok(&self.block[0])
12059
}
12160

12261
/// Read a block, and return a reference to it.
123-
pub fn read_mut(&mut self, block_idx: BlockIdx) -> Result<&mut Block, D::Error> {
62+
pub fn read_mut(&mut self, block_idx: u64) -> Result<&mut Block, D::Error> {
12463
if self.block_idx != Some(block_idx) {
12564
self.block_idx = None;
126-
self.block_device.read(&mut self.block, block_idx)?;
65+
self.block_device.read(block_idx, &mut self.block)?;
12766
self.block_idx = Some(block_idx);
12867
}
12968
Ok(&mut self.block[0])
@@ -132,13 +71,13 @@ where
13271
/// Write back a block you read with [`Self::read_mut`] and then modified.
13372
pub fn write_back(&mut self) -> Result<(), D::Error> {
13473
self.block_device.write(
135-
&self.block,
13674
self.block_idx.expect("write_back with no read"),
75+
&self.block,
13776
)
13877
}
13978

14079
/// Access a blank sector
141-
pub fn blank_mut(&mut self, block_idx: BlockIdx) -> &mut Block {
80+
pub fn blank_mut(&mut self, block_idx: u64) -> &mut Block {
14281
self.block_idx = Some(block_idx);
14382
for b in self.block[0].iter_mut() {
14483
*b = 0;
@@ -173,7 +112,7 @@ impl BlockIdx {
173112
/// volume. Useful if your underlying block device actually works in
174113
/// bytes, like `open("/dev/mmcblk0")` does on Linux.
175114
pub fn into_bytes(self) -> u64 {
176-
(u64::from(self.0)) * (Block::LEN as u64)
115+
u64::from(self.0) * BLOCK_LEN_U64
177116
}
178117

179118
/// Create an iterator from the current `BlockIdx` through the given
@@ -183,6 +122,12 @@ impl BlockIdx {
183122
}
184123
}
185124

125+
impl From<BlockIdx> for u64 {
126+
fn from(value: BlockIdx) -> Self {
127+
value.0.into()
128+
}
129+
}
130+
186131
impl core::ops::Add<BlockCount> for BlockIdx {
187132
type Output = BlockIdx;
188133
fn add(self, rhs: BlockCount) -> BlockIdx {
@@ -254,8 +199,8 @@ impl BlockCount {
254199
/// assert_eq!(BlockCount::from_bytes(1025), BlockCount(3));
255200
/// ```
256201
pub const fn from_bytes(byte_count: u32) -> BlockCount {
257-
let mut count = byte_count / Block::LEN_U32;
258-
if (count * Block::LEN_U32) != byte_count {
202+
let mut count = byte_count / BLOCK_LEN_U32;
203+
if (count * BLOCK_LEN_U32) != byte_count {
259204
count += 1;
260205
}
261206
BlockCount(count)
@@ -264,7 +209,7 @@ impl BlockCount {
264209
/// Take a number of blocks and increment by the integer number of blocks
265210
/// required to get to the block that holds the byte at the given offset.
266211
pub fn offset_bytes(self, offset: u32) -> Self {
267-
BlockCount(self.0 + (offset / Block::LEN_U32))
212+
BlockCount(self.0 + (offset / BLOCK_LEN_U32))
268213
}
269214
}
270215

0 commit comments

Comments
 (0)