diff --git a/bsp_linux/main.c b/bsp_linux/main.c index d884385..f56f989 100644 --- a/bsp_linux/main.c +++ b/bsp_linux/main.c @@ -2,10 +2,12 @@ #include #include +#include + void mission(void); void done() { - printf("done."); + printf("done.\n"); exit(0); } @@ -15,11 +17,10 @@ void rust_eh_personality() { puts("eh_personality"); } -void outbyte(uint8_t byte){ - printf("%c", byte); -} - int main(void) { + printf("std %i sterr %i\n", stdout, stderr); + const char * buffer ="123"; + write(STDOUT_FILENO, buffer, 3); mission(); return 0; } \ No newline at end of file diff --git a/bsp_z7/CMakeLists.txt b/bsp_z7/CMakeLists.txt index 732ad32..d5d3e3d 100644 --- a/bsp_z7/CMakeLists.txt +++ b/bsp_z7/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(freeRTOS) add_subdirectory(ps7_cortexa9_0) +add_subdirectory(newlib) target_sources(${TARGET_NAME} PRIVATE main.c) \ No newline at end of file diff --git a/bsp_z7/newlib/CMakeLists.txt b/bsp_z7/newlib/CMakeLists.txt new file mode 100644 index 0000000..09d4bd8 --- /dev/null +++ b/bsp_z7/newlib/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${TARGET_NAME} PRIVATE write.c) \ No newline at end of file diff --git a/bsp_z7/newlib/write.c b/bsp_z7/newlib/write.c new file mode 100644 index 0000000..365fb29 --- /dev/null +++ b/bsp_z7/newlib/write.c @@ -0,0 +1,15 @@ +#include "xil_printf.h" +#include "xparameters.h" + +int write(int file, char *ptr, int len) { + if (ptr == NULL) { + return 0; + } + // TODO file descriptors + int todo; + + for (todo = 0; todo < len; todo++) { + outbyte(*ptr++); + } + return len; +} \ No newline at end of file diff --git a/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt b/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt index 416de1f..bfb6e99 100644 --- a/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt +++ b/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt @@ -22,7 +22,7 @@ target_sources(${TARGET_NAME} PUBLIC src/xil_testio.c src/xplatform_info.c src/getpid.c - src/write.c + #src/write.c src/xil_mem.c src/kill.c src/xil_mmu.c diff --git a/mission_rust/src/fsrc/sif.rs b/mission_rust/src/fsrc/sif.rs index f56438b..ec31dc1 100644 --- a/mission_rust/src/fsrc/sif.rs +++ b/mission_rust/src/fsrc/sif.rs @@ -1,37 +1,76 @@ // TODO this is platform specific -pub struct Outbytes {} +pub struct Stdout {} +pub struct Stderr {} use core::fmt::{Error, Write}; -impl Write for Outbytes { +extern "C" { + pub fn write(fd: core::ffi::c_int, buffer: *const core::ffi::c_void, count: usize) -> core::ffi::c_int; +} + +impl Write for Stdout { fn write_str(&mut self, s: &str) -> Result<(), Error> { - for c in s.as_bytes() { - unsafe { - crate::fsrc::osal::outbyte(*c); - } + + // Safe because write will only read the pointer an then return + let result = unsafe { + write( + 1, + s.as_bytes().as_ptr() as *const core::ffi::c_void, + s.as_bytes().len(), + ) + }; + // We do not retry incomplete writes, this is stdout after all... + let safe_count: i32 = match s.as_bytes().len().try_into() { + Ok(count)=> count, + Err(_) => return Err(Error) + }; + if result < safe_count { + Err(Error) + } else { + Ok(()) + } + } +} + +impl Write for Stderr { + fn write_str(&mut self, s: &str) -> Result<(), Error> { + + // Safe because write will only read the pointer an then return + let result = unsafe { + write( + 2, + s.as_bytes().as_ptr() as *const core::ffi::c_void, + s.as_bytes().len(), + ) + }; + // We do not retry incomplete writes, this is stdout after all... + let safe_count: i32 = match s.as_bytes().len().try_into() { + Ok(count)=> count, + Err(_) => return Err(Error) + }; + if result < safe_count { + Err(Error) + } else { + Ok(()) } - Ok(()) } } #[macro_export] macro_rules! sifln { ($(,)?) => ( - let mut stdout = Outbytes {}; - writeln!(stdout); + //let mut stdout = Outbytes {}; + writeln!(Stdout {}); ); ($($arg:tt)*) => ( - let mut stdout = crate::fsrc::sif::Outbytes {}; - let _alwaysok = writeln!(stdout, $($arg)*); + let _alwaysok = writeln!(crate::fsrc::sif::Stdout {}, $($arg)*); ); } #[macro_export] macro_rules! sif { ($($arg:tt)*) => ( - let mut stdout = crate::fsrc::sif::Outbytes {}; - let _alwaysok = write!(stdout, $($arg)*); + let _alwaysok = write!(crate::fsrc::sif::Stdout {}, $($arg)*); ); } - diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 8ebd689..6ce067a 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -20,9 +20,9 @@ fn panic(panic: &PanicInfo<'_>) -> ! { unsafe { osal::stop_it(); } - // TODO: Make this unicode-safe - sifln!(""); - sif!("in task \""); + // TODO: Make this unicode-safe + _ = writeln!(crate::fsrc::sif::Stderr {},""); + _ = write!(crate::fsrc::sif::Stderr {},"in task \""); unsafe { //osal::get_task_name is implemented safely in C, so we trust it let task_name = core::ffi::CStr::from_ptr(osal::get_task_name()); @@ -32,12 +32,12 @@ fn panic(panic: &PanicInfo<'_>) -> ! { sif!("{}", string); } Err(_) => { - sif!("Schei� Encoding"); + _ = writeln!(crate::fsrc::sif::Stderr {},"Schei� Encoding"); } } } - sifln!("\":"); - sifln!("{}", panic); + _ = writeln!(crate::fsrc::sif::Stderr {},"\":"); + _ = writeln!(crate::fsrc::sif::Stderr {},"{}", panic); //TODO: stop RTOS, exit if hosted unsafe { done() }; loop {} @@ -59,7 +59,7 @@ extern "C" fn rust_assert_called(ptr: *const core::ffi::c_char, line: core::ffi: } }; - panic!("assertion failed at {file_name}:{}", line); + panic!("assertion failed at {file_name}:{line}"); } #[no_mangle]