forked from ROMEO/obsw
Using write() for output for better portability
This commit is contained in:
parent
716fdd7fa0
commit
02a7d525be
@ -2,10 +2,12 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
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;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
add_subdirectory(freeRTOS)
|
||||
add_subdirectory(ps7_cortexa9_0)
|
||||
add_subdirectory(newlib)
|
||||
|
||||
target_sources(${TARGET_NAME} PRIVATE main.c)
|
1
bsp_z7/newlib/CMakeLists.txt
Normal file
1
bsp_z7/newlib/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
||||
target_sources(${TARGET_NAME} PRIVATE write.c)
|
15
bsp_z7/newlib/write.c
Normal file
15
bsp_z7/newlib/write.c
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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)*);
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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<EFBFBD> Encoding");
|
||||
_ = writeln!(crate::fsrc::sif::Stderr {},"Schei<EFBFBD> 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]
|
||||
|
Loading…
x
Reference in New Issue
Block a user