progress
diff --git a/src/console.rs b/src/console.rs
new file mode 100644
index 0000000..96711e1
--- /dev/null
+++ b/src/console.rs
@@ -0,0 +1,61 @@
+use core::{fmt,mem};
+use core::cell::Cell;
+use core::result::Result;
+use syscalls::{self, allow, yieldk_for};
+
+use alloc::{String, VecDeque};
+
+pub struct Console {
+ queue: VecDeque<String>,
+ outstanding: bool
+}
+
+impl Console {
+ pub fn new() -> Console {
+ Console {
+ queue: VecDeque::new(),
+ outstanding: false
+ }
+ }
+
+ pub fn write(&mut self, string: String) {
+ if !self.outstanding {
+ self.outstanding = true;
+ unsafe {
+ putstr_async(string, Self::cb, self as *const _ as usize);
+ }
+ } else {
+ self.queue.push_back(string);
+ }
+ }
+
+ extern fn cb(_: usize, _: usize, _: usize, ptr: usize) {
+ let console: &mut Console = unsafe {
+ mem::transmute(ptr)
+ };
+ if let Some(next) = console.queue.pop_front() {
+ unsafe {
+ putstr_async(next, Self::cb, ptr);
+ }
+ } else {
+ console.outstanding = false;
+ }
+ }
+}
+
+impl fmt::Write for Console {
+ fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
+ self.write(String::from(string));
+ Ok(())
+ }
+}
+
+unsafe fn putstr_async(string: String, cb: extern fn (usize, usize, usize, usize), ud: usize) -> isize {
+ let ret = allow(0, 1, string.as_bytes());
+ if ret < 0 {
+ return ret;
+ }
+
+ return syscalls::subscribe(0, 1, cb, ud);
+}
+
diff --git a/src/led.rs b/src/led.rs
index 9f589e5..6fcd12d 100644
--- a/src/led.rs
+++ b/src/led.rs
@@ -6,17 +6,25 @@
const TOGGLE: u32 = 3;
pub fn count() -> isize {
- command(8, COUNT, 0)
+ unsafe {
+ command(8, COUNT, 0)
+ }
}
pub fn on(led_num: u32) {
- command(8, ON, led_num as isize);
+ unsafe {
+ command(8, ON, led_num as isize);
+ }
}
pub fn off(led_num: u32) {
- command(8, OFF, led_num as isize);
+ unsafe {
+ command(8, OFF, led_num as isize);
+ }
}
pub fn toggle(led_num: u32) {
- command(8, TOGGLE, led_num as isize);
+ unsafe {
+ command(8, TOGGLE, led_num as isize);
+ }
}
diff --git a/src/lib.rs b/src/lib.rs
index 57c4611..c77d666 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,17 +1,20 @@
-#![feature(asm,const_fn,global_allocator,lang_items,naked_functions)]
+#![feature(asm,alloc,compiler_builtins_lib,const_fn,global_allocator,lang_items,naked_functions)]
#![no_std]
pub mod syscalls;
+pub mod console;
pub mod timer;
pub mod led;
+extern crate alloc;
+extern crate compiler_builtins;
extern crate linked_list_allocator;
mod lang_items;
use core::ptr;
use core::mem::size_of;
-use linked_list_allocator::{Heap,BaseHeap};
+use linked_list_allocator::BaseHeap;
#[global_allocator]
static ALLOCATOR : BaseHeap = BaseHeap;
@@ -29,13 +32,15 @@
}
unsafe {
+ asm!("mov r9, $0" : : "r"(app_heap_break) : : "volatile");
+ syscalls::memop(0, mem_start + 2048);
+
// Setup stack
- let new_stack = mem_start + size_of::<Heap>();
+ let new_stack = mem_start + 1024;
asm!("mov sp, $0" : : "r"(new_stack) : : "volatile");
-
let heap_start = new_stack + size_of::<usize>();
- let heap_size = app_heap_break - heap_start;
+ let heap_size = 1024;
BaseHeap.init(heap_start, heap_size);
// arguments are not used in Tock applications
diff --git a/src/syscalls.rs b/src/syscalls.rs
index a45e43d..65d57cc 100644
--- a/src/syscalls.rs
+++ b/src/syscalls.rs
@@ -11,7 +11,18 @@
}
}
-pub fn subscribe(major: u32, minor: u32, cb: extern fn(usize, usize, usize, usize), ud: usize) -> u32 {
+pub unsafe fn allow(major: u32, minor: u32, slice: &[u8]) -> isize {
+ let res;
+ unsafe {
+ asm!("svc 3" : "={r0}"(res)
+ : "{r0}"(major) "{r1}"(minor) "{r2}"(slice.as_ptr()) "{r3}"(slice.len())
+ : "memory"
+ : "volatile");
+ }
+ res
+}
+
+pub unsafe fn subscribe(major: u32, minor: u32, cb: extern fn(usize, usize, usize, usize), ud: usize) -> isize {
let res;
unsafe {
asm!("svc 1" : "={r0}"(res)
@@ -22,7 +33,7 @@
res
}
-pub fn command(major: u32, minor: u32, arg1: isize) -> isize {
+pub unsafe fn command(major: u32, minor: u32, arg1: isize) -> isize {
let res;
unsafe {
asm!("svc 2" : "={r0}"(res)
@@ -33,3 +44,14 @@
res
}
+pub unsafe fn memop(major: u32, arg1: usize) -> isize {
+ let res;
+ unsafe {
+ asm!("svc 4" : "={r0}"(res)
+ : "{r0}"(major) "{r1}"(arg1)
+ : "memory"
+ : "volatile");
+ }
+ res
+}
+
diff --git a/src/timer.rs b/src/timer.rs
index 538b292..2680694 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -2,20 +2,26 @@
use core::cell::Cell;
use syscalls::{self, command, yieldk_for};
-pub fn subscribe(cb: extern fn(usize, usize, usize, usize), ud: usize) {
+pub unsafe fn subscribe(cb: extern fn(usize, usize, usize, usize), ud: usize) {
syscalls::subscribe(3, 0, cb, ud);
}
pub fn start_oneshot(ms: u32) {
- command(3, 1, ms as isize);
+ unsafe {
+ command(3, 1, ms as isize);
+ }
}
pub fn start_repeating(ms: u32) {
- command(3, 2, ms as isize);
+ unsafe {
+ command(3, 2, ms as isize);
+ }
}
pub fn stop(ms: u32) {
- command(3, 3, ms as isize);
+ unsafe {
+ command(3, 3, ms as isize);
+ }
}
pub fn delay_ms(ms: u32) {
@@ -27,8 +33,10 @@
}
let expired = Cell::new(false);
- subscribe(cb, &expired as *const _ as usize);
- start_oneshot(ms);
- yieldk_for(|| expired.get() );
+ unsafe {
+ subscribe(cb, &expired as *const _ as usize);
+ start_oneshot(ms);
+ yieldk_for(|| expired.get() );
+ }
}