forked from M-Labs/artiq-zynq
Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Astro | 41d8af754a | |
pca006132 | 9611be657c |
|
@ -280,6 +280,12 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log_buffer"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f033173c9486b7fe97a79c895c0a3483ae395ab6744c985d10078950e2492419"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "managed"
|
name = "managed"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
|
@ -400,6 +406,7 @@ dependencies = [
|
||||||
"libregister",
|
"libregister",
|
||||||
"libsupport_zynq",
|
"libsupport_zynq",
|
||||||
"log",
|
"log",
|
||||||
|
"log_buffer",
|
||||||
"nb",
|
"nb",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
|
|
|
@ -22,6 +22,7 @@ void = { version = "1", default-features = false }
|
||||||
futures = { version = "0.3", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3", default-features = false, features = ["async-await"] }
|
||||||
async-recursion = "0.3"
|
async-recursion = "0.3"
|
||||||
fatfs = { version = "0.3", features = ["core_io"], default-features = false }
|
fatfs = { version = "0.3", features = ["core_io"], default-features = false }
|
||||||
|
log_buffer = { version = "1.2" }
|
||||||
|
|
||||||
libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||||
libsupport_zynq = { default-features = false, git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
libsupport_zynq = { default-features = false, git = "https://git.m-labs.hk/M-Labs/zc706.git" }
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
use core::cell::{Cell, RefCell, RefMut};
|
||||||
|
use core::fmt::Write;
|
||||||
|
use log::{Log, LevelFilter};
|
||||||
|
use log_buffer::LogBuffer;
|
||||||
|
use libboard_zynq::{println, timer::GlobalTimer};
|
||||||
|
|
||||||
|
pub struct LogBufferRef<'a> {
|
||||||
|
buffer: RefMut<'a, LogBuffer<&'static mut [u8]>>,
|
||||||
|
old_log_level: LevelFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LogBufferRef<'a> {
|
||||||
|
fn new(buffer: RefMut<'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: RefCell<LogBuffer<&'static mut [u8]>>,
|
||||||
|
uart_filter: Cell<LevelFilter>
|
||||||
|
}
|
||||||
|
|
||||||
|
static mut LOGGER: Option<BufferLogger> = None;
|
||||||
|
|
||||||
|
impl BufferLogger {
|
||||||
|
pub fn new(buffer: &'static mut [u8]) -> BufferLogger {
|
||||||
|
BufferLogger {
|
||||||
|
buffer: RefCell::new(LogBuffer::new(buffer)),
|
||||||
|
uart_filter: Cell::new(LevelFilter::Info),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register<F: FnOnce()>(self, f: F) {
|
||||||
|
unsafe {
|
||||||
|
LOGGER = Some(self);
|
||||||
|
log::set_logger(LOGGER.as_ref().unwrap())
|
||||||
|
.expect("global logger can only be initialized once");
|
||||||
|
}
|
||||||
|
log::set_max_level(LevelFilter::Info);
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with<R, F: FnOnce(&BufferLogger) -> R>(f: F) -> R {
|
||||||
|
f(unsafe { LOGGER.as_ref().expect("with logger") })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn buffer<'a>(&'a self) -> Result<LogBufferRef<'a>, ()> {
|
||||||
|
self.buffer
|
||||||
|
.try_borrow_mut()
|
||||||
|
.map(LogBufferRef::new)
|
||||||
|
.map_err(|_| ())
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
let seconds = timestamp / 1_000_000;
|
||||||
|
let micros = timestamp % 1_000_000;
|
||||||
|
|
||||||
|
if let Ok(mut buffer) = self.buffer.try_borrow_mut() {
|
||||||
|
writeln!(buffer, "[{:6}.{:06}s] {:>5}({}): {}", seconds, micros,
|
||||||
|
record.level(), record.target(), record.args()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
if record.level() <= self.uart_filter.get() {
|
||||||
|
println!("[{:6}.{:06}s] {:>5}({}): {}", seconds, micros,
|
||||||
|
record.level(), record.target(), record.args());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&self) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ extern crate alloc;
|
||||||
use core::{cmp, str};
|
use core::{cmp, str};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
|
||||||
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds, logger, devc, slcr};
|
use libboard_zynq::{timer::GlobalTimer, time::Milliseconds, devc, slcr, println};
|
||||||
use libsupport_zynq::ram;
|
use libsupport_zynq::ram;
|
||||||
use libregister::RegisterW;
|
use libregister::RegisterW;
|
||||||
use nb::block;
|
use nb::block;
|
||||||
|
@ -30,6 +30,7 @@ mod moninj;
|
||||||
mod load_pl;
|
mod load_pl;
|
||||||
mod eh_artiq;
|
mod eh_artiq;
|
||||||
mod panic;
|
mod panic;
|
||||||
|
mod logger;
|
||||||
|
|
||||||
fn init_gateware() {
|
fn init_gateware() {
|
||||||
// Set up PS->PL clocks
|
// Set up PS->PL clocks
|
||||||
|
@ -124,10 +125,16 @@ fn init_rtio(timer: GlobalTimer, cfg: &config::Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn main_core0() {
|
pub fn main_core0() {
|
||||||
let timer = GlobalTimer::start();
|
let timer = GlobalTimer::start();
|
||||||
let _ = logger::init();
|
unsafe {
|
||||||
|
println!("BUFFER ADDR = {:p}", LOG_BUFFER.as_ptr());
|
||||||
|
println!("BUFFER LEN = {}", LOG_BUFFER.len());
|
||||||
|
logger::BufferLogger::new(&mut LOG_BUFFER[..]).register(|| {});
|
||||||
|
}
|
||||||
log::set_max_level(log::LevelFilter::Debug);
|
log::set_max_level(log::LevelFilter::Debug);
|
||||||
info!("NAR3/Zynq7000 starting...");
|
info!("NAR3/Zynq7000 starting...");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue