diff --git a/dodo.py b/dodo.py index f59ee5d..e6ded1c 100644 --- a/dodo.py +++ b/dodo.py @@ -88,6 +88,16 @@ def task_install_dep(): ], } +def task_check(): + """ Run a compiler check on the code. + """ + task = { + 'file_dep': get_build_dep(), + 'actions': [f'RUSTFLAGS="{consts.RUSTC_FLAGS}" cargo check --target={consts.TARGET} {consts.CARGO_COMPILE_FLAGS}'], + } + print(task) + return task + def task_compile(): """ Compile the sources. """ diff --git a/flash.sh b/flash.sh new file mode 100755 index 0000000..8e450b8 --- /dev/null +++ b/flash.sh @@ -0,0 +1,5 @@ +#!/usr/bin/sh + +udisksctl mount -b /dev/disk/by-label/BOOT +cp kernel8.img /run/media/me/BOOT/kernel8.img +udisksctl unmount -b /dev/disk/by-label/BOOT diff --git a/src/bsp/rpi3/uart.rs b/src/bsp/rpi3/uart.rs index c6ff694..caf892b 100644 --- a/src/bsp/rpi3/uart.rs +++ b/src/bsp/rpi3/uart.rs @@ -4,24 +4,27 @@ use core::arch::asm; use core::fmt; use crate::traits::console::{Write, Console}; +use crate::traits::synchronization::{DummyMutex, Mutex}; use super::memory_map::uart as mm; - pub struct Uart<'a> { + inner: DummyMutex>, +} + +pub struct UartInner<'a> { initialized: bool, memory_map: &'a mm::UartMemoryMap, } -impl<'a> Uart<'a> { - // TODO: not sure this should be public outside of bsp. +impl<'a> UartInner<'a> { /// Constructor for [`Uart`]. - pub const fn new(memory_map: &'a mm::UartMemoryMap) -> Self { - Uart { initialized: false, memory_map } + const fn new(memory_map: &'a mm::UartMemoryMap) -> Self { + Self { initialized: false, memory_map } } /// Initialise the UART. - pub fn init(&mut self) { + fn init(&mut self) { // TODO: Recover from possible previous test. self.flush(); @@ -68,55 +71,80 @@ impl<'a> Uart<'a> { fn is_tx_full(&self) -> bool { self.memory_map.fr_txff.read() != 0 } + + /// Write a character to the Uart + fn write_char(&self, c: char) { + if !self.initialized { + panic!("Cannot write to a non initialized UART"); + } + while self.is_tx_full() { + use super::gpio; + let _ = gpio::set_pin_output_state(20, gpio::PinOutputState::High); + unsafe { asm!("nop") }; + } + self.memory_map.dr_data.write_without_read(c as u32); + } + + /// Flush the uart + fn flush(&self) { + while self.is_busy() { + unsafe { asm!("nop") }; + } + } } // Allow the use of uart for fmt::Write::write_fmt. -impl fmt::Write for Uart<'_> { +impl fmt::Write for UartInner<'_> { fn write_str(&mut self, s: &str) -> fmt::Result { for c in s.chars() { if c == '\n' { - Write::write_char(self, '\r'); + UartInner::write_char(self, '\r'); } - Write::write_char(self, c); + UartInner::write_char(self, c); } Ok(()) } } -// TODO: add sync impl Write for Uart<'_> { fn write_char(&self, c: char) { - if !self.initialized { - //panic!("Cannot write to a non initialized UART"); - } - while self.is_tx_full() { - use super::gpio; - let _ = gpio::set_pin_output_state(20, gpio::PinOutputState::High); - unsafe { asm!("nop") }; - } - self.memory_map.dr_data.write_without_read(c as u32); + self.inner.lock(|uart| uart.write_char(c)) } fn write_fmt(&self, args: fmt::Arguments) -> fmt::Result { - // TODO: use syncronisation here - let mut new_uart = Uart { initialized: self.initialized, memory_map: self.memory_map}; - fmt::Write::write_fmt(&mut new_uart, args) + self.inner.lock(|uart| fmt::Write::write_fmt(uart, args)) } fn flush(&self) { - while self.is_busy() { - unsafe { asm!("nop") }; + self.inner.lock(|uart| uart.flush()) + } +} + +impl<'a> Uart<'a> { + + // TODO: not sure this should be public? public in bsp only? + /// Create a new UART object + const fn new(memory_map: &'a mm::UartMemoryMap) -> Self { + Self { + inner: DummyMutex::new( + UartInner::new(memory_map) + ) } } + + /// Initialize the UART. + fn init(&self) { + self.inner.lock(|uart| uart.init()) + } } impl Console for Uart<'_> {} -static UART: Uart = Uart { initialized: true, memory_map: &mm::UART }; // TODO: use sync +/// The UART object +static UART: Uart = Uart::new(&mm::UART); pub fn init() { - let mut uart = Uart::new(&mm::UART); - uart.init(); + UART.init(); } // TODO: move?