diff --git a/src/libc/src/lib.rs b/src/libc/src/lib.rs index 7b53b850..2175a656 100644 --- a/src/libc/src/lib.rs +++ b/src/libc/src/lib.rs @@ -4,7 +4,9 @@ use libboard_zynq::stdio; +pub type c_char = i8; pub type c_int = i32; +pub type size_t = usize; pub type uintptr_t = usize; pub type c_void = core::ffi::c_void; diff --git a/src/runtime/src/analyzer.rs b/src/runtime/src/analyzer.rs index 1c8f4f0a..3db7f9b3 100644 --- a/src/runtime/src/analyzer.rs +++ b/src/runtime/src/analyzer.rs @@ -71,7 +71,7 @@ async fn handle_connection(stream: &mut TcpStream) -> Result<(), Error> { total_byte_count: total_byte_count, sent_bytes: if wraparound { BUFFER_SIZE as u32 } else { total_byte_count as u32 }, overflow_occurred: overflow_occurred, - log_channel: 255, + log_channel: pl::csr::CONFIG_RTIO_LOG_CHANNEL as u8, dds_onehot_sel: true // kept for backward compatibility of analyzer dumps }; debug!("{:?}", header); diff --git a/src/runtime/src/kernel/api.rs b/src/runtime/src/kernel/api.rs index 0153d7ab..aba60193 100644 --- a/src/runtime/src/kernel/api.rs +++ b/src/runtime/src/kernel/api.rs @@ -37,6 +37,7 @@ pub fn resolve(required: &[u8]) -> Option { api!(rtio_input_timestamp = rtio::input_timestamp), api!(rtio_input_data = rtio::input_data), api!(rtio_input_timestamped_data = rtio::input_timestamped_data), + api!(rtio_log = rtio::log), // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index ecd09705..40370946 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -3,6 +3,7 @@ #![recursion_limit="1024"] // for futures_util::select! #![feature(alloc_error_handler)] #![feature(panic_info_message)] +#![feature(c_variadic)] extern crate alloc; diff --git a/src/runtime/src/rtio.rs b/src/runtime/src/rtio.rs index ef5b9d18..0918d669 100644 --- a/src/runtime/src/rtio.rs +++ b/src/runtime/src/rtio.rs @@ -1,5 +1,9 @@ -use core::ptr::{read_volatile, write_volatile}; +use core::ptr::{self, read_volatile, write_volatile}; +use core::ffi::VaList; +use alloc::vec; use cslice::CSlice; +use libc::{c_char, c_int, size_t}; + use crate::artiq_raise; use crate::pl::csr; @@ -198,3 +202,34 @@ pub extern fn input_timestamped_data(timeout: i64, channel: i32) -> TimestampedD } } } + +extern "C" { + fn vsnprintf_(buffer: *mut c_char, count: size_t, format: *const c_char, va: VaList) -> c_int; +} + +fn write_rtio_log(data: &[i8]) { + unsafe { + csr::rtio::target_write(csr::CONFIG_RTIO_LOG_CHANNEL << 8); + + let mut word: u32 = 0; + for i in 0..data.len() { + word <<= 8; + word |= data[i] as u32; + if i % 4 == 3 { + rtio_o_data_write(0, word); + word = 0; + } + } + + if word != 0 { + rtio_o_data_write(0, word); + } + } +} + +pub unsafe extern fn log(fmt: *const c_char, mut args: ...) { + let size = vsnprintf_(ptr::null_mut(), 0, fmt, args.as_va_list()) as usize; + let mut buf = vec![0; size + 1]; + vsnprintf_(buf.as_mut_ptr(), size + 1, fmt, args.as_va_list()); + write_rtio_log(buf.as_slice()); +}