1
0
Fork 0

sd_reader: transition away core-io

This commit is contained in:
Simon Renblad 2024-07-29 16:33:03 +08:00
parent 79bd73a254
commit a11d94f959
1 changed files with 43 additions and 37 deletions

View File

@ -1,8 +1,8 @@
use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write}; use fatfs::{self as fatfs, Read, Seek, SeekFrom, Write};
use fatfs;
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError}; use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
use log::debug; use log::debug;
use alloc::vec::Vec; use alloc::vec::Vec;
use alloc::string::String;
const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA]; const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA];
const PARTID_FAT12: u8 = 0x01; const PARTID_FAT12: u8 = 0x01;
@ -12,9 +12,6 @@ const PARTID_FAT32: u8 = 0x0B;
const PARTID_FAT32_LBA: u8 = 0x0C; const PARTID_FAT32_LBA: u8 = 0x0C;
const PARTID_FAT16_LBA: u8 = 0x0E; const PARTID_FAT16_LBA: u8 = 0x0E;
fn cmd_error_to_io_error(_: CmdTransferError) -> Error {
Error::new(ErrorKind::Other, "Command transfer error")
}
const BLOCK_SIZE: usize = 512; const BLOCK_SIZE: usize = 512;
@ -53,6 +50,10 @@ pub enum PartitionEntry {
Entry4 = 0x1EE, Entry4 = 0x1EE,
} }
impl IoBase for SdReader {
type Error = fatfs::error::Error<String>;
}
impl SdReader { impl SdReader {
/// Create SdReader from SdCard /// Create SdReader from SdCard
pub fn new(sd: SdCard) -> SdReader { pub fn new(sd: SdCard) -> SdReader {
@ -72,7 +73,7 @@ impl SdReader {
/// Internal read function for unaligned read. /// Internal read function for unaligned read.
/// The read must not cross block boundary. /// The read must not cross block boundary.
fn read_unaligned(&mut self, buf: &mut [u8]) -> IoResult<usize> { fn read_unaligned(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
if buf.len() == 0 { if buf.len() == 0 {
return Ok(0); return Ok(0);
} }
@ -86,7 +87,7 @@ impl SdReader {
/// Internal write function for unaligned write. /// Internal write function for unaligned write.
/// The write must not cross block boundary. /// The write must not cross block boundary.
fn write_unaligned(&mut self, buf: &[u8]) -> IoResult<usize> { fn write_unaligned(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
if buf.len() == 0 { if buf.len() == 0 {
return Ok(0); return Ok(0);
} }
@ -137,7 +138,7 @@ impl SdReader {
} }
/// Set the base offset of the SD card, to transform from physical address to logical address. /// Set the base offset of the SD card, to transform from physical address to logical address.
fn set_base_offset(&mut self, offset: u32) -> IoResult<u64> { fn set_base_offset(&mut self, offset: u32) -> Result<u64, Self::Error> {
self.offset = offset; self.offset = offset;
self.seek(SeekFrom::Start(0)) self.seek(SeekFrom::Start(0))
} }
@ -145,13 +146,13 @@ impl SdReader {
/// Mount fatfs from partition entry, and return the fatfs object if success. /// Mount fatfs from partition entry, and return the fatfs object if success.
/// This takes the ownership of self, so currently there is no way to recover from an error, /// This takes the ownership of self, so currently there is no way to recover from an error,
/// except creating a new SD card instance. /// except creating a new SD card instance.
pub fn mount_fatfs(mut self, entry: PartitionEntry) -> IoResult<fatfs::FileSystem<Self>> { pub fn mount_fatfs(mut self, entry: PartitionEntry) -> Result<fatfs::FileSystem<Self>, Self::Error> {
let mut buffer: [u8; 4] = [0; 4]; let mut buffer: [u8; 4] = [0; 4];
self.seek(SeekFrom::Start(0x1FE))?; self.seek(SeekFrom::Start(0x1FE))?;
self.read_exact(&mut buffer[..2])?; self.read_exact(&mut buffer[..2])?;
// check MBR signature // check MBR signature
if buffer[..2] != MBR_SIGNATURE { if buffer[..2] != MBR_SIGNATURE {
return Err(Error::new( return Err(Self::Error::new(
ErrorKind::InvalidData, ErrorKind::InvalidData,
"Incorrect signature for MBR sector.", "Incorrect signature for MBR sector.",
)); ));
@ -164,7 +165,7 @@ impl SdReader {
PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 | PARTID_FAT12 | PARTID_FAT16_LESS32M | PARTID_FAT16 |
PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {} PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {}
_ => { _ => {
return Err(Error::new( return Err(Self::Error::new(
ErrorKind::InvalidData, ErrorKind::InvalidData,
"No FAT partition found for the specified entry.", "No FAT partition found for the specified entry.",
)); ));
@ -183,10 +184,15 @@ impl SdReader {
// setup fatfs // setup fatfs
fatfs::FileSystem::new(self, fatfs::FsOptions::new()) fatfs::FileSystem::new(self, fatfs::FsOptions::new())
} }
fn cmd_error_to_io_error(_: CmdTransferError) -> Self::Error {
Self::Error::Other("Command transfer error")
}
} }
impl Read for SdReader { impl Read for SdReader {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
let total_length = buf.len(); let total_length = buf.len();
let (a, b, c) = self.block_align_mut(buf); let (a, b, c) = self.block_align_mut(buf);
self.read_unaligned(a)?; self.read_unaligned(a)?;
@ -211,30 +217,30 @@ impl Read for SdReader {
} }
} }
impl BufRead for SdReader { // impl BufRead for SdReader {
fn fill_buf(&mut self) -> IoResult<&[u8]> { // fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
if self.index == BLOCK_SIZE { // if self.index == BLOCK_SIZE {
// flush the buffer if it is dirty before overwriting it with new data // // flush the buffer if it is dirty before overwriting it with new data
if self.dirty { // if self.dirty {
self.flush()?; // self.flush()?;
} // }
// reload buffer // // reload buffer
self.sd // self.sd
.read_block(self.byte_addr / (BLOCK_SIZE as u32), 1, &mut self.buffer) // .read_block(self.byte_addr / (BLOCK_SIZE as u32), 1, &mut self.buffer)
.map_err(cmd_error_to_io_error)?; // .map_err(cmd_error_to_io_error)?;
self.index = (self.byte_addr as usize) % BLOCK_SIZE; // self.index = (self.byte_addr as usize) % BLOCK_SIZE;
} // }
Ok(&self.buffer[self.index..]) // Ok(&self.buffer[self.index..])
} // }
//
fn consume(&mut self, amt: usize) { // fn consume(&mut self, amt: usize) {
self.index += amt; // self.index += amt;
self.byte_addr += amt as u32; // self.byte_addr += amt as u32;
} // }
} // }
impl Write for SdReader { impl Write for SdReader {
fn write(&mut self, buf: &[u8]) -> IoResult<usize> { fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
let (a, b, c) = self.block_align(buf); let (a, b, c) = self.block_align(buf);
self.write_unaligned(a)?; self.write_unaligned(a)?;
if b.len() > 0 { if b.len() > 0 {
@ -255,12 +261,12 @@ impl Write for SdReader {
Ok(buf.len()) Ok(buf.len())
} }
fn flush(&mut self) -> IoResult<()> { fn flush(&mut self) -> Result<(), Self::Error> {
if self.dirty { if self.dirty {
let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32); let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32);
self.sd self.sd
.write_block(block_addr, 1, &self.buffer) .write_block(block_addr, 1, &self.buffer)
.map_err(cmd_error_to_io_error)?; .map_err(self.cmd_error_to_io_error)?;
self.dirty = false; self.dirty = false;
} }
Ok(()) Ok(())
@ -268,7 +274,7 @@ impl Write for SdReader {
} }
impl Seek for SdReader { impl Seek for SdReader {
fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> { fn seek(&mut self, pos: SeekFrom) -> Result<u64, Self::Error> {
let raw_target = match pos { let raw_target = match pos {
SeekFrom::Start(x) => self.offset as i64 + x as i64, SeekFrom::Start(x) => self.offset as i64 + x as i64,
SeekFrom::Current(x) => self.byte_addr as i64 + x, SeekFrom::Current(x) => self.byte_addr as i64 + x,