Merge pull request #235 from alistair23/alistair/println
console: Add support for println! and print!
diff --git a/examples-features/alloc_error.rs b/examples-features/alloc_error.rs
index 40ae939..8b20f84 100644
--- a/examples-features/alloc_error.rs
+++ b/examples-features/alloc_error.rs
@@ -7,7 +7,7 @@
use alloc::vec::Vec;
use core::alloc::Layout;
-use core::fmt::Write;
+use libtock::println;
use libtock::result::TockResult;
use libtock::syscalls;
@@ -22,8 +22,8 @@
#[alloc_error_handler]
unsafe fn alloc_error_handler(_: Layout) -> ! {
if let Ok(drivers) = libtock::retrieve_drivers() {
- let mut console = drivers.console.create_console();
- let _ = writeln!(console, "alloc_error_handler called");
+ drivers.console.create_console();
+ println!("alloc_error_handler called");
}
loop {
syscalls::raw::yieldk();
diff --git a/examples-features/libtock_test.rs b/examples-features/libtock_test.rs
index ac1e541..ac2cb48 100644
--- a/examples-features/libtock_test.rs
+++ b/examples-features/libtock_test.rs
@@ -12,11 +12,11 @@
use core::pin::Pin;
use core::task::Context;
use core::task::Poll;
-use libtock::console::Console;
use libtock::console::ConsoleDriver;
use libtock::gpio::GpioDriverFactory;
use libtock::gpio::GpioState;
use libtock::gpio::ResistorMode;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::DriverContext;
use libtock::timer::Duration;
@@ -59,16 +59,13 @@
}
struct LibtockTest {
- console: Console,
success: bool,
}
impl LibtockTest {
fn initialize(console: ConsoleDriver) -> Self {
- Self {
- console: console.create_console(),
- success: true,
- }
+ console.create_console();
+ Self { success: true }
}
fn console(&mut self) -> TockResult<()> {
@@ -170,12 +167,12 @@
}
fn log_success(&mut self, message: &str) -> TockResult<()> {
- writeln!(&mut self.console, "[ OK ] {}", message)?;
+ println!("[ OK ] {}", message);
Ok(())
}
fn log_failure(&mut self, message: &str) -> TockResult<()> {
- writeln!(&mut self.console, "[ FAILURE ] {}", message)?;
+ println!("[ FAILURE ] {}", message);
self.success = false;
Ok(())
}
diff --git a/examples-features/panic.rs b/examples-features/panic.rs
index 5a9123a..8af98bf 100644
--- a/examples-features/panic.rs
+++ b/examples-features/panic.rs
@@ -2,8 +2,8 @@
#![no_std]
-use core::fmt::Write;
use core::panic::PanicInfo;
+use libtock::println;
use libtock::result::TockResult;
use libtock::syscalls;
@@ -15,8 +15,8 @@
#[panic_handler]
unsafe fn panic_handler(_info: &PanicInfo) -> ! {
if let Ok(drivers) = libtock::retrieve_drivers() {
- let mut console = drivers.console.create_console();
- let _ = writeln!(console, "panic_handler called");
+ drivers.console.create_console();
+ println!("panic_handler called");
}
loop {
syscalls::raw::yieldk();
diff --git a/examples/adc.rs b/examples/adc.rs
index 711176e..28b1534 100644
--- a/examples/adc.rs
+++ b/examples/adc.rs
@@ -1,6 +1,6 @@
#![no_std]
-use core::fmt::Write;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;
@@ -11,10 +11,10 @@
let adc_driver = drivers.adc.init_driver()?;
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
let mut callback = |channel, value| {
- writeln!(console, "channel: {}, value: {}", channel, value).unwrap();
+ println!("channel: {}, value: {}", channel, value);
};
let _subscription = adc_driver.subscribe(&mut callback)?;
diff --git a/examples/adc_buffer.rs b/examples/adc_buffer.rs
index 86f94b2..1337cf4 100644
--- a/examples/adc_buffer.rs
+++ b/examples/adc_buffer.rs
@@ -1,7 +1,7 @@
#![no_std]
-use core::fmt::Write;
use libtock::adc::AdcBuffer;
+use libtock::println;
use libtock::result::TockResult;
use libtock::syscalls;
@@ -11,7 +11,7 @@
let mut drivers = libtock::retrieve_drivers()?;
let adc_driver = drivers.adc.init_driver()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
let mut adc_buffer = AdcBuffer::default();
let mut temp_buffer = [0; libtock::adc::BUFFER_SIZE];
@@ -20,7 +20,7 @@
let mut callback = |_, _| {
adc_buffer.read_bytes(&mut temp_buffer[..]);
- writeln!(console, "First sample in buffer: {}", temp_buffer[0]).unwrap();
+ println!("First sample in buffer: {}", temp_buffer[0]);
};
let _subscription = adc_driver.subscribe(&mut callback)?;
diff --git a/examples/button_read.rs b/examples/button_read.rs
index c3f9aa6..e888185 100644
--- a/examples/button_read.rs
+++ b/examples/button_read.rs
@@ -1,6 +1,6 @@
#![no_std]
-use core::fmt::Write;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;
@@ -11,16 +11,11 @@
let buttons_driver = drivers.buttons.init_driver()?;
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
loop {
for button in buttons_driver.buttons() {
- writeln!(
- console,
- "button {}: {:?}",
- button.button_num(),
- button.read()?
- )?;
+ println!("button {}: {:?}", button.button_num(), button.read()?);
}
timer_driver.sleep(Duration::from_ms(500)).await?;
}
diff --git a/examples/button_subscribe.rs b/examples/button_subscribe.rs
index d06a0e9..8b2f17e 100644
--- a/examples/button_subscribe.rs
+++ b/examples/button_subscribe.rs
@@ -1,8 +1,8 @@
#![no_std]
use core::cell::Cell;
-use core::fmt::Write;
use libtock::buttons::ButtonState;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;
@@ -13,7 +13,7 @@
let buttons_driver = drivers.buttons.init_driver()?;
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
let pressed_count = Cell::new(0usize);
let released_count = Cell::new(0usize);
@@ -30,12 +30,11 @@
}
loop {
- writeln!(
- console,
+ println!(
"pressed: {}, released: {}",
pressed_count.get(),
released_count.get()
- )?;
+ );
timer_driver.sleep(Duration::from_ms(500)).await?;
}
}
diff --git a/examples/ctap.rs b/examples/ctap.rs
index 42917d1..d545d0c 100644
--- a/examples/ctap.rs
+++ b/examples/ctap.rs
@@ -1,38 +1,39 @@
#![no_std]
/// This is a very basic CTAP example
/// This example only calls the CTAP driver calls, it does not implement CTAP
-use core::fmt::Write;
use libtock::ctap::{CtapRecvBuffer, CtapSendBuffer};
use libtock::result::TockResult;
use libtock::syscalls;
+use libtock::{print, println};
#[libtock::main]
async fn main() -> TockResult<()> {
let mut drivers = libtock::retrieve_drivers()?;
- let mut console = drivers.console.create_console();
- writeln!(console, "Starting CTAP example")?;
+ drivers.console.create_console();
+ println!("Starting CTAP example");
let ctap_driver = drivers.ctap.init_driver()?;
- writeln!(console, "Creating recv buffer")?;
+ println!("Creating recv buffer");
let mut recv_buffer = CtapRecvBuffer::default();
let recv_buffer = ctap_driver.init_recv_buffer(&mut recv_buffer)?;
- writeln!(console, " done")?;
+ println!(" done");
- writeln!(console, "Creating send buffer")?;
+ println!("Creating send buffer");
let mut send_buffer = CtapSendBuffer::default();
let _send_buffer = ctap_driver.init_send_buffer(&mut send_buffer)?;
- writeln!(console, " done")?;
+ println!(" done");
let mut temp_buffer = [0; libtock::ctap::RECV_BUFFER_SIZE];
- writeln!(console, "Setting callback and running")?;
+ println!("Setting callback and running");
let mut callback = |_, _| {
- writeln!(console, "CTAP Complete, printing data").unwrap();
+ println!("CTAP Complete, printing data");
recv_buffer.read_bytes(&mut temp_buffer[..]);
for buf in temp_buffer.iter().take(libtock::ctap::RECV_BUFFER_SIZE) {
- write!(console, "{:x}", *buf).unwrap();
+ print!("{:x}", *buf);
}
+ println!();
let _ret = ctap_driver.allow_receive();
};
diff --git a/examples/gpio_read.rs b/examples/gpio_read.rs
index a29662e..8fc216b 100644
--- a/examples/gpio_read.rs
+++ b/examples/gpio_read.rs
@@ -1,7 +1,7 @@
#![no_std]
-use core::fmt::Write;
use libtock::gpio::ResistorMode;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;
@@ -13,12 +13,12 @@
let mut gpio_driver = drivers.gpio.init_driver()?;
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
let mut gpio = gpio_driver.gpios().next().unwrap();
let gpio_in = gpio.enable_input(ResistorMode::PullDown)?;
loop {
- writeln!(console, "{:?}", gpio_in.read()?)?;
+ println!("{:?}", gpio_in.read()?);
timer_driver.sleep(Duration::from_ms(500)).await?;
}
}
diff --git a/examples/hello_world.rs b/examples/hello_world.rs
index 052cf69..49ada78 100644
--- a/examples/hello_world.rs
+++ b/examples/hello_world.rs
@@ -4,16 +4,16 @@
#![no_std]
-use core::fmt::Write;
+use libtock::println;
use libtock::result::TockResult;
#[libtock::main]
async fn main() -> TockResult<()> {
let drivers = libtock::retrieve_drivers()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
- writeln!(console, "Hello Tock World")?;
+ println!("Hello Tock World");
Ok(())
}
diff --git a/examples/hmac.rs b/examples/hmac.rs
index b6f2881..fe956bb 100644
--- a/examples/hmac.rs
+++ b/examples/hmac.rs
@@ -1,23 +1,23 @@
#![no_std]
-use core::fmt::Write;
use libtock::hmac::{HmacDataBuffer, HmacDestBuffer, HmacKeyBuffer};
+use libtock::println;
use libtock::result::TockResult;
use libtock::syscalls;
#[libtock::main]
async fn main() -> TockResult<()> {
let mut drivers = libtock::retrieve_drivers()?;
- let mut console = drivers.console.create_console();
- writeln!(console, "Starting HMAC example")?;
+ drivers.console.create_console();
+ println!("Starting HMAC example");
let hmac_driver = drivers.hmac.init_driver()?;
- writeln!(console, "Loading in 0 key")?;
+ println!("Loading in 0 key");
let mut key_buffer = HmacKeyBuffer::default();
let _key_buffer = hmac_driver.init_key_buffer(&mut key_buffer)?;
- writeln!(console, " done")?;
+ println!(" done");
- writeln!(console, "Creating data buffer")?;
+ println!("Creating data buffer");
let mut data_buffer = HmacDataBuffer::default();
let data: &[u8; 72] =
b"A language empowering everyone to build reliable and efficient software.";
@@ -26,22 +26,22 @@
data_buffer[i] = *d;
}
let _data_buffer = hmac_driver.init_data_buffer(&mut data_buffer)?;
- writeln!(console, " done")?;
+ println!(" done");
- writeln!(console, "Creating dest buffer")?;
+ println!("Creating dest buffer");
let mut dest_buffer = HmacDestBuffer::default();
let dest_buffer = hmac_driver.init_dest_buffer(&mut dest_buffer)?;
- writeln!(console, " done")?;
+ println!(" done");
let mut temp_buffer = [0; libtock::hmac::DEST_BUFFER_SIZE];
- writeln!(console, "Setting callback and running")?;
+ println!("Setting callback and running");
let mut callback = |_result, _digest| {
- writeln!(console, "HMAC Complete, printing digest").unwrap();
+ println!("HMAC Complete, printing digest");
dest_buffer.read_bytes(&mut temp_buffer[..]);
for buf in temp_buffer.iter().take(libtock::hmac::DEST_BUFFER_SIZE) {
- write!(console, "{:x}", *buf).unwrap();
+ println!("{:x}", *buf);
}
};
diff --git a/examples/sensors.rs b/examples/sensors.rs
index 7ea87c7..5196cd1 100644
--- a/examples/sensors.rs
+++ b/examples/sensors.rs
@@ -1,6 +1,6 @@
#![no_std]
-use core::fmt::Write;
+use libtock::println;
use libtock::result::TockResult;
use libtock::sensors::Sensor;
use libtock::timer::Duration;
@@ -11,29 +11,13 @@
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
loop {
- writeln!(
- console,
- "Humidity: {}\n",
- drivers.humidity_sensor.read()?
- )?;
- writeln!(
- console,
- "Temperature: {}\n",
- drivers.temperature_sensor.read()?
- )?;
- writeln!(
- console,
- "Light: {}\n",
- drivers.ambient_light_sensor.read()?
- )?;
- writeln!(
- console,
- "Accel: {}\n",
- drivers.ninedof.read_acceleration()?
- )?;
+ println!("Humidity: {}\n", drivers.humidity_sensor.read()?);
+ println!("Temperature: {}\n", drivers.temperature_sensor.read()?);
+ println!("Light: {}\n", drivers.ambient_light_sensor.read()?);
+ println!("Accel: {}\n", drivers.ninedof.read_acceleration()?);
timer_driver.sleep(Duration::from_ms(500)).await?;
}
}
diff --git a/examples/temperature.rs b/examples/temperature.rs
index 7428187..6298cb4 100644
--- a/examples/temperature.rs
+++ b/examples/temperature.rs
@@ -1,6 +1,6 @@
#![no_std]
-use core::fmt::Write;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;
@@ -11,11 +11,11 @@
let mut temperature_driver = drivers.temperature.init_driver()?;
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
loop {
let temperature = temperature_driver.measure_temperature().await?;
- writeln!(console, "Temperature: {}", temperature)?;
+ println!("Temperature: {}", temperature);
timer_driver.sleep(Duration::from_ms(1000)).await?;
}
}
diff --git a/examples/timer.rs b/examples/timer.rs
index 493f0b9..2277e6c 100644
--- a/examples/timer.rs
+++ b/examples/timer.rs
@@ -1,10 +1,9 @@
#![no_std]
+use libtock::println;
/**
* This example shows a repeated timer combined with reading and displaying the current time in
* clock ticks.
**/
-use core::fmt::Write;
-use libtock::console::Console;
use libtock::result::TockResult;
use libtock::timer::DriverContext;
use libtock::timer::Duration;
@@ -15,12 +14,12 @@
async fn main() -> TockResult<()> {
let mut drivers = libtock::retrieve_drivers()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
let mut previous_ticks = None;
for i in 0.. {
- print_now(&mut console, &mut drivers.timer, &mut previous_ticks, i)?;
+ print_now(&mut drivers.timer, &mut previous_ticks, i)?;
let mut timer_driver = drivers.timer.create_timer_driver();
let timer_driver = timer_driver.activate()?;
@@ -31,7 +30,6 @@
}
fn print_now(
- console: &mut Console,
timer_context: &mut DriverContext,
previous_ticks: &mut Option<isize>,
i: usize,
@@ -41,8 +39,7 @@
let current_clock = timer.get_current_clock()?;
let ticks = current_clock.num_ticks();
let frequency = timer.clock_frequency().hz();
- writeln!(
- console,
+ println!(
"[{}] Waited roughly {}. Now is {} = {:#010x} ticks ({:?} ticks since last time at {} Hz)",
i,
PrettyTime::from_ms(i * DELAY_MS),
@@ -50,7 +47,7 @@
ticks,
previous_ticks.map(|previous| ticks - previous),
frequency
- )?;
+ );
*previous_ticks = Some(ticks);
Ok(())
}
diff --git a/examples/timer_subscribe.rs b/examples/timer_subscribe.rs
index 5c69be1..5a7ad4b 100644
--- a/examples/timer_subscribe.rs
+++ b/examples/timer_subscribe.rs
@@ -1,7 +1,7 @@
#![no_std]
-use core::fmt::Write;
use futures::future;
+use libtock::println;
use libtock::result::TockResult;
use libtock::timer::Duration;
@@ -9,14 +9,10 @@
async fn main() -> TockResult<()> {
let mut drivers = libtock::retrieve_drivers()?;
- let mut console = drivers.console.create_console();
+ drivers.console.create_console();
let mut with_callback = drivers.timer.with_callback(|_, _| {
- writeln!(
- console,
- "This line is printed 2 seconds after the start of the program.",
- )
- .unwrap();
+ println!("This line is printed 2 seconds after the start of the program.");
});
let mut timer = with_callback.init()?;
diff --git a/src/console.rs b/src/console.rs
index a94fc13..9bf2c24 100644
--- a/src/console.rs
+++ b/src/console.rs
@@ -5,8 +5,12 @@
use crate::syscalls;
use core::cell::Cell;
use core::fmt;
+use core::fmt::Write;
use core::mem;
+// Global console
+static mut CONSOLE: Option<Console> = None;
+
const DRIVER_NUMBER: usize = 1;
mod command_nr {
@@ -25,10 +29,12 @@
pub struct ConsoleDriver;
impl ConsoleDriver {
- pub fn create_console(self) -> Console {
- Console {
+ pub fn create_console(self) {
+ let console = Console {
allow_buffer: [0; 64],
- }
+ };
+
+ console.set_global_console();
}
}
@@ -36,6 +42,22 @@
allow_buffer: [u8; 64],
}
+pub static mut MISSED_PRINT: bool = false;
+
+pub fn get_global_console() -> Option<Console> {
+ unsafe {
+ if let Some(con) = CONSOLE.take() {
+ Some(con)
+ } else {
+ // If we get here then either the console was never initalised
+ // or someone else took it. Set MISSED_PRINT to true so that we
+ // can warn the user.
+ MISSED_PRINT = true;
+ None
+ }
+ }
+}
+
impl Console {
pub fn write<S: AsRef<[u8]>>(&mut self, text: S) -> TockResult<()> {
let mut not_written_yet = text.as_ref();
@@ -73,6 +95,19 @@
Ok(())
}
+
+ pub fn set_global_console(mut self) {
+ unsafe {
+ if MISSED_PRINT {
+ // Someone tried to print while we were or someone tried
+ // to print before initalisation, print a warning here.
+ let _ = write!(self, "A print was dropped while the console was locked");
+ MISSED_PRINT = false;
+ }
+
+ CONSOLE = Some(self);
+ }
+ }
}
impl fmt::Write for Console {
@@ -80,3 +115,47 @@
self.write(string).map_err(|_| fmt::Error)
}
}
+
+#[macro_export]
+macro_rules! println {
+ () => ({
+ // Allow an empty println!() to print the location when hit
+ println!("")
+ });
+ ($msg:expr) => ({
+ if let Some(mut console) = $crate::console::get_global_console() {
+ use core::fmt::Write;
+ let _ = writeln!(console, $msg);
+ console.set_global_console();
+ }
+ });
+ ($fmt:expr, $($arg:tt)+) => ({
+ if let Some(mut console) = $crate::console::get_global_console() {
+ use core::fmt::Write;
+ let _ = writeln!(console, "{}", format_args!($fmt, $($arg)+));
+ console.set_global_console();
+ }
+ });
+}
+
+#[macro_export]
+macro_rules! print {
+ () => ({
+ // Allow an empty print!() to print the location when hit
+ print!("")
+ });
+ ($msg:expr) => ({
+ if let Some(mut console) = $crate::console::get_global_console() {
+ use core::fmt::Write;
+ let _ = write!(console, $msg);
+ console.set_global_console();
+ }
+ });
+ ($fmt:expr, $($arg:tt)+) => ({
+ if let Some(mut console) = $crate::console::get_global_console() {
+ use core::fmt::Write;
+ let _ = write!(console, "{}", format_args!($fmt, $($arg)+));
+ console.set_global_console();
+ }
+ });
+}
diff --git a/src/debug/mod.rs b/src/debug/mod.rs
index 3bae683..85b4337 100644
--- a/src/debug/mod.rs
+++ b/src/debug/mod.rs
@@ -3,32 +3,18 @@
mod low_level_debug;
use crate::drivers;
+use crate::println;
use libtock_core::debug as core_debug;
pub use low_level_debug::*;
-pub fn println() {
- let buffer = [b'\n'];
- let drivers = unsafe { drivers::retrieve_drivers_unsafe() };
- let mut console = drivers.console.create_console();
- let _ = console.write(&buffer);
-}
-
-pub fn print_as_hex(value: usize) {
- let mut buffer = [b'\n'; 11];
- write_as_hex(&mut buffer, value);
- let drivers = unsafe { drivers::retrieve_drivers_unsafe() };
- let mut console = drivers.console.create_console();
- let _ = console.write(buffer);
-}
-
pub fn print_stack_pointer() {
let mut buffer = [b'\n'; 15];
buffer[0..4].clone_from_slice(b"SP: ");
write_as_hex(&mut buffer[4..15], core_debug::get_stack_pointer());
let drivers = unsafe { drivers::retrieve_drivers_unsafe() };
- let mut console = drivers.console.create_console();
- let _ = console.write(buffer);
+ drivers.console.create_console();
+ println!("{:?}", buffer);
}
#[inline(always)]
@@ -49,8 +35,8 @@
}
buffer[27] = b'\n';
let drivers = drivers::retrieve_drivers_unsafe();
- let mut console = drivers.console.create_console();
- let _ = console.write(&buffer);
+ drivers.console.create_console();
+ println!("{:?}", buffer);
}
/// Dumps arbitrary memory regions.