mirror of https://github.com/m-labs/artiq.git
firmware: factor out console and logging from runtime/satman.
This commit is contained in:
parent
5604d9bb55
commit
3633671656
|
@ -71,6 +71,15 @@ name = "log_buffer"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "logger_artiq"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"board 0.0.0",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "managed"
|
name = "managed"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -86,7 +95,7 @@ dependencies = [
|
||||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fringe 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fringe 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"logger_artiq 0.0.0",
|
||||||
"smoltcp 0.2.0 (git+https://github.com/m-labs/smoltcp?rev=b90495f)",
|
"smoltcp 0.2.0 (git+https://github.com/m-labs/smoltcp?rev=b90495f)",
|
||||||
"std_artiq 0.0.0",
|
"std_artiq 0.0.0",
|
||||||
]
|
]
|
||||||
|
@ -99,7 +108,7 @@ dependencies = [
|
||||||
"board 0.0.0",
|
"board 0.0.0",
|
||||||
"build_artiq 0.0.0",
|
"build_artiq 0.0.0",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"logger_artiq 0.0.0",
|
||||||
"std_artiq 0.0.0",
|
"std_artiq 0.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -10,3 +10,6 @@ path = "lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = { version = "0.3", default-features = false }
|
log = { version = "0.3", default-features = false }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
uart_console = []
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(asm)]
|
#![feature(asm, lang_items)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -12,6 +12,8 @@ pub mod spr;
|
||||||
pub mod irq;
|
pub mod irq;
|
||||||
pub mod clock;
|
pub mod clock;
|
||||||
pub mod uart;
|
pub mod uart;
|
||||||
|
#[cfg(feature = "uart_console")]
|
||||||
|
pub mod uart_console;
|
||||||
|
|
||||||
#[cfg(has_i2c)]
|
#[cfg(has_i2c)]
|
||||||
pub mod i2c;
|
pub mod i2c;
|
||||||
|
@ -29,6 +31,9 @@ mod ad9154_reg;
|
||||||
#[cfg(has_converter_spi)]
|
#[cfg(has_converter_spi)]
|
||||||
pub mod ad9154;
|
pub mod ad9154;
|
||||||
|
|
||||||
|
#[cfg(feature = "uart_console")]
|
||||||
|
pub use uart_console::Console;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub fn flush_cpu_dcache();
|
pub fn flush_cpu_dcache();
|
||||||
pub fn flush_l2_cache();
|
pub fn flush_l2_cache();
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
pub struct Console;
|
||||||
|
|
||||||
|
impl fmt::Write for Console {
|
||||||
|
fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
|
||||||
|
extern { fn putchar(c: i32) -> i32; }
|
||||||
|
for c in s.bytes() { unsafe { putchar(c as i32); } }
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! print {
|
||||||
|
($($arg:tt)*) => ({
|
||||||
|
use core::fmt::Write;
|
||||||
|
write!($crate::uart_console::Console, $($arg)*).unwrap()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! println {
|
||||||
|
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
||||||
|
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[lang = "panic_fmt"]
|
||||||
|
pub extern fn panic_fmt(args: fmt::Arguments, file: &'static str, line: u32) -> ! {
|
||||||
|
println!("panic at {}:{}: {}", file, line, args);
|
||||||
|
loop {}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
authors = ["M-Labs"]
|
||||||
|
name = "logger_artiq"
|
||||||
|
version = "0.0.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "logger_artiq"
|
||||||
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = { version = "0.3", default-features = false, features = [] }
|
||||||
|
log_buffer = { version = "1.0" }
|
||||||
|
board = { path = "../libboard" }
|
|
@ -1,17 +1,23 @@
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate log;
|
||||||
|
extern crate log_buffer;
|
||||||
|
extern crate board;
|
||||||
|
|
||||||
use core::{mem, ptr};
|
use core::{mem, ptr};
|
||||||
use core::cell::{Cell, RefCell};
|
use core::cell::{Cell, RefCell};
|
||||||
use log::{self, Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter};
|
use core::fmt::Write;
|
||||||
|
use log::{Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter};
|
||||||
use log_buffer::LogBuffer;
|
use log_buffer::LogBuffer;
|
||||||
use board;
|
use board::{Console, clock};
|
||||||
|
|
||||||
pub struct BufferLogger {
|
pub struct BufferLogger {
|
||||||
buffer: RefCell<LogBuffer<&'static mut [u8]>>,
|
buffer: RefCell<LogBuffer<&'static mut [u8]>>,
|
||||||
trace_to_uart: Cell<bool>
|
trace_to_uart: Cell<bool>
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Sync for BufferLogger {}
|
static mut LOGGER: *const BufferLogger = 0 as *const _;
|
||||||
|
|
||||||
static mut LOGGER: *const BufferLogger = ptr::null();
|
|
||||||
|
|
||||||
impl BufferLogger {
|
impl BufferLogger {
|
||||||
pub fn new(buffer: &'static mut [u8]) -> BufferLogger {
|
pub fn new(buffer: &'static mut [u8]) -> BufferLogger {
|
||||||
|
@ -44,11 +50,11 @@ impl BufferLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
borrow_mut!(self.buffer).clear()
|
self.buffer.borrow_mut().clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract<R, F: FnOnce(&str) -> R>(&self, f: F) -> R {
|
pub fn extract<R, F: FnOnce(&str) -> R>(&self, f: F) -> R {
|
||||||
f(borrow_mut!(self.buffer).extract())
|
f(self.buffer.borrow_mut().extract())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_trace_to_uart(&self) {
|
pub fn disable_trace_to_uart(&self) {
|
||||||
|
@ -60,6 +66,9 @@ impl BufferLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// required for impl Log
|
||||||
|
unsafe impl Sync for BufferLogger {}
|
||||||
|
|
||||||
impl Log for BufferLogger {
|
impl Log for BufferLogger {
|
||||||
fn enabled(&self, _metadata: &LogMetadata) -> bool {
|
fn enabled(&self, _metadata: &LogMetadata) -> bool {
|
||||||
true
|
true
|
||||||
|
@ -69,9 +78,8 @@ impl Log for BufferLogger {
|
||||||
if self.enabled(record.metadata()) {
|
if self.enabled(record.metadata()) {
|
||||||
let force_uart = match self.buffer.try_borrow_mut() {
|
let force_uart = match self.buffer.try_borrow_mut() {
|
||||||
Ok(mut buffer) => {
|
Ok(mut buffer) => {
|
||||||
use core::fmt::Write;
|
|
||||||
writeln!(buffer, "[{:12}us] {:>5}({}): {}",
|
writeln!(buffer, "[{:12}us] {:>5}({}): {}",
|
||||||
board::clock::get_us(), record.level(),
|
clock::get_us(), record.level(),
|
||||||
record.target(), record.args()).unwrap();
|
record.target(), record.args()).unwrap();
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -85,8 +93,9 @@ impl Log for BufferLogger {
|
||||||
// Printing to UART is really slow, so avoid doing that when we have an alternative
|
// Printing to UART is really slow, so avoid doing that when we have an alternative
|
||||||
// route to retrieve the debug messages.
|
// route to retrieve the debug messages.
|
||||||
if self.trace_to_uart.get() || record.level() <= LogLevel::Info || force_uart {
|
if self.trace_to_uart.get() || record.level() <= LogLevel::Info || force_uart {
|
||||||
println!("[{:12}us] {:>5}({}): {}",
|
writeln!(Console, "[{:12}us] {:>5}({}): {}",
|
||||||
board::clock::get_us(), record.level(), record.target(), record.args());
|
clock::get_us(), record.level(),
|
||||||
|
record.target(), record.args()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,10 +15,10 @@ build_artiq = { path = "../libbuild_artiq" }
|
||||||
[dependencies]
|
[dependencies]
|
||||||
alloc_artiq = { path = "../liballoc_artiq" }
|
alloc_artiq = { path = "../liballoc_artiq" }
|
||||||
std_artiq = { path = "../libstd_artiq", features = ["alloc"] }
|
std_artiq = { path = "../libstd_artiq", features = ["alloc"] }
|
||||||
board = { path = "../libboard" }
|
logger_artiq = { path = "../liblogger_artiq" }
|
||||||
fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] }
|
|
||||||
log = { version = "0.3", default-features = false, features = [] }
|
log = { version = "0.3", default-features = false, features = [] }
|
||||||
log_buffer = { version = "1.0" }
|
board = { path = "../libboard", features = ["uart_console"] }
|
||||||
|
fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] }
|
||||||
byteorder = { version = "1.0", default-features = false }
|
byteorder = { version = "1.0", default-features = false }
|
||||||
|
|
||||||
[dependencies.smoltcp]
|
[dependencies.smoltcp]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(libc, const_fn, repr_simd, asm, lang_items)]
|
#![feature(libc, repr_simd)]
|
||||||
|
|
||||||
extern crate alloc_artiq;
|
extern crate alloc_artiq;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -7,56 +7,20 @@ extern crate std_artiq as std;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate log_buffer;
|
extern crate logger_artiq;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
extern crate fringe;
|
extern crate fringe;
|
||||||
extern crate smoltcp;
|
extern crate smoltcp;
|
||||||
|
#[macro_use]
|
||||||
extern crate board;
|
extern crate board;
|
||||||
|
|
||||||
use core::fmt::Write;
|
|
||||||
use std::boxed::Box;
|
use std::boxed::Box;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn putchar(c: libc::c_int) -> libc::c_int;
|
|
||||||
fn readchar() -> libc::c_char;
|
fn readchar() -> libc::c_char;
|
||||||
fn readchar_nonblock() -> libc::c_int;
|
fn readchar_nonblock() -> libc::c_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! print {
|
|
||||||
($($arg:tt)*) => ($crate::print_fmt(format_args!($($arg)*)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! println {
|
|
||||||
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
|
||||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Console;
|
|
||||||
|
|
||||||
impl core::fmt::Write for Console {
|
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
|
|
||||||
for c in s.bytes() { unsafe { putchar(c as i32); } }
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_fmt(args: self::core::fmt::Arguments) {
|
|
||||||
let _ = Console.write_fmt(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
#[lang = "panic_fmt"]
|
|
||||||
pub extern fn panic_fmt(args: self::core::fmt::Arguments, file: &'static str, line: u32) -> ! {
|
|
||||||
let _ = write!(Console, "panic at {}:{}: {}\n", file, line, args);
|
|
||||||
let _ = write!(Console, "waiting for debugger...\n");
|
|
||||||
unsafe {
|
|
||||||
let _ = readchar();
|
|
||||||
loop { asm!("l.trap 0") }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! borrow_mut {
|
macro_rules! borrow_mut {
|
||||||
($x:expr) => ({
|
($x:expr) => ({
|
||||||
match $x.try_borrow_mut() {
|
match $x.try_borrow_mut() {
|
||||||
|
@ -74,7 +38,6 @@ mod rpc_queue;
|
||||||
|
|
||||||
mod urc;
|
mod urc;
|
||||||
mod sched;
|
mod sched;
|
||||||
mod logger;
|
|
||||||
mod cache;
|
mod cache;
|
||||||
|
|
||||||
mod proto;
|
mod proto;
|
||||||
|
@ -96,7 +59,7 @@ mod analyzer;
|
||||||
fn startup() {
|
fn startup() {
|
||||||
board::uart::set_speed(921600);
|
board::uart::set_speed(921600);
|
||||||
board::clock::init();
|
board::clock::init();
|
||||||
info!("booting ARTIQ");
|
info!("ARTIQ runtime starting...");
|
||||||
info!("software version {}", cfg!(git_describe));
|
info!("software version {}", cfg!(git_describe));
|
||||||
info!("gateware version {}", board::ident(&mut [0; 64]));
|
info!("gateware version {}", board::ident(&mut [0; 64]));
|
||||||
|
|
||||||
|
@ -176,7 +139,7 @@ pub unsafe extern fn main() -> i32 {
|
||||||
&_eheap as *const u8 as usize - &_fheap as *const u8 as usize);
|
&_eheap as *const u8 as usize - &_fheap as *const u8 as usize);
|
||||||
|
|
||||||
static mut LOG_BUFFER: [u8; 65536] = [0; 65536];
|
static mut LOG_BUFFER: [u8; 65536] = [0; 65536];
|
||||||
logger::BufferLogger::new(&mut LOG_BUFFER[..]).register(startup);
|
logger_artiq::BufferLogger::new(&mut LOG_BUFFER[..]).register(startup);
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::cell::RefCell;
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::btree_set::BTreeSet;
|
use std::btree_set::BTreeSet;
|
||||||
use {config, rtio_mgt, mailbox, rpc_queue, kernel};
|
use {config, rtio_mgt, mailbox, rpc_queue, kernel};
|
||||||
use logger::BufferLogger;
|
use logger_artiq::BufferLogger;
|
||||||
use cache::Cache;
|
use cache::Cache;
|
||||||
use urc::Urc;
|
use urc::Urc;
|
||||||
use sched::{ThreadHandle, Io};
|
use sched::{ThreadHandle, Io};
|
||||||
|
|
|
@ -15,6 +15,6 @@ build_artiq = { path = "../libbuild_artiq" }
|
||||||
[dependencies]
|
[dependencies]
|
||||||
alloc_artiq = { path = "../liballoc_artiq" }
|
alloc_artiq = { path = "../liballoc_artiq" }
|
||||||
std_artiq = { path = "../libstd_artiq", features = ["alloc"] }
|
std_artiq = { path = "../libstd_artiq", features = ["alloc"] }
|
||||||
|
logger_artiq = { path = "../liblogger_artiq" }
|
||||||
board = { path = "../libboard" }
|
board = { path = "../libboard" }
|
||||||
log = { version = "0.3", default-features = false }
|
log = { version = "0.3", default-features = false }
|
||||||
log_buffer = { version = "1.0" }
|
|
||||||
|
|
|
@ -7,8 +7,6 @@ OBJECTS := main.o
|
||||||
|
|
||||||
RUSTOUT := cargo/or1k-unknown-none/debug
|
RUSTOUT := cargo/or1k-unknown-none/debug
|
||||||
|
|
||||||
CFLAGS += -I$(LIBALLOC_DIRECTORY)
|
|
||||||
|
|
||||||
LDFLAGS += --gc-sections \
|
LDFLAGS += --gc-sections \
|
||||||
-L../libcompiler-rt \
|
-L../libcompiler-rt \
|
||||||
-L../libbase \
|
-L../libbase \
|
||||||
|
|
|
@ -1,60 +1,53 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![feature(libc, const_fn, repr_simd, asm, lang_items)]
|
|
||||||
|
|
||||||
extern crate alloc_artiq;
|
extern crate alloc_artiq;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate std_artiq as std;
|
extern crate std_artiq as std;
|
||||||
extern crate libc;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate log_buffer;
|
extern crate logger_artiq;
|
||||||
extern crate board;
|
extern crate board;
|
||||||
|
|
||||||
use core::fmt::Write;
|
fn startup() {
|
||||||
use logger::BufferLogger;
|
board::clock::init();
|
||||||
|
info!("ARTIQ satellite manager starting...");
|
||||||
|
info!("software version {}", cfg!(git_describe));
|
||||||
|
info!("gateware version {}", board::ident(&mut [0; 64]));
|
||||||
|
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
|
||||||
|
use board::{irq, csr};
|
||||||
extern {
|
extern {
|
||||||
fn putchar(c: libc::c_int) -> libc::c_int;
|
fn uart_init();
|
||||||
fn readchar() -> libc::c_char;
|
fn uart_isr();
|
||||||
fn readchar_nonblock() -> libc::c_int;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
fn alloc_give(ptr: *mut u8, length: usize);
|
||||||
macro_rules! print {
|
static mut _fheap: u8;
|
||||||
($($arg:tt)*) => ($crate::print_fmt(format_args!($($arg)*)));
|
static mut _eheap: u8;
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! println {
|
|
||||||
($fmt:expr) => (print!(concat!($fmt, "\n")));
|
|
||||||
($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Console;
|
|
||||||
|
|
||||||
impl core::fmt::Write for Console {
|
|
||||||
fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> {
|
|
||||||
for c in s.bytes() { unsafe { putchar(c as i32); } }
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn print_fmt(args: self::core::fmt::Arguments) {
|
|
||||||
let _ = Console.write_fmt(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[lang = "panic_fmt"]
|
pub unsafe extern fn main() -> i32 {
|
||||||
pub extern fn panic_fmt(args: self::core::fmt::Arguments, file: &'static str, line: u32) -> ! {
|
irq::set_mask(0);
|
||||||
let _ = write!(Console, "panic at {}:{}: {}\n", file, line, args);
|
irq::set_ie(true);
|
||||||
let _ = write!(Console, "waiting for debugger...\n");
|
uart_init();
|
||||||
unsafe {
|
|
||||||
let _ = readchar();
|
alloc_give(&mut _fheap as *mut u8,
|
||||||
loop { asm!("l.trap 0") }
|
&_eheap as *const u8 as usize - &_fheap as *const u8 as usize);
|
||||||
}
|
|
||||||
|
static mut LOG_BUFFER: [u8; 65536] = [0; 65536];
|
||||||
|
logger_artiq::BufferLogger::new(&mut LOG_BUFFER[..]).register(startup);
|
||||||
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
mod logger;
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn isr() {
|
||||||
|
let irqs = irq::pending() & irq::get_mask();
|
||||||
|
if irqs & (1 << csr::UART_INTERRUPT) != 0 {
|
||||||
|
uart_isr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Allow linking with crates that are built as -Cpanic=unwind even if we use -Cpanic=abort.
|
// Allow linking with crates that are built as -Cpanic=unwind even if we use -Cpanic=abort.
|
||||||
// This is never called.
|
// This is never called.
|
||||||
|
@ -63,29 +56,3 @@ mod logger;
|
||||||
pub extern "C" fn _Unwind_Resume() -> ! {
|
pub extern "C" fn _Unwind_Resume() -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern fn rust_main() {
|
|
||||||
static mut LOG_BUFFER: [u8; 65536] = [0; 65536];
|
|
||||||
BufferLogger::new(&mut LOG_BUFFER[..])
|
|
||||||
.register(move || {
|
|
||||||
board::clock::init();
|
|
||||||
info!("ARTIQ satellite manager starting...");
|
|
||||||
info!("software version {}", cfg!(git_describe));
|
|
||||||
info!("gateware version {}", board::ident(&mut [0; 64]));
|
|
||||||
|
|
||||||
loop {
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub unsafe extern fn isr() {
|
|
||||||
use board::{irq, csr};
|
|
||||||
extern { fn uart_isr(); }
|
|
||||||
|
|
||||||
let irqs = irq::pending() & irq::get_mask();
|
|
||||||
if irqs & (1 << csr::UART_INTERRUPT) != 0 {
|
|
||||||
uart_isr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
use core::{mem, ptr};
|
|
||||||
use core::cell::{Cell, RefCell};
|
|
||||||
use log::{self, Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter};
|
|
||||||
use log_buffer::LogBuffer;
|
|
||||||
use board;
|
|
||||||
|
|
||||||
pub struct BufferLogger {
|
|
||||||
buffer: RefCell<LogBuffer<&'static mut [u8]>>,
|
|
||||||
trace_to_uart: Cell<bool>
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Sync for BufferLogger {}
|
|
||||||
|
|
||||||
static mut LOGGER: *const BufferLogger = ptr::null();
|
|
||||||
|
|
||||||
impl BufferLogger {
|
|
||||||
pub fn new(buffer: &'static mut [u8]) -> BufferLogger {
|
|
||||||
BufferLogger {
|
|
||||||
buffer: RefCell::new(LogBuffer::new(buffer)),
|
|
||||||
trace_to_uart: Cell::new(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register<F: FnOnce()>(&self, f: F) {
|
|
||||||
// log::set_logger_raw captures a pointer to ourselves, so we must prevent
|
|
||||||
// ourselves from being moved or dropped after that function is called (and
|
|
||||||
// before log::shutdown_logger_raw is called).
|
|
||||||
unsafe {
|
|
||||||
log::set_logger_raw(|max_log_level| {
|
|
||||||
max_log_level.set(LogLevelFilter::Trace);
|
|
||||||
self as *const Log
|
|
||||||
}).expect("global logger can only be initialized once");
|
|
||||||
LOGGER = self;
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
log::shutdown_logger_raw().unwrap();
|
|
||||||
unsafe {
|
|
||||||
LOGGER = ptr::null();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_instance<R, F: FnOnce(&BufferLogger) -> R>(f: F) -> R {
|
|
||||||
f(unsafe { mem::transmute::<*const BufferLogger, &BufferLogger>(LOGGER) })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear(&self) {
|
|
||||||
self.buffer.borrow_mut().clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn extract<R, F: FnOnce(&str) -> R>(&self, f: F) -> R {
|
|
||||||
f(self.buffer.borrow_mut().extract())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn disable_trace_to_uart(&self) {
|
|
||||||
if self.trace_to_uart.get() {
|
|
||||||
trace!("disabling tracing to UART; all further trace messages \
|
|
||||||
are sent to core log only");
|
|
||||||
self.trace_to_uart.set(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Log for BufferLogger {
|
|
||||||
fn enabled(&self, _metadata: &LogMetadata) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log(&self, record: &LogRecord) {
|
|
||||||
if self.enabled(record.metadata()) {
|
|
||||||
use core::fmt::Write;
|
|
||||||
writeln!(self.buffer.borrow_mut(),
|
|
||||||
"[{:12}us] {:>5}({}): {}",
|
|
||||||
board::clock::get_us(), record.level(), record.target(), record.args()).unwrap();
|
|
||||||
|
|
||||||
// Printing to UART is really slow, so avoid doing that when we have an alternative
|
|
||||||
// route to retrieve the debug messages.
|
|
||||||
if self.trace_to_uart.get() || record.level() <= LogLevel::Info {
|
|
||||||
println!("[{:12}us] {:>5}({}): {}",
|
|
||||||
board::clock::get_us(), record.level(), record.target(), record.args());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
#include <alloc.h>
|
|
||||||
#include <irq.h>
|
|
||||||
#include <uart.h>
|
|
||||||
#include <system.h>
|
|
||||||
#include <generated/csr.h>
|
|
||||||
|
|
||||||
extern void _fheap, _eheap;
|
|
||||||
|
|
||||||
extern void rust_main();
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
irq_setmask(0);
|
|
||||||
irq_setie(1);
|
|
||||||
uart_init();
|
|
||||||
|
|
||||||
alloc_give(&_fheap, &_eheap - &_fheap);
|
|
||||||
|
|
||||||
rust_main();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue