Rust: add support for artiq_coreconfig.

This commit is contained in:
whitequark 2016-09-29 18:54:08 +00:00
parent 1e392cca64
commit 83940ae4a6
6 changed files with 99 additions and 13 deletions

View File

@ -1,4 +1,3 @@
use core::mem;
use core::cell::RefCell; use core::cell::RefCell;
use log::{self, Log, LogMetadata, LogRecord, LogLevelFilter}; use log::{self, Log, LogMetadata, LogRecord, LogLevelFilter};
use log_buffer::LogBuffer; use log_buffer::LogBuffer;
@ -41,7 +40,7 @@ impl BufferLogger {
} }
impl Log for BufferLogger { impl Log for BufferLogger {
fn enabled(&self, _metadata: &log::LogMetadata) -> bool { fn enabled(&self, _metadata: &LogMetadata) -> bool {
true true
} }

View File

@ -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<usize, usize> {
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<u8> {
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() }
}

View File

@ -1,8 +1,9 @@
#![no_std] #![no_std]
#![feature(const_fn)] #![feature(libc)]
#[macro_use] #[macro_use]
extern crate std_artiq as std; extern crate std_artiq as std;
extern crate libc;
#[macro_use] #[macro_use]
extern crate log; extern crate log;
extern crate log_buffer; extern crate log_buffer;
@ -13,6 +14,7 @@ use buffer_logger::BufferLogger;
pub mod board; pub mod board;
pub mod io; pub mod io;
pub mod config;
pub mod buffer_logger; pub mod buffer_logger;
pub mod session; pub mod session;

View File

@ -1,6 +1,7 @@
use std::prelude::v1::*; use std::prelude::v1::*;
use std::str; use std::str;
use std::io::{self, Read, ErrorKind}; use std::io::{self, Read, ErrorKind};
use config;
use self::protocol::*; use self::protocol::*;
mod protocol; mod protocol;
@ -67,9 +68,8 @@ fn handle_request(stream: &mut ::io::TcpStream,
} }
match try!(read_request(stream)) { match try!(read_request(stream)) {
Request::Ident => { Request::Ident =>
write_reply(stream, Reply::Ident(::board::ident(&mut [0; 64]))) write_reply(stream, Reply::Ident(::board::ident(&mut [0; 64]))),
}
Request::Log => { Request::Log => {
// Logging the packet with the log is inadvisable // Logging the packet with the log is inadvisable
@ -84,6 +84,28 @@ fn handle_request(stream: &mut ::io::TcpStream,
write_reply(stream, Reply::Log("")) 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!() _ => unreachable!()
} }
} }

View File

@ -51,7 +51,9 @@ fn write_bytes(writer: &mut Write, value: &[u8]) -> io::Result<()> {
} }
fn read_string(reader: &mut Read) -> io::Result<String> { fn read_string(reader: &mut Read) -> io::Result<String> {
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)) String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
} }
@ -128,8 +130,8 @@ pub enum Request {
FlashRead { key: String }, FlashRead { key: String },
FlashWrite { key: String, value: Vec<u8> }, FlashWrite { key: String, value: Vec<u8> },
FlashErase { key: String },
FlashRemove { key: String }, FlashRemove { key: String },
FlashErase,
} }
impl Request { impl Request {
@ -162,9 +164,7 @@ impl Request {
key: try!(read_string(reader)), key: try!(read_string(reader)),
value: try!(read_bytes(reader)) value: try!(read_bytes(reader))
}, },
11 => Request::FlashErase { 11 => Request::FlashErase,
key: try!(read_string(reader))
},
12 => Request::FlashRemove { 12 => Request::FlashRemove {
key: try!(read_string(reader)) key: try!(read_string(reader))
}, },

View File

@ -245,8 +245,8 @@ int main(void)
clock_init(); clock_init();
rtiocrg_init(); rtiocrg_init();
// rust_main(); rust_main();
regular_main(); // regular_main();
return 0; return 0;
} }