forked from M-Labs/zynq-rs
sd_reader: transition away core-io
This commit is contained in:
parent
79bd73a254
commit
a11d94f959
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue