embedded_sdmmc/
blockdevice.rs1#[derive(Clone)]
14pub struct Block {
15 pub contents: [u8; Block::LEN],
17}
18
19impl Block {
20 pub const LEN: usize = 512;
24
25 pub const LEN_U32: u32 = 512;
27
28 pub fn new() -> Block {
30 Block {
31 contents: [0u8; Self::LEN],
32 }
33 }
34}
35
36impl core::ops::Deref for Block {
37 type Target = [u8; 512];
38 fn deref(&self) -> &[u8; 512] {
39 &self.contents
40 }
41}
42
43impl core::ops::DerefMut for Block {
44 fn deref_mut(&mut self) -> &mut [u8; 512] {
45 &mut self.contents
46 }
47}
48
49impl 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
70impl Default for Block {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76pub trait BlockDevice {
79 type Error: core::fmt::Debug;
81 fn read(&self, blocks: &mut [Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
83 fn write(&self, blocks: &[Block], start_block_idx: BlockIdx) -> Result<(), Self::Error>;
85 fn num_blocks(&self) -> Result<BlockCount, Self::Error>;
87}
88
89#[derive(Debug)]
93pub struct BlockCache<D> {
94 block_device: D,
95 block: [Block; 1],
96 block_idx: Option<BlockIdx>,
97}
98
99impl<D> BlockCache<D>
100where
101 D: BlockDevice,
102{
103 pub fn new(block_device: D) -> BlockCache<D> {
105 BlockCache {
106 block_device,
107 block: [Block::new()],
108 block_idx: None,
109 }
110 }
111
112 pub fn read(&mut self, block_idx: BlockIdx) -> Result<&Block, D::Error> {
114 if self.block_idx != Some(block_idx) {
115 self.block_idx = None;
116 self.block_device.read(&mut self.block, block_idx)?;
117 self.block_idx = Some(block_idx);
118 }
119 Ok(&self.block[0])
120 }
121
122 pub fn read_mut(&mut self, block_idx: BlockIdx) -> Result<&mut Block, D::Error> {
124 if self.block_idx != Some(block_idx) {
125 self.block_idx = None;
126 self.block_device.read(&mut self.block, block_idx)?;
127 self.block_idx = Some(block_idx);
128 }
129 Ok(&mut self.block[0])
130 }
131
132 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 )
138 }
139
140 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)?;
149 Ok(())
150 }
151
152 pub fn blank_mut(&mut self, block_idx: BlockIdx) -> &mut Block {
154 self.block_idx = Some(block_idx);
155 self.block[0].fill(0);
156 &mut self.block[0]
157 }
158
159 pub fn block_device(&mut self) -> &mut D {
161 self.block_idx = None;
163 &mut self.block_device
165 }
166
167 pub fn free(self) -> D {
169 self.block_device
170 }
171}
172
173#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
178#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
179pub struct BlockIdx(pub u32);
180
181impl BlockIdx {
182 pub fn into_bytes(self) -> u64 {
186 (u64::from(self.0)) * (Block::LEN as u64)
187 }
188
189 pub fn range(self, num: BlockCount) -> BlockIter {
192 BlockIter::new(self, self + BlockCount(num.0))
193 }
194}
195
196impl core::ops::Add<BlockCount> for BlockIdx {
197 type Output = BlockIdx;
198 fn add(self, rhs: BlockCount) -> BlockIdx {
199 BlockIdx(self.0 + rhs.0)
200 }
201}
202
203impl core::ops::AddAssign<BlockCount> for BlockIdx {
204 fn add_assign(&mut self, rhs: BlockCount) {
205 self.0 += rhs.0
206 }
207}
208
209impl core::ops::Sub<BlockCount> for BlockIdx {
210 type Output = BlockIdx;
211 fn sub(self, rhs: BlockCount) -> BlockIdx {
212 BlockIdx(self.0 - rhs.0)
213 }
214}
215
216impl core::ops::SubAssign<BlockCount> for BlockIdx {
217 fn sub_assign(&mut self, rhs: BlockCount) {
218 self.0 -= rhs.0
219 }
220}
221
222#[cfg_attr(feature = "defmt-log", derive(defmt::Format))]
226#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
227pub struct BlockCount(pub u32);
228
229impl core::ops::Add<BlockCount> for BlockCount {
230 type Output = BlockCount;
231 fn add(self, rhs: BlockCount) -> BlockCount {
232 BlockCount(self.0 + rhs.0)
233 }
234}
235
236impl core::ops::AddAssign<BlockCount> for BlockCount {
237 fn add_assign(&mut self, rhs: BlockCount) {
238 self.0 += rhs.0
239 }
240}
241
242impl core::ops::Sub<BlockCount> for BlockCount {
243 type Output = BlockCount;
244 fn sub(self, rhs: BlockCount) -> BlockCount {
245 BlockCount(self.0 - rhs.0)
246 }
247}
248
249impl core::ops::SubAssign<BlockCount> for BlockCount {
250 fn sub_assign(&mut self, rhs: BlockCount) {
251 self.0 -= rhs.0
252 }
253}
254
255impl BlockCount {
256 pub const fn from_bytes(byte_count: u32) -> BlockCount {
267 let mut count = byte_count / Block::LEN_U32;
268 if (count * Block::LEN_U32) != byte_count {
269 count += 1;
270 }
271 BlockCount(count)
272 }
273
274 pub fn offset_bytes(self, offset: u32) -> Self {
277 BlockCount(self.0 + (offset / Block::LEN_U32))
278 }
279}
280
281pub struct BlockIter {
283 inclusive_end: BlockIdx,
284 current: BlockIdx,
285}
286
287impl BlockIter {
288 pub const fn new(start: BlockIdx, inclusive_end: BlockIdx) -> BlockIter {
291 BlockIter {
292 inclusive_end,
293 current: start,
294 }
295 }
296}
297
298impl core::iter::Iterator for BlockIter {
299 type Item = BlockIdx;
300 fn next(&mut self) -> Option<Self::Item> {
301 if self.current.0 >= self.inclusive_end.0 {
302 None
303 } else {
304 let this = self.current;
305 self.current += BlockCount(1);
306 Some(this)
307 }
308 }
309}
310
311