Support channel names in RTIO errors #209
|
@ -423,7 +423,7 @@ pub fn main(timer: GlobalTimer, cfg: Config) {
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
drtio_routing::interconnect_disable_all();
|
drtio_routing::interconnect_disable_all();
|
||||||
|
|
||||||
rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer);
|
rtio_mgt::startup(&aux_mutex, &drtio_routing_table, &up_destinations, timer, &cfg);
|
||||||
|
|
||||||
analyzer::start();
|
analyzer::start();
|
||||||
moninj::start(timer, aux_mutex, drtio_routing_table);
|
moninj::start(timer, aux_mutex, drtio_routing_table);
|
||||||
|
|
|
@ -434,6 +434,7 @@ macro_rules! artiq_raise {
|
||||||
($name:expr, $message:expr, $param0:expr, $param1:expr, $param2:expr) => ({
|
($name:expr, $message:expr, $param0:expr, $param1:expr, $param2:expr) => ({
|
||||||
use cslice::AsCSlice;
|
use cslice::AsCSlice;
|
||||||
let name_id = $crate::eh_artiq::get_exception_id($name);
|
let name_id = $crate::eh_artiq::get_exception_id($name);
|
||||||
|
let message_cl = $message.clone();
|
||||||
let exn = $crate::eh_artiq::Exception {
|
let exn = $crate::eh_artiq::Exception {
|
||||||
id: name_id,
|
id: name_id,
|
||||||
file: file!().as_c_slice(),
|
file: file!().as_c_slice(),
|
||||||
|
@ -441,7 +442,7 @@ macro_rules! artiq_raise {
|
||||||
column: column!(),
|
column: column!(),
|
||||||
// https://github.com/rust-lang/rfcs/pull/1719
|
// https://github.com/rust-lang/rfcs/pull/1719
|
||||||
function: "(Rust function)".as_c_slice(),
|
function: "(Rust function)".as_c_slice(),
|
||||||
message: $message.as_c_slice(),
|
message: message_cl.as_c_slice(),
|
||||||
param: [$param0, $param1, $param2]
|
param: [$param0, $param1, $param2]
|
||||||
};
|
};
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::{
|
||||||
pl::csr,
|
pl::csr,
|
||||||
artiq_raise,
|
artiq_raise,
|
||||||
rtio,
|
rtio,
|
||||||
|
rtio_mgt::resolve_channel_name,
|
||||||
};
|
};
|
||||||
use alloc::{vec::Vec, string::String, boxed::Box};
|
use alloc::{vec::Vec, string::String, boxed::Box};
|
||||||
use cslice::CSlice;
|
use cslice::CSlice;
|
||||||
|
@ -198,12 +199,12 @@ pub extern fn dma_playback(timestamp: i64, ptr: i32) {
|
||||||
csr::rtio_dma::error_write(1);
|
csr::rtio_dma::error_write(1);
|
||||||
if error & 1 != 0 {
|
if error & 1 != 0 {
|
||||||
artiq_raise!("RTIOUnderflow",
|
artiq_raise!("RTIOUnderflow",
|
||||||
"RTIO underflow at {0} mu, channel {1}",
|
format!("RTIO underflow at channel {}:{}, {{0}} mu", channel, resolve_channel_name(channel as u32)),
|
||||||
timestamp as i64, channel as i64, 0);
|
timestamp as i64, channel as i64, 0);
|
||||||
}
|
}
|
||||||
if error & 2 != 0 {
|
if error & 2 != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, output, at {0} mu, channel {1}",
|
format!("RTIO destination unreachable, output, at {{0}} mu, channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
timestamp as i64, channel as i64, 0);
|
timestamp as i64, channel as i64, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#![feature(naked_functions)]
|
#![feature(naked_functions)]
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use log::{info, warn, error};
|
use log::{info, warn, error};
|
||||||
|
@ -70,16 +71,16 @@ async fn report_async_rtio_errors() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let errors = pl::csr::rtio_core::async_error_read();
|
let errors = pl::csr::rtio_core::async_error_read();
|
||||||
if errors & ASYNC_ERROR_COLLISION != 0 {
|
if errors & ASYNC_ERROR_COLLISION != 0 {
|
||||||
error!("RTIO collision involving channel {}",
|
let channel = pl::csr::rtio_core::collision_channel_read();
|
||||||
pl::csr::rtio_core::collision_channel_read());
|
error!("RTIO collision involving channel {}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32));
|
||||||
}
|
}
|
||||||
if errors & ASYNC_ERROR_BUSY != 0 {
|
if errors & ASYNC_ERROR_BUSY != 0 {
|
||||||
error!("RTIO busy error involving channel {}",
|
let channel = pl::csr::rtio_core::busy_channel_read();
|
||||||
pl::csr::rtio_core::busy_channel_read());
|
error!("RTIO busy error involving channel {}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32));
|
||||||
}
|
}
|
||||||
if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 {
|
if errors & ASYNC_ERROR_SEQUENCE_ERROR != 0 {
|
||||||
error!("RTIO sequence error involving channel {}",
|
let channel = pl::csr::rtio_core::sequence_error_channel_read();
|
||||||
pl::csr::rtio_core::sequence_error_channel_read());
|
error!("RTIO sequence error involving channel {}:{}", channel, rtio_mgt::resolve_channel_name(channel as u32));
|
||||||
}
|
}
|
||||||
SEEN_ASYNC_ERRORS = errors;
|
SEEN_ASYNC_ERRORS = errors;
|
||||||
pl::csr::rtio_core::async_error_write(errors);
|
pl::csr::rtio_core::async_error_write(errors);
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::artiq_raise;
|
||||||
use core::sync::atomic::{fence, Ordering};
|
use core::sync::atomic::{fence, Ordering};
|
||||||
|
|
||||||
use crate::pl::csr;
|
use crate::pl::csr;
|
||||||
|
use crate::rtio_mgt::resolve_channel_name;
|
||||||
|
|
||||||
pub const RTIO_O_STATUS_WAIT: i32 = 1;
|
pub const RTIO_O_STATUS_WAIT: i32 = 1;
|
||||||
pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
|
pub const RTIO_O_STATUS_UNDERFLOW: i32 = 2;
|
||||||
|
@ -87,12 +88,12 @@ unsafe fn process_exceptional_status(channel: i32, status: i32) {
|
||||||
}
|
}
|
||||||
if status & RTIO_O_STATUS_UNDERFLOW != 0 {
|
if status & RTIO_O_STATUS_UNDERFLOW != 0 {
|
||||||
artiq_raise!("RTIOUnderflow",
|
artiq_raise!("RTIOUnderflow",
|
||||||
"RTIO underflow at {0} mu, channel {1}, slack {2} mu",
|
format!("RTIO underflow at channel {}:{}, {{1}} mu, slack {{2}} mu", channel, resolve_channel_name(channel as u32)),
|
||||||
timestamp, channel as i64, timestamp - get_counter());
|
channel as i64, timestamp, timestamp - get_counter());
|
||||||
}
|
}
|
||||||
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, output, at {0} mu, channel {1}",
|
format!("RTIO destination unreachable, output, at {{0}} mu, channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
timestamp, channel as i64, 0);
|
timestamp, channel as i64, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +177,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
|
||||||
|
|
||||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||||
artiq_raise!("RTIOOverflow",
|
artiq_raise!("RTIOOverflow",
|
||||||
"RTIO input overflow on channel {0}",
|
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
||||||
|
@ -184,7 +185,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, input, on channel {0}",
|
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,12 +215,12 @@ pub extern fn input_data(channel: i32) -> i32 {
|
||||||
|
|
||||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||||
artiq_raise!("RTIOOverflow",
|
artiq_raise!("RTIOOverflow",
|
||||||
"RTIO input overflow on channel {0}",
|
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, input, on channel {0}",
|
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,12 +250,12 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD
|
||||||
|
|
||||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||||
artiq_raise!("RTIOOverflow",
|
artiq_raise!("RTIOOverflow",
|
||||||
"RTIO input overflow on channel {0}",
|
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, input, on channel {0}",
|
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use cslice::CSlice;
|
||||||
use crate::artiq_raise;
|
use crate::artiq_raise;
|
||||||
|
|
||||||
use crate::pl::csr;
|
use crate::pl::csr;
|
||||||
|
use crate::rtio_mgt::resolve_channel_name;
|
||||||
|
|
||||||
pub const RTIO_O_STATUS_WAIT: u8 = 1;
|
pub const RTIO_O_STATUS_WAIT: u8 = 1;
|
||||||
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2;
|
pub const RTIO_O_STATUS_UNDERFLOW: u8 = 2;
|
||||||
|
@ -72,12 +73,12 @@ unsafe fn process_exceptional_status(channel: i32, status: u8) {
|
||||||
}
|
}
|
||||||
if status & RTIO_O_STATUS_UNDERFLOW != 0 {
|
if status & RTIO_O_STATUS_UNDERFLOW != 0 {
|
||||||
artiq_raise!("RTIOUnderflow",
|
artiq_raise!("RTIOUnderflow",
|
||||||
"RTIO underflow at {0} mu, channel {1}, slack {2} mu",
|
format!("RTIO underflow at channel {}:{}, {{1}} mu, slack {{2}} mu", channel, resolve_channel_name(channel as u32)),
|
||||||
timestamp, channel as i64, timestamp - get_counter());
|
channel as i64, timestamp, timestamp - get_counter());
|
||||||
}
|
}
|
||||||
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_O_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, output, at {0} mu, channel {1}",
|
format!("RTIO destination unreachable, output, at {{0}} mu, channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
timestamp, channel as i64, 0);
|
timestamp, channel as i64, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +121,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
|
||||||
|
|
||||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||||
artiq_raise!("RTIOOverflow",
|
artiq_raise!("RTIOOverflow",
|
||||||
"RTIO input overflow on channel {0}",
|
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
||||||
|
@ -128,7 +129,7 @@ pub extern fn input_timestamp(timeout: i64, channel: i32) -> i64 {
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, input, on channel {0}",
|
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,12 +149,12 @@ pub extern fn input_data(channel: i32) -> i32 {
|
||||||
|
|
||||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||||
artiq_raise!("RTIOOverflow",
|
artiq_raise!("RTIOOverflow",
|
||||||
"RTIO input overflow on channel {0}",
|
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, input, on channel {0}",
|
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD
|
||||||
|
|
||||||
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
if status & RTIO_I_STATUS_OVERFLOW != 0 {
|
||||||
artiq_raise!("RTIOOverflow",
|
artiq_raise!("RTIOOverflow",
|
||||||
"RTIO input overflow on channel {0}",
|
format!("RTIO input overflow on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
if status & RTIO_I_STATUS_WAIT_EVENT != 0 {
|
||||||
|
@ -181,7 +182,7 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD
|
||||||
}
|
}
|
||||||
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
if status & RTIO_I_STATUS_DESTINATION_UNREACHABLE != 0 {
|
||||||
artiq_raise!("RTIODestinationUnreachable",
|
artiq_raise!("RTIODestinationUnreachable",
|
||||||
"RTIO destination unreachable, input, on channel {0}",
|
format!("RTIO destination unreachable, input, on channel {}:{}", channel, resolve_channel_name(channel as u32)),
|
||||||
channel as i64, 0, 0);
|
channel as i64, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
|
use alloc::collections::BTreeMap;
|
||||||
|
use alloc::string::String;
|
||||||
use libboard_zynq::timer::GlobalTimer;
|
use libboard_zynq::timer::GlobalTimer;
|
||||||
use libboard_artiq::{pl::csr, drtio_routing};
|
use libboard_artiq::{pl::csr, drtio_routing};
|
||||||
use libcortex_a9::mutex::Mutex;
|
use libcortex_a9::mutex::Mutex;
|
||||||
|
use libconfig::Config;
|
||||||
|
use io::{Cursor, ProtoRead};
|
||||||
|
use log::error;
|
||||||
|
|
||||||
|
static mut RTIO_DEVICE_MAP: BTreeMap<u32, String> = BTreeMap::new();
|
||||||
|
|
||||||
|
|
||||||
#[cfg(has_drtio)]
|
#[cfg(has_drtio)]
|
||||||
|
@ -332,6 +339,38 @@ pub mod drtio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_device_map(cfg: &Config) -> BTreeMap<u32, String> {
|
||||||
|
let mut device_map: BTreeMap<u32, String> = BTreeMap::new();
|
||||||
|
let _ = cfg.read("device_map").and_then(|raw_bytes| {
|
||||||
|
let mut bytes_cr = Cursor::new(raw_bytes);
|
||||||
|
let size = bytes_cr.read_u32().unwrap();
|
||||||
|
for _ in 0..size {
|
||||||
|
let channel = bytes_cr.read_u32().unwrap();
|
||||||
|
let device_name = bytes_cr.read_string().unwrap();
|
||||||
|
if let Some(old_entry) = device_map.insert(channel, device_name.clone()) {
|
||||||
|
error!("conflicting entries for channel {}: `{}` and `{}`",
|
||||||
|
channel, old_entry, device_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} ).or_else(|err| {
|
||||||
|
error!("read_device_map: error reading `device_map` from config: {}", err);
|
||||||
|
Err(err)
|
||||||
|
});
|
||||||
|
device_map
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _resolve_channel_name(channel: u32, device_map: &BTreeMap<u32, String>) -> String {
|
||||||
|
match device_map.get(&channel) {
|
||||||
|
Some(val) => val.clone(),
|
||||||
|
None => String::from("unknown")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolve_channel_name(channel: u32) -> String {
|
||||||
|
_resolve_channel_name(channel, unsafe{&RTIO_DEVICE_MAP})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(has_drtio))]
|
#[cfg(not(has_drtio))]
|
||||||
pub mod drtio {
|
pub mod drtio {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -346,7 +385,9 @@ pub mod drtio {
|
||||||
pub fn startup(aux_mutex: &Rc<Mutex<bool>>,
|
pub fn startup(aux_mutex: &Rc<Mutex<bool>>,
|
||||||
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
routing_table: &Rc<RefCell<drtio_routing::RoutingTable>>,
|
||||||
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
up_destinations: &Rc<RefCell<[bool; drtio_routing::DEST_COUNT]>>,
|
||||||
timer: GlobalTimer) {
|
timer: GlobalTimer,
|
||||||
|
cfg: &Config) {
|
||||||
|
unsafe { RTIO_DEVICE_MAP = read_device_map(cfg); }
|
||||||
drtio::startup(aux_mutex, routing_table, up_destinations, timer);
|
drtio::startup(aux_mutex, routing_table, up_destinations, timer);
|
||||||
unsafe {
|
unsafe {
|
||||||
csr::rtio_core::reset_phy_write(1);
|
csr::rtio_core::reset_phy_write(1);
|
||||||
|
|
Loading…
Reference in New Issue