forked from M-Labs/zynq-rs
remove core_io dependency from libconfig
This commit is contained in:
parent
fd46cb9c8b
commit
fbf9dff15c
|
@ -1,5 +1,6 @@
|
|||
use alloc::vec::Vec;
|
||||
use core_io::{Error, Read, Seek, SeekFrom};
|
||||
use crate::sd_reader::Error
|
||||
use fatfs::io::{Read, Seek, SeekFrom};
|
||||
use libboard_zynq::devc;
|
||||
use log::debug;
|
||||
|
||||
|
@ -12,8 +13,8 @@ pub enum BootgenLoadingError {
|
|||
DevcError(devc::DevcError),
|
||||
}
|
||||
|
||||
impl From<Error> for BootgenLoadingError {
|
||||
fn from(error: Error) -> Self {
|
||||
impl From<sd_reader::Error> for BootgenLoadingError {
|
||||
fn from(error: sd_reader::Error) -> Self {
|
||||
BootgenLoadingError::IoError(error)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ extern crate alloc;
|
|||
|
||||
use core::fmt;
|
||||
use alloc::{string::FromUtf8Error, string::String, vec::Vec, rc::Rc};
|
||||
use core_io::{self as io, BufRead, BufReader, Read, Write, Seek, SeekFrom};
|
||||
use fatfs::io::{Read, Write, Seek, SeekFrom}
|
||||
use libboard_zynq::sdio;
|
||||
|
||||
pub mod sd_reader;
|
||||
|
@ -13,7 +13,7 @@ pub mod bootgen;
|
|||
#[derive(Debug)]
|
||||
pub enum Error<'a> {
|
||||
SdError(sdio::sd_card::CardInitializationError),
|
||||
IoError(io::Error),
|
||||
IoError(sd_reader::Error),
|
||||
Utf8Error(FromUtf8Error),
|
||||
KeyNotFoundError(&'a str),
|
||||
NoConfig,
|
||||
|
@ -39,8 +39,8 @@ impl<'a> From<sdio::sd_card::CardInitializationError> for Error<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> From<io::Error> for Error<'a> {
|
||||
fn from(error: io::Error) -> Self {
|
||||
impl<'a> From<sd_reader::Error> for Error<'a> {
|
||||
fn from(error: sd_reader::Error) -> Self {
|
||||
Error::IoError(error)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use core_io::{BufRead, Error, ErrorKind, Read, Result as IoResult, Seek, SeekFrom, Write};
|
||||
use fatfs;
|
||||
use fatfs::io::{Read, Seek, SeekFrom, Write}
|
||||
use libboard_zynq::sdio::{sd_card::SdCard, CmdTransferError};
|
||||
use log::debug;
|
||||
use alloc::vec::Vec;
|
||||
use core::fmt;
|
||||
|
||||
const MBR_SIGNATURE: [u8; 2] = [0x55, 0xAA];
|
||||
const PARTID_FAT12: u8 = 0x01;
|
||||
|
@ -12,13 +13,46 @@ const PARTID_FAT32: u8 = 0x0B;
|
|||
const PARTID_FAT32_LBA: u8 = 0x0C;
|
||||
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;
|
||||
|
||||
/// SdReader struct implementing `Read + BufRead + Write + Seek` traits for `core_io`.
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
message: String
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn new(message: &str) -> Self {
|
||||
Self { message: String::new(message) }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl IoError for Error {
|
||||
fn is_interrupted(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn new_unexpected_eof_error() -> Self {
|
||||
Error::new("Unexpected end of file error")
|
||||
}
|
||||
|
||||
fn new_write_zero_error() -> Self {
|
||||
Error::new("Write zero error")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CmdTransferError> for Error {
|
||||
fn from(_: CmdTransferError) -> Self {
|
||||
Error::new("Command transfer error")
|
||||
}
|
||||
}
|
||||
|
||||
/// SdReader struct implementing `Read + Write + Seek` traits for `core_io`.
|
||||
/// Used as an adaptor for fatfs crate, but could be used directly for raw data access.
|
||||
///
|
||||
/// Implementation: all read/writes would be split into unaligned and block-aligned parts,
|
||||
|
@ -43,6 +77,10 @@ pub struct SdReader {
|
|||
offset: u32,
|
||||
}
|
||||
|
||||
impl IoBase for SdReader {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[allow(unused)]
|
||||
// Partition entry enum, normally we would use entry1.
|
||||
|
@ -72,7 +110,7 @@ impl SdReader {
|
|||
|
||||
/// Internal read function for unaligned read.
|
||||
/// 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> {
|
||||
if buf.len() == 0 {
|
||||
return Ok(0);
|
||||
}
|
||||
|
@ -86,7 +124,7 @@ impl SdReader {
|
|||
|
||||
/// Internal write function for unaligned write.
|
||||
/// 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> {
|
||||
if buf.len() == 0 {
|
||||
return Ok(0);
|
||||
}
|
||||
|
@ -137,7 +175,7 @@ impl SdReader {
|
|||
}
|
||||
|
||||
/// 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.offset = offset;
|
||||
self.seek(SeekFrom::Start(0))
|
||||
}
|
||||
|
@ -145,14 +183,13 @@ impl SdReader {
|
|||
/// 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,
|
||||
/// 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>> {
|
||||
let mut buffer: [u8; 4] = [0; 4];
|
||||
self.seek(SeekFrom::Start(0x1FE))?;
|
||||
self.read_exact(&mut buffer[..2])?;
|
||||
// check MBR signature
|
||||
if buffer[..2] != MBR_SIGNATURE {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"Incorrect signature for MBR sector.",
|
||||
));
|
||||
}
|
||||
|
@ -165,7 +202,6 @@ impl SdReader {
|
|||
PARTID_FAT16_LBA | PARTID_FAT32 | PARTID_FAT32_LBA => {}
|
||||
_ => {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
"No FAT partition found for the specified entry.",
|
||||
));
|
||||
}
|
||||
|
@ -186,7 +222,7 @@ impl SdReader {
|
|||
}
|
||||
|
||||
impl Read for SdReader {
|
||||
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
let total_length = buf.len();
|
||||
let (a, b, c) = self.block_align_mut(buf);
|
||||
self.read_unaligned(a)?;
|
||||
|
@ -211,30 +247,8 @@ impl Read for SdReader {
|
|||
}
|
||||
}
|
||||
|
||||
impl BufRead for SdReader {
|
||||
fn fill_buf(&mut self) -> IoResult<&[u8]> {
|
||||
if self.index == BLOCK_SIZE {
|
||||
// flush the buffer if it is dirty before overwriting it with new data
|
||||
if self.dirty {
|
||||
self.flush()?;
|
||||
}
|
||||
// reload buffer
|
||||
self.sd
|
||||
.read_block(self.byte_addr / (BLOCK_SIZE as u32), 1, &mut self.buffer)
|
||||
.map_err(cmd_error_to_io_error)?;
|
||||
self.index = (self.byte_addr as usize) % BLOCK_SIZE;
|
||||
}
|
||||
Ok(&self.buffer[self.index..])
|
||||
}
|
||||
|
||||
fn consume(&mut self, amt: usize) {
|
||||
self.index += amt;
|
||||
self.byte_addr += amt as u32;
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for SdReader {
|
||||
fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
|
||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
|
||||
let (a, b, c) = self.block_align(buf);
|
||||
self.write_unaligned(a)?;
|
||||
if b.len() > 0 {
|
||||
|
@ -255,12 +269,11 @@ impl Write for SdReader {
|
|||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> IoResult<()> {
|
||||
fn flush(&mut self) -> Result<(), Error> {
|
||||
if self.dirty {
|
||||
let block_addr = (self.byte_addr - self.index as u32) / (BLOCK_SIZE as u32);
|
||||
self.sd
|
||||
.write_block(block_addr, 1, &self.buffer)
|
||||
.map_err(cmd_error_to_io_error)?;
|
||||
.write_block(block_addr, 1, &self.buffer)?;
|
||||
self.dirty = false;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -268,14 +281,14 @@ impl Write for SdReader {
|
|||
}
|
||||
|
||||
impl Seek for SdReader {
|
||||
fn seek(&mut self, pos: SeekFrom) -> IoResult<u64> {
|
||||
fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error> {
|
||||
let raw_target = match pos {
|
||||
SeekFrom::Start(x) => self.offset as i64 + x as i64,
|
||||
SeekFrom::Current(x) => self.byte_addr as i64 + x,
|
||||
SeekFrom::End(_) => panic!("SD card does not support seek from end"),
|
||||
};
|
||||
if raw_target < self.offset as i64 || raw_target > core::u32::MAX as i64 {
|
||||
return Err(Error::new(ErrorKind::InvalidInput, "Invalid address"));
|
||||
return Err(Error::new("Invalid address"));
|
||||
}
|
||||
let target_byte_addr = raw_target as u32;
|
||||
let address_same_block =
|
||||
|
|
Loading…
Reference in New Issue