From 83940ae4a6e4748179bb2d123acfc1164fe85124 Mon Sep 17 00:00:00 2001 From: whitequark Date: Thu, 29 Sep 2016 18:54:08 +0000 Subject: [PATCH] Rust: add support for artiq_coreconfig. --- artiq/runtime.rs/src/buffer_logger.rs | 3 +- artiq/runtime.rs/src/config.rs | 63 ++++++++++++++++++++++++ artiq/runtime.rs/src/lib.rs | 4 +- artiq/runtime.rs/src/session/mod.rs | 28 +++++++++-- artiq/runtime.rs/src/session/protocol.rs | 10 ++-- artiq/runtime/main.c | 4 +- 6 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 artiq/runtime.rs/src/config.rs diff --git a/artiq/runtime.rs/src/buffer_logger.rs b/artiq/runtime.rs/src/buffer_logger.rs index e10a5a876..7e7537f8e 100644 --- a/artiq/runtime.rs/src/buffer_logger.rs +++ b/artiq/runtime.rs/src/buffer_logger.rs @@ -1,4 +1,3 @@ -use core::mem; use core::cell::RefCell; use log::{self, Log, LogMetadata, LogRecord, LogLevelFilter}; use log_buffer::LogBuffer; @@ -41,7 +40,7 @@ impl BufferLogger { } impl Log for BufferLogger { - fn enabled(&self, _metadata: &log::LogMetadata) -> bool { + fn enabled(&self, _metadata: &LogMetadata) -> bool { true } diff --git a/artiq/runtime.rs/src/config.rs b/artiq/runtime.rs/src/config.rs new file mode 100644 index 000000000..df3d1868e --- /dev/null +++ b/artiq/runtime.rs/src/config.rs @@ -0,0 +1,63 @@ +use std::cmp; +use std::vec::Vec; +use libc::{c_void, c_char, c_int, c_uint}; + +extern { + fn fs_remove(key: *const c_char); + fn fs_erase(); + fn fs_write(key: *const c_char, buffer: *const c_void, buflen: c_uint) -> c_int; + fn fs_read(key: *const c_char, buffer: *mut c_void, buflen: c_uint, + remain: *mut c_uint) -> c_uint; +} + +macro_rules! c_str { + ($s:ident) => { + { + let mut c = [0; 64 + 1]; + let len = cmp::min($s.len(), c.len() - 1); + c[..len].copy_from_slice($s.as_bytes()); + c + } + } +} + +pub fn read(key: &str, buf: &mut [u8]) -> Result { + let key_c = c_str!(key); + let mut remain: c_uint = 0; + let result = unsafe { + fs_read(key_c.as_ptr() as *const c_char, + buf.as_mut_ptr() as *mut c_void, buf.len() as c_uint, &mut remain) + }; + if remain == 0 { Ok(result as usize) } else { Err(remain as usize) } +} + +pub fn read_to_end(key: &str) -> Vec { + let mut value = Vec::new(); + match read(key, &mut []) { + Ok(0) => (), + Ok(_) => unreachable!(), + Err(size) => { + value.resize(size, 0); + read(key, &mut value).unwrap(); + } + } + value +} + +pub fn write(key: &str, buf: &[u8]) -> Result<(), ()> { + let key_c = c_str!(key); + let result = unsafe { + fs_write(key_c.as_ptr() as *const c_char, + buf.as_ptr() as *mut c_void, buf.len() as c_uint) + }; + if result == 1 { Ok(()) } else { Err(()) } +} + +pub fn remove(key: &str) { + let key_c = c_str!(key); + unsafe { fs_remove(key_c.as_ptr() as *const c_char) } +} + +pub fn erase() { + unsafe { fs_erase() } +} diff --git a/artiq/runtime.rs/src/lib.rs b/artiq/runtime.rs/src/lib.rs index 22feccda2..3c1c6ed32 100644 --- a/artiq/runtime.rs/src/lib.rs +++ b/artiq/runtime.rs/src/lib.rs @@ -1,8 +1,9 @@ #![no_std] -#![feature(const_fn)] +#![feature(libc)] #[macro_use] extern crate std_artiq as std; +extern crate libc; #[macro_use] extern crate log; extern crate log_buffer; @@ -13,6 +14,7 @@ use buffer_logger::BufferLogger; pub mod board; pub mod io; +pub mod config; pub mod buffer_logger; pub mod session; diff --git a/artiq/runtime.rs/src/session/mod.rs b/artiq/runtime.rs/src/session/mod.rs index b4d05bb99..fca04c563 100644 --- a/artiq/runtime.rs/src/session/mod.rs +++ b/artiq/runtime.rs/src/session/mod.rs @@ -1,6 +1,7 @@ use std::prelude::v1::*; use std::str; use std::io::{self, Read, ErrorKind}; +use config; use self::protocol::*; mod protocol; @@ -67,9 +68,8 @@ fn handle_request(stream: &mut ::io::TcpStream, } match try!(read_request(stream)) { - Request::Ident => { - write_reply(stream, Reply::Ident(::board::ident(&mut [0; 64]))) - } + Request::Ident => + write_reply(stream, Reply::Ident(::board::ident(&mut [0; 64]))), Request::Log => { // Logging the packet with the log is inadvisable @@ -84,6 +84,28 @@ fn handle_request(stream: &mut ::io::TcpStream, write_reply(stream, Reply::Log("")) } + Request::FlashRead { ref key } => { + let value = config::read_to_end(key); + write_reply(stream, Reply::FlashRead(&value)) + } + + Request::FlashWrite { ref key, ref value } => { + match config::write(key, value) { + Ok(_) => write_reply(stream, Reply::FlashOk), + Err(_) => write_reply(stream, Reply::FlashError) + } + } + + Request::FlashRemove { ref key } => { + config::remove(key); + write_reply(stream, Reply::FlashOk) + } + + Request::FlashErase => { + config::erase(); + write_reply(stream, Reply::FlashOk) + } + _ => unreachable!() } } diff --git a/artiq/runtime.rs/src/session/protocol.rs b/artiq/runtime.rs/src/session/protocol.rs index deaa2abdd..ba3a64ae2 100644 --- a/artiq/runtime.rs/src/session/protocol.rs +++ b/artiq/runtime.rs/src/session/protocol.rs @@ -51,7 +51,9 @@ fn write_bytes(writer: &mut Write, value: &[u8]) -> io::Result<()> { } fn read_string(reader: &mut Read) -> io::Result { - let bytes = try!(read_bytes(reader)); + let mut bytes = try!(read_bytes(reader)); + let len = bytes.len() - 1; // length without trailing \0 + bytes.resize(len, 0); // FIXME: don't send \0 in the first place String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e)) } @@ -128,8 +130,8 @@ pub enum Request { FlashRead { key: String }, FlashWrite { key: String, value: Vec }, - FlashErase { key: String }, FlashRemove { key: String }, + FlashErase, } impl Request { @@ -162,9 +164,7 @@ impl Request { key: try!(read_string(reader)), value: try!(read_bytes(reader)) }, - 11 => Request::FlashErase { - key: try!(read_string(reader)) - }, + 11 => Request::FlashErase, 12 => Request::FlashRemove { key: try!(read_string(reader)) }, diff --git a/artiq/runtime/main.c b/artiq/runtime/main.c index e1ded8b75..25e826200 100644 --- a/artiq/runtime/main.c +++ b/artiq/runtime/main.c @@ -245,8 +245,8 @@ int main(void) clock_init(); rtiocrg_init(); - // rust_main(); - regular_main(); + rust_main(); + // regular_main(); return 0; }