#![feature(const_fn)] #![feature(generators)] #![feature(never_type)] #![feature(nll)] #![feature(prelude_import)] #![feature(proc_macro_gen)] #[macro_use] extern crate drone_core; #[macro_use] extern crate drone_fatfs; extern crate futures; #[macro_use] extern crate lazy_static; #[prelude_import] #[allow(unused_imports)] use drone_core::prelude::*; use drone_core::drv::Driver; use drone_core::ffi::{CStr, CString}; use drone_core::io::{Read, Write}; use drone_core::stack_adapter::{Adapter, Context, In, Out, Stack}; use drone_core::sv::Supervisor; use drone_core::thr; use drone_fatfs::rt::{ Rt, RtcRt, CTRL_SYNC, CTRL_TRIM, DRESULT, DWORD, FF_MIN_SS, GET_BLOCK_SIZE, GET_SECTOR_COUNT, GET_SECTOR_SIZE, WORD, }; use drone_fatfs::{ Cmd, CmdRes, FatSess, FatSessError, FatSessRes, FatTime, Req, ReqRes, }; use futures::prelude::*; use std::sync::Mutex; use std::{slice, str}; const SECTOR_SIZE: usize = FF_MIN_SS as usize; const SECTOR_COUNT: usize = 256; lazy_static! { static ref DRIVE: Mutex<[u8; SECTOR_SIZE * SECTOR_COUNT]> = Mutex::new([0; SECTOR_SIZE * SECTOR_COUNT]); } fatfs! { RTC => MemRt; 0 => MemRt; } thr! { struct Thr; struct ThrLocal; extern struct Sv; extern static THREADS; } struct MemRt; impl Rt for MemRt { fn disk_initialize() -> u8 { 0 } fn disk_status() -> u8 { 0 } fn disk_ioctl(cmd: u8, buff: *mut u8) -> DRESULT { match cmd as u32 { CTRL_SYNC => DRESULT::RES_OK, GET_SECTOR_COUNT => { unsafe { *(buff as *mut DWORD) = SECTOR_COUNT as DWORD }; DRESULT::RES_OK } GET_SECTOR_SIZE => { unsafe { *(buff as *mut WORD) = SECTOR_SIZE as WORD }; DRESULT::RES_OK } GET_BLOCK_SIZE => { unsafe { *(buff as *mut DWORD) = 8 }; DRESULT::RES_OK } CTRL_TRIM => DRESULT::RES_OK, _ => DRESULT::RES_PARERR, } } fn disk_read(buff: *mut u8, sector: u32, count: u32) -> DRESULT { let drive = DRIVE.lock().unwrap(); unsafe { slice::from_raw_parts_mut(buff, count as usize * SECTOR_SIZE) .copy_from_slice( &drive[sector as usize * SECTOR_SIZE ..(sector as usize + count as usize) * SECTOR_SIZE], ); } DRESULT::RES_OK } fn disk_write(buff: *const u8, sector: u32, count: u32) -> DRESULT { let mut drive = DRIVE.lock().unwrap(); unsafe { drive[sector as usize * SECTOR_SIZE ..(sector as usize + count as usize) * SECTOR_SIZE] .copy_from_slice(slice::from_raw_parts( buff, count as usize * SECTOR_SIZE, )); } DRESULT::RES_OK } } impl RtcRt for MemRt { fn get_current_time() -> FatTime { FatTime::new() } } struct WakeNop; unsafe impl task::UnsafeWake for WakeNop { unsafe fn clone_raw(&self) -> task::Waker { task::Waker::new(self) } unsafe fn drop_raw(&self) {} unsafe fn wake(&self) {} } static mut THREADS: [Thr; 1] = [Thr::new(0)]; struct Sv; impl Supervisor for Sv { fn first() -> *const Self { ::std::ptr::null() } } #[derive(Resource, Driver)] struct MemSess(MemSessRes); #[derive(Resource)] struct MemSessRes(Runner); struct Runner; impl FatSessRes for MemSess { type Stack = Runner; type Context = Runner; } impl Adapter for MemSess { type Stack = Runner; type Context = Runner; type Cmd = Cmd; type CmdRes = CmdRes; type Req = Req; type ReqRes = ReqRes; type Error = !; const STACK_SIZE: usize = 0x800; fn stack(&mut self) -> &mut Self::Stack { &mut (self.0).0 } fn run_cmd(_cmd: Self::Cmd, _context: Self::Context) -> Self::CmdRes { unimplemented!() } fn run_req<'a>( &'a mut self, _req: Self::Req, ) -> Box + 'a> { unimplemented!() } } impl Context for Runner { unsafe fn new() -> Self { unimplemented!() } fn req(&self, _req: Req) -> ReqRes { unimplemented!() } } unsafe impl Stack for Runner { fn resume(&mut self, input: In) -> Out { Out::CmdRes(unsafe { input.into_cmd() }.run()) } } #[test] fn test() { unsafe { thr::init::() }; let mut sess = FatSess::::new(MemSessRes(Runner)); let drive_name = CString::default(); let file_name = CStr::from_bytes_with_nul(b"hello.txt\0").unwrap(); let text = "Hello, World!"; let mut buf = [0; 13]; let mut fut = async(static move || { await!(sess.format(&drive_name))?; let fs = await!(sess.mount(drive_name))?; let mut file = await!(sess.create(&file_name))?; let mut file_sess = file.sess(&mut sess); let bytes_written = await!(file_sess.write(text.as_bytes()))?; assert_eq!(bytes_written, 13); await!(sess.close(file))?; let mut file = await!(sess.open(&file_name))?; let mut file_sess = file.sess(&mut sess); let bytes_read = await!(file_sess.read(&mut buf))?; assert_eq!(bytes_read, 13); assert_eq!(str::from_utf8(&buf), Ok(text)); await!(sess.umount(fs))?; Ok::<(), FatSessError>(()) }); let waker = unsafe { task::Waker::new(&WakeNop) }; let mut map = task::LocalMap::new(); let mut cx = task::Context::without_spawn(&mut map, &waker); while let Async::Pending = fut.poll(&mut cx).unwrap() {} }