From 5fa575ce4cc8614d71a5290d916489c7f5f3ebc1 Mon Sep 17 00:00:00 2001 From: mwojcik Date: Thu, 22 Jul 2021 11:24:43 +0200 Subject: [PATCH] drtio_routing: made to use libconfig; moved logger --- src/libboard_artiqzynq/Cargo.toml | 8 +- src/libboard_artiqzynq/drtio_routing.rs | 25 ++--- src/libboard_artiqzynq/lib.rs | 2 + src/libboard_artiqzynq/logger.rs | 123 ++++++++++++++++++++++++ src/satman/main.rs | 14 ++- 5 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 src/libboard_artiqzynq/logger.rs diff --git a/src/libboard_artiqzynq/Cargo.toml b/src/libboard_artiqzynq/Cargo.toml index 10983b8..781d48a 100644 --- a/src/libboard_artiqzynq/Cargo.toml +++ b/src/libboard_artiqzynq/Cargo.toml @@ -4,9 +4,13 @@ version = "0.0.0" authors = ["M-Labs"] [lib] -name = "board_artiqzync" +name = "board_artiqzynq" [dependencies] log = "0.4" +log_buffer = { version = "1.2" } + io = { path = "../libio", features = ["byteorder"] } -libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git"} \ No newline at end of file +libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git"} +libconfig = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git"} +libcortex_a9 = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } \ No newline at end of file diff --git a/src/libboard_artiqzynq/drtio_routing.rs b/src/libboard_artiqzynq/drtio_routing.rs index b561256..47d912c 100644 --- a/src/libboard_artiqzynq/drtio_routing.rs +++ b/src/libboard_artiqzynq/drtio_routing.rs @@ -1,7 +1,6 @@ -use board_misoc::config; // <- port; use libconfig? - +use libconfig::Config; #[cfg(has_drtio_routing)] -use pl::csr; // <- port +use pl::csr; // <- check if it works in the same way use core::fmt; #[cfg(has_drtio_routing)] @@ -54,22 +53,16 @@ impl fmt::Display for RoutingTable { } } -pub fn config_routing_table(default_n_links: usize) -> RoutingTable { +pub fn config_routing_table(default_n_links: usize, cfg: Config) -> RoutingTable { let mut ret = RoutingTable::default_master(default_n_links); - let ok = config::read("routing_table", |result| { - if let Ok(data) = result { - if data.len() == DEST_COUNT*MAX_HOPS { - for i in 0..DEST_COUNT { - for j in 0..MAX_HOPS { - ret.0[i][j] = data[i*MAX_HOPS+j]; - } + if let Ok(data) = cfg.read("routing_table").ok() && data.len() == DEST_COUNT*MAX_HOPS { + for i in 0..DEST_COUNT { + for j in 0..MAX_HOPS { + ret.0[i][j] = data[i*MAX_HOPS+j]; } - return true; } - } - false - }); - if !ok { + } + else { warn!("could not read routing table from configuration, using default"); } info!("routing table: {}", ret); diff --git a/src/libboard_artiqzynq/lib.rs b/src/libboard_artiqzynq/lib.rs index 3608519..b1b1943 100644 --- a/src/libboard_artiqzynq/lib.rs +++ b/src/libboard_artiqzynq/lib.rs @@ -1,5 +1,6 @@ pub mod clock; +// has csr; taken from runtime main #[path = "../../../build/pl.rs"] pub mod pl; @@ -7,3 +8,4 @@ pub mod pl; pub mod drtioaux; pub mod drtio_routing; pub mod si5324; +pub mod logger; diff --git a/src/libboard_artiqzynq/logger.rs b/src/libboard_artiqzynq/logger.rs new file mode 100644 index 0000000..3ae9643 --- /dev/null +++ b/src/libboard_artiqzynq/logger.rs @@ -0,0 +1,123 @@ +use core::cell::Cell; +use core::fmt::Write; +use log::{Log, LevelFilter}; +use log_buffer::LogBuffer; +use libcortex_a9::mutex::{Mutex, MutexGuard}; +use libboard_zynq::{println, timer::GlobalTimer}; + +pub struct LogBufferRef<'a> { + buffer: MutexGuard<'a, LogBuffer<&'static mut [u8]>>, + old_log_level: LevelFilter +} + +impl<'a> LogBufferRef<'a> { + fn new(buffer: MutexGuard<'a, LogBuffer<&'static mut [u8]>>) -> LogBufferRef<'a> { + let old_log_level = log::max_level(); + log::set_max_level(LevelFilter::Off); + LogBufferRef { buffer, old_log_level } + } + + pub fn is_empty(&self) -> bool { + self.buffer.is_empty() + } + + pub fn clear(&mut self) { + self.buffer.clear() + } + + pub fn extract(&mut self) -> &str { + self.buffer.extract() + } +} + +impl<'a> Drop for LogBufferRef<'a> { + fn drop(&mut self) { + log::set_max_level(self.old_log_level) + } +} + +pub struct BufferLogger { + buffer: Mutex>, + uart_filter: Cell, + buffer_filter: Cell, +} + +static mut LOGGER: Option = None; + +impl BufferLogger { + pub fn new(buffer: &'static mut [u8]) -> BufferLogger { + BufferLogger { + buffer: Mutex::new(LogBuffer::new(buffer)), + uart_filter: Cell::new(LevelFilter::Info), + buffer_filter: Cell::new(LevelFilter::Trace), + } + } + + pub fn register(self) { + unsafe { + LOGGER = Some(self); + log::set_logger(LOGGER.as_ref().unwrap()) + .expect("global logger can only be initialized once"); + } + } + + pub unsafe fn get_logger() -> &'static mut Option { + &mut LOGGER + } + + pub fn buffer<'a>(&'a self) -> Option> { + self.buffer + .try_lock() + .map(LogBufferRef::new) + } + + pub fn uart_log_level(&self) -> LevelFilter { + self.uart_filter.get() + } + + pub fn set_uart_log_level(&self, max_level: LevelFilter) { + self.uart_filter.set(max_level) + } + + pub fn buffer_log_level(&self) -> LevelFilter { + self.buffer_filter.get() + } + + /// this should be reserved for mgmt module + pub fn set_buffer_log_level(&self, max_level: LevelFilter) { + self.buffer_filter.set(max_level) + } +} + +// required for impl Log +unsafe impl Sync for BufferLogger {} + +impl Log for BufferLogger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + true + } + + fn log(&self, record: &log::Record) { + if self.enabled(record.metadata()) { + let timestamp = unsafe { + GlobalTimer::get() + }.get_us().0; + let seconds = timestamp / 1_000_000; + let micros = timestamp % 1_000_000; + + if record.level() <= self.buffer_log_level() { + let mut buffer = self.buffer.lock(); + writeln!(buffer, "[{:6}.{:06}s] {:>5}({}): {}", seconds, micros, + record.level(), record.target(), record.args()).unwrap(); + } + + if record.level() <= self.uart_log_level() { + println!("[{:6}.{:06}s] {:>5}({}): {}", seconds, micros, + record.level(), record.target(), record.args()); + } + } + } + + fn flush(&self) { + } +} diff --git a/src/satman/main.rs b/src/satman/main.rs index 0882be5..3368b27 100644 --- a/src/satman/main.rs +++ b/src/satman/main.rs @@ -5,13 +5,14 @@ extern crate log; use core::convert::TryFrom; -use board_misoc::{csr, irq, ident, clock, uart_logger, i2c}; // <- port, use libboard_zynq +use board_misoc::{csr, irq, ident, clock, i2c}; // <- port, use libboard_zynq #[cfg(has_si5324)] use board_artiqzynq::si5324; // <- move from runtime #[cfg(has_wrpll)] use board_artiq::wrpll; // <- port -use board_artiq::{spi, drtioaux}; // <- port, use libboard_zynq -use board_artiq::drtio_routing; // <- artiqzync +use board_artiq::spi; // <- port?, use libboard_zynq (if spi available/necessary) +use board_artiqzynq::{drtio_routing drtioaux}; // <- artiqzync +use board_artiqzynq::logger; mod repeater; #[cfg(has_jdcg)] @@ -414,8 +415,13 @@ const SI5324_SETTINGS: si5324::FrequencySettings #[no_mangle] pub extern fn main() -> i32 { clock::init(); - uart_logger::ConsoleLogger::register(); + let buffer_logger = unsafe { + logger::BufferLogger::new(&mut LOG_BUFFER[..]) + }; + buffer_logger.set_uart_log_level(log::LevelFilter::Info); + buffer_logger.register(); + info!("ARTIQ satellite manager starting..."); info!("software ident {}", csr::CONFIG_IDENTIFIER_STR); info!("gateware ident {}", ident::read(&mut [0; 64]));