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 <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
void mission(void);
|
void mission(void);
|
||||||
|
|
||||||
void done() {
|
void done() {
|
||||||
printf("done.");
|
printf("done.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15,11 +17,10 @@ void rust_eh_personality() {
|
|||||||
puts("eh_personality");
|
puts("eh_personality");
|
||||||
}
|
}
|
||||||
|
|
||||||
void outbyte(uint8_t byte){
|
|
||||||
printf("%c", byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
printf("std %i sterr %i\n", stdout, stderr);
|
||||||
|
const char * buffer ="123";
|
||||||
|
write(STDOUT_FILENO, buffer, 3);
|
||||||
mission();
|
mission();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
add_subdirectory(freeRTOS)
|
add_subdirectory(freeRTOS)
|
||||||
add_subdirectory(ps7_cortexa9_0)
|
add_subdirectory(ps7_cortexa9_0)
|
||||||
|
add_subdirectory(newlib)
|
||||||
|
|
||||||
target_sources(${TARGET_NAME} PRIVATE main.c)
|
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/xil_testio.c
|
||||||
src/xplatform_info.c
|
src/xplatform_info.c
|
||||||
src/getpid.c
|
src/getpid.c
|
||||||
src/write.c
|
#src/write.c
|
||||||
src/xil_mem.c
|
src/xil_mem.c
|
||||||
src/kill.c
|
src/kill.c
|
||||||
src/xil_mmu.c
|
src/xil_mmu.c
|
||||||
|
@ -1,37 +1,76 @@
|
|||||||
// TODO this is platform specific
|
// TODO this is platform specific
|
||||||
|
|
||||||
pub struct Outbytes {}
|
pub struct Stdout {}
|
||||||
|
pub struct Stderr {}
|
||||||
|
|
||||||
use core::fmt::{Error, Write};
|
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> {
|
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
||||||
for c in s.as_bytes() {
|
|
||||||
unsafe {
|
// Safe because write will only read the pointer an then return
|
||||||
crate::fsrc::osal::outbyte(*c);
|
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(())
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sifln {
|
macro_rules! sifln {
|
||||||
($(,)?) => (
|
($(,)?) => (
|
||||||
let mut stdout = Outbytes {};
|
//let mut stdout = Outbytes {};
|
||||||
writeln!(stdout);
|
writeln!(Stdout {});
|
||||||
);
|
);
|
||||||
($($arg:tt)*) => (
|
($($arg:tt)*) => (
|
||||||
let mut stdout = crate::fsrc::sif::Outbytes {};
|
let _alwaysok = writeln!(crate::fsrc::sif::Stdout {}, $($arg)*);
|
||||||
let _alwaysok = writeln!(stdout, $($arg)*);
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sif {
|
macro_rules! sif {
|
||||||
($($arg:tt)*) => (
|
($($arg:tt)*) => (
|
||||||
let mut stdout = crate::fsrc::sif::Outbytes {};
|
let _alwaysok = write!(crate::fsrc::sif::Stdout {}, $($arg)*);
|
||||||
let _alwaysok = write!(stdout, $($arg)*);
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ fn panic(panic: &PanicInfo<'_>) -> ! {
|
|||||||
osal::stop_it();
|
osal::stop_it();
|
||||||
}
|
}
|
||||||
// TODO: Make this unicode-safe
|
// TODO: Make this unicode-safe
|
||||||
sifln!("");
|
_ = writeln!(crate::fsrc::sif::Stderr {},"");
|
||||||
sif!("in task \"");
|
_ = write!(crate::fsrc::sif::Stderr {},"in task \"");
|
||||||
unsafe {
|
unsafe {
|
||||||
//osal::get_task_name is implemented safely in C, so we trust it
|
//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());
|
let task_name = core::ffi::CStr::from_ptr(osal::get_task_name());
|
||||||
@ -32,12 +32,12 @@ fn panic(panic: &PanicInfo<'_>) -> ! {
|
|||||||
sif!("{}", string);
|
sif!("{}", string);
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
sif!("Schei<EFBFBD> Encoding");
|
_ = writeln!(crate::fsrc::sif::Stderr {},"Schei<EFBFBD> Encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sifln!("\":");
|
_ = writeln!(crate::fsrc::sif::Stderr {},"\":");
|
||||||
sifln!("{}", panic);
|
_ = writeln!(crate::fsrc::sif::Stderr {},"{}", panic);
|
||||||
//TODO: stop RTOS, exit if hosted
|
//TODO: stop RTOS, exit if hosted
|
||||||
unsafe { done() };
|
unsafe { done() };
|
||||||
loop {}
|
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]
|
#[no_mangle]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user