diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cfbd4a..a59a412 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,8 @@ set(ROMEO_Z7_LINK_OPTIONS -Wl,--cref -Wl,-Map=${OBSW_NAME}.map -mcpu=cortex-a9 - set(ROMEO_WARNING_FLAGS -Wall -Wextra - -Wpedantic) - #-Werror) #TODO fix Xilinx stuff + -Wpedantic + -Werror) # TODO so far, this only affects mission code, not bsp # CMake options which are only available when crosscompiling if (${CMAKE_CROSSCOMPILING}) diff --git a/bsp_linux/hardware/hardware.c b/bsp_linux/hardware/hardware.c index 890e6e0..f0e33ec 100644 --- a/bsp_linux/hardware/hardware.c +++ b/bsp_linux/hardware/hardware.c @@ -40,8 +40,6 @@ const char *get_port_number(const char *path, size_t path_len) { return NULL; } - - int hw_device_open(const char *path, size_t path_len) { int serial_fd = serial_open(path, path_len); diff --git a/bsp_linux/main.c b/bsp_linux/main.c index 918acee..6e80ac2 100644 --- a/bsp_linux/main.c +++ b/bsp_linux/main.c @@ -14,25 +14,26 @@ int ai_family = AF_UNSPEC; void mission(void); +void done() { exit(0); } -void done() { - exit(0); -} - -void done_error() { - exit(1); -} +void done_error() { exit(1); } int test_socket(); // TODO link to GCC's personality or make the linux build not use it? void rust_eh_personality() { puts("eh_personality"); } -void print_usage(const char * name) { -fprintf(stderr, "Usage: %s [-s sim_ip] [-4|6]\n", name); +void print_usage(const char *name) { + fprintf(stderr, "Usage: %s [-s sim_ip] [-4|6]\n", name); } +#include + int main(int argc, char **argv) { + hw_device_open( + "invalidpath", + 11); // TODO for some weird linker behaviour, if this function is not used + // here, it will not be found by the linker when linking the rust lib static struct option long_options[] = { /* NAME ARGUMENT FLAG SHORTNAME */ {"sim_ip", required_argument, NULL, 's'}, @@ -58,9 +59,8 @@ int main(int argc, char **argv) { exit(EXIT_FAILURE); } } - } + } mission(); return 0; } - diff --git a/bsp_z7/hardware/interface_access.h b/bsp_z7/hardware/interface_access.h index 5578958..6eea8b3 100644 --- a/bsp_z7/hardware/interface_access.h +++ b/bsp_z7/hardware/interface_access.h @@ -1,5 +1,7 @@ #pragma once -int hw_interface_write(int fd, const char *ptr, int len); +#include -int hw_interface_read(int fd, char *ptr, int len); \ No newline at end of file +int hw_interface_write(int fd, const char *ptr, size_t len); + +int hw_interface_read(int fd, char *ptr, size_t len); \ No newline at end of file diff --git a/bsp_z7/hardware/interfaces.c b/bsp_z7/hardware/interfaces.c index 8e47112..8293038 100644 --- a/bsp_z7/hardware/interfaces.c +++ b/bsp_z7/hardware/interfaces.c @@ -53,14 +53,14 @@ ssize_t hw_device_transfer(int fd, void *sendbuffer, void *receivebuffer, // we could implement interrupt based nonblocking sending using a queue // like we do receiving (where we need it for the small hw buffer) // but in the end, we do not want too many interrupts, so we do it blocking -void uart_send(uint32_t BaseAddress, const char *data, int data_len) { +void uart_send(uint32_t BaseAddress, const char *data, size_t data_len) { int todo; for (todo = 0; todo < data_len; todo++) { XUartPs_SendByte(BaseAddress, *data++); } } -int hw_interface_write(int fd, const char *ptr, int len) { +int hw_interface_write(int fd, const char *ptr, size_t len) { enum InterfaceFileDescriptors fd_enum = fd; switch (fd) { case UART_0: @@ -74,7 +74,7 @@ int hw_interface_write(int fd, const char *ptr, int len) { return -1; } -int hw_interface_read(int fd, char *ptr, int len) { +int hw_interface_read(int fd, char *ptr, size_t len) { enum InterfaceFileDescriptors fd_enum = fd; switch (fd) { case UART_0: diff --git a/bsp_z7/hardware/uart.c b/bsp_z7/hardware/uart.c index da5b018..8e4db59 100644 --- a/bsp_z7/hardware/uart.c +++ b/bsp_z7/hardware/uart.c @@ -143,7 +143,7 @@ void uart1_enable_receiver() { XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_1_INTR); } -int uart0_read(char *ptr, int len) { +int uart0_read(char *ptr, size_t len) { // TODO for blocking, if first call was successfull, further calls need to be // delay=0 int received = 0; @@ -159,7 +159,7 @@ int uart0_read(char *ptr, int len) { return received; } -int uart1_read(char *ptr, int len) { +int uart1_read(char *ptr, size_t len) { // TODO for blocking, if first call was successfull, further calls need to be // delay=0 int received = 0; diff --git a/bsp_z7/hardware/uart.h b/bsp_z7/hardware/uart.h index 8ee06b2..b0e5176 100644 --- a/bsp_z7/hardware/uart.h +++ b/bsp_z7/hardware/uart.h @@ -1,6 +1,6 @@ #pragma once void uart0_enable_receiver(); -int uart0_read(char *ptr, int len); +int uart0_read(char *ptr, int size_t); void uart1_enable_receiver(); -int uart1_read(char *ptr, int len); \ No newline at end of file +int uart1_read(char *ptr, int size_t); \ No newline at end of file diff --git a/bsp_z7/ps7_cortexa9_0/include/xuartps.h b/bsp_z7/ps7_cortexa9_0/include/xuartps.h index 89ed5fd..9f52528 100644 --- a/bsp_z7/ps7_cortexa9_0/include/xuartps.h +++ b/bsp_z7/ps7_cortexa9_0/include/xuartps.h @@ -447,10 +447,11 @@ typedef struct { * u32 XUartPs_IsTransmitEmpty(XUartPs InstancePtr) * ******************************************************************************/ +#ifndef XUartPs_IsTransmitEmpty // Xilinx screwed up #define XUartPs_IsTransmitEmpty(InstancePtr) \ ((Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_SR_OFFSET) & \ (u32)XUARTPS_SR_TXEMPTY) == (u32)XUARTPS_SR_TXEMPTY) - +#endif /************************** Function Prototypes *****************************/ diff --git a/bsp_z7/ps7_cortexa9_0/libsrc/uartps/src/xuartps.h b/bsp_z7/ps7_cortexa9_0/libsrc/uartps/src/xuartps.h index 89ed5fd..9f52528 100644 --- a/bsp_z7/ps7_cortexa9_0/libsrc/uartps/src/xuartps.h +++ b/bsp_z7/ps7_cortexa9_0/libsrc/uartps/src/xuartps.h @@ -447,10 +447,11 @@ typedef struct { * u32 XUartPs_IsTransmitEmpty(XUartPs InstancePtr) * ******************************************************************************/ +#ifndef XUartPs_IsTransmitEmpty // Xilinx screwed up #define XUartPs_IsTransmitEmpty(InstancePtr) \ ((Xil_In32(((InstancePtr)->Config.BaseAddress) + (u32)XUARTPS_SR_OFFSET) & \ (u32)XUARTPS_SR_TXEMPTY) == (u32)XUARTPS_SR_TXEMPTY) - +#endif /************************** Function Prototypes *****************************/ diff --git a/common/git_version/get_version.cmake b/common/git_version/get_version.cmake index f8e96db..584e598 100644 --- a/common/git_version/get_version.cmake +++ b/common/git_version/get_version.cmake @@ -1,3 +1,3 @@ -execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --dirty OUTPUT_VARIABLE GIT_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE) +execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --dirty --always OUTPUT_VARIABLE GIT_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE) string(TIMESTAMP BUILD_TIME_STRING UTC) configure_file(${INPUT_FILE} ${OUTPUT_FILE}) \ No newline at end of file diff --git a/mission/mission.c b/mission/mission.c index 4a8284b..932d66b 100644 --- a/mission/mission.c +++ b/mission/mission.c @@ -1,14 +1,11 @@ /* Standard includes. */ #include -#include /* Scheduler include files. */ #include "freeRTOS_rust_helper.h" #include "semphr.h" #include "task.h" -#include - #include #include @@ -16,31 +13,6 @@ void rust_main(void); -void test_hardware() { - - int fd0 = hw_device_open("uart0", 5); - write(fd0, "UART0\n", 6); - int fd1 = hw_device_open("uart1", 5); - write(fd1, "UART1\n", 6); - - // uint8_t buffer[255]; - - // for (int i = 0; i< sizeof(buffer); i++) { - // buffer[i] = i; - // } - - // write(fd0, buffer, sizeof(buffer)); - - // vTaskDelay(10 / portTICK_PERIOD_MS); - - // write(1, "got:\n", 5); - - // int read_bytes = read(fd0, buffer, sizeof(buffer)); - // write(1, buffer, read_bytes); - // read_bytes = read(fd1, buffer, sizeof(buffer)); - // write(1, buffer, read_bytes); -} - // called to stop execution on error // to be implemented by bsp (do not return from it!) void done_error(); @@ -61,8 +33,6 @@ void mission(void) { write(1, BUILD_TIME_STRING, strlen(BUILD_TIME_STRING)); write(1, "\n", 1); - test_hardware(); - freertos_init_and_start_scheduling(init_task); /* If all is well, the scheduler will now be running, and the following diff --git a/mission_rust/CMakeLists.txt b/mission_rust/CMakeLists.txt index 06fbb87..c9eff4f 100644 --- a/mission_rust/CMakeLists.txt +++ b/mission_rust/CMakeLists.txt @@ -5,7 +5,6 @@ -#TODO can we get CMake to configure cmake --build --clean to run cargo clean? #TODO look into corrosion cmake plugin if (${CMAKE_CROSSCOMPILING}) @@ -16,6 +15,8 @@ if (${CMAKE_CROSSCOMPILING}) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) + set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/target/${CMAKE_SYSTEM_PROCESSOR}/$,release,debug>/) + add_library(mission_rust INTERFACE) add_dependencies(mission_rust mission_rust_internal) @@ -30,6 +31,8 @@ else() WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) + set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${CMAKE_CURRENT_SOURCE_DIR}/target/$,release,debug>/) + add_library(mission_rust INTERFACE) add_dependencies(mission_rust mission_rust_internal) diff --git a/mission_rust/src/fsrc/dh/debug.rs b/mission_rust/src/fsrc/dh/debug.rs index 1a6cad4..e3fc558 100644 --- a/mission_rust/src/fsrc/dh/debug.rs +++ b/mission_rust/src/fsrc/dh/debug.rs @@ -15,6 +15,7 @@ use crate::{ #[derive(Debug)] pub enum Error { IoError(osal::io::Error), + ToDo } impl From for Error { diff --git a/mission_rust/src/fsrc/osal/ffi.rs b/mission_rust/src/fsrc/osal/ffi.rs index 3533645..3c54ef4 100644 --- a/mission_rust/src/fsrc/osal/ffi.rs +++ b/mission_rust/src/fsrc/osal/ffi.rs @@ -1,5 +1,5 @@ // TODO verify uXX == uintXX_t -// TODO track current state of usize == size_t (needed for some) +// TODO Document size_t != usize problems better type TaskFunction = unsafe extern "C" fn(*mut core::ffi::c_void) -> !; pub struct Sizes {} @@ -99,7 +99,7 @@ extern "C" { /// Harware Abstraction API in common/include/interfaces.h /// Used for access to peripherals to make switching between linux and embedded easier //int hw_device_open(const char * path, size_t path_len); - pub fn hw_device_open(path: *const core::ffi::c_char, path_len: usize) -> core::ffi::c_int; + pub fn hw_device_open(path: *const core::ffi::c_char, path_len: core::ffi::c_size_t) -> core::ffi::c_int; } //////////////////////// /// libc API (read/write/etc) diff --git a/mission_rust/src/fsrc/osal/io.rs b/mission_rust/src/fsrc/osal/io.rs index 4f03438..55eb070 100644 --- a/mission_rust/src/fsrc/osal/io.rs +++ b/mission_rust/src/fsrc/osal/io.rs @@ -22,7 +22,6 @@ impl Display for Error { } } - pub type Result = core::result::Result; pub trait Read { @@ -41,11 +40,16 @@ pub struct HardwareInterface { impl HardwareInterface { pub fn new(path: &str) -> Result { // Safe: we trust our own implementation to only read - // as we cut our string into bytes, conversion to c_char is correct, as C will compare bit value + // as we cut our string into bytes, conversion to c_char is correct, C will compare bit value + #[allow(irrefutable_let_patterns)] + // is refutable on some exotic targets. If you wanna have fun: https://internals.rust-lang.org/t/pre-rfc-usize-is-not-size-t/15369 + let Ok(len_converted) = path.as_bytes().len().try_into() else { + panic!(); // TODO Abort + }; let fd = unsafe { crate::osal::ffi::hw_device_open( path.as_bytes().as_ptr() as *const core::ffi::c_char, - path.as_bytes().len(), + len_converted, ) }; if fd >= 0 { @@ -60,10 +64,10 @@ impl HardwareInterface { impl Write for HardwareInterface { fn write(&mut self, data: &[u8]) -> Result<()> { - #[allow(irrefutable_let_patterns)] // is refutable on some targets - let Ok(len_converted) = data.len().try_into() else { - return Err(Error::Os(OsError::NumericalResultOutOfRange)); - }; + #[allow(irrefutable_let_patterns)] // is refutable on some exotic targets. See above + let Ok(len_converted) = data.len().try_into() else { + return Err(Error::Os(OsError::NumericalResultOutOfRange)); + }; let written = unsafe { ffi::write( self.fd, @@ -95,7 +99,7 @@ impl Read for HardwareInterface { let read = unsafe { #[allow(irrefutable_let_patterns)] // is refutable on some targets let Ok(len_converted) = buffer.len().try_into() else { - return Err(Error::Os(OsError::NumericalResultOutOfRange)) + return Err(Error::Os(OsError::NumericalResultOutOfRange)); }; ffi::read( self.fd, diff --git a/mission_rust/src/fsrc/sif.rs b/mission_rust/src/fsrc/sif.rs index 8d9074e..3c5e46d 100644 --- a/mission_rust/src/fsrc/sif.rs +++ b/mission_rust/src/fsrc/sif.rs @@ -6,74 +6,62 @@ pub struct Stderr {} // TODO why or how does pub work (users from same crate need to use core::fmt::... ) pub use core::fmt::{Error, Write}; -// TODO this is already in osal -// 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> { - - // Safe because write will only read the pointer an then return - // try_into is used as write call is different depending on platform - let len_converted = match s.as_bytes().len().try_into(){ - Ok(value) => value, - Err(_) => return Err(Error) + #[allow(irrefutable_let_patterns)] // is refutable on some exotic targets. See above + let Ok(len_converted) = s.as_bytes().len().try_into() else { + return Err(Error); }; - let result = unsafe { - crate::fsrc::osal::ffi::write( + // Safe because write will only read the pointer an then return + let written = unsafe { + crate::fsrc::osal::ffi::write( 1, s.as_bytes().as_ptr() as *const core::ffi::c_void, len_converted, ) }; - // We do not retry incomplete writes, this is stdout after all... - let safe_count = match s.as_bytes().len().try_into() { - Ok(count)=> count, - Err(_) => return Err(Error) + let Ok(written_unsigned): Result = written.try_into() else { + return Err(Error); }; - if result < safe_count { - Err(Error) + if written_unsigned < s.as_bytes().len() { + return Err(Error); } else { - Ok(()) + return 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 - // try_into is used as write call is different depending on platform - let len_converted = match s.as_bytes().len().try_into(){ - Ok(value) => value, - Err(_) => return Err(Error) + #[allow(irrefutable_let_patterns)] // is refutable on some exotic targets. See above + let Ok(len_converted) = s.as_bytes().len().try_into() else { + return Err(Error); }; - let result = unsafe { - crate::fsrc::osal::ffi::write( - 1, + // Safe because write will only read the pointer an then return + let written = unsafe { + crate::fsrc::osal::ffi::write( + 2, s.as_bytes().as_ptr() as *const core::ffi::c_void, len_converted, ) }; - // We do not retry incomplete writes, this is stdout after all... - let safe_count = match s.as_bytes().len().try_into() { - Ok(count)=> count, - Err(_) => return Err(Error) + let Ok(written_unsigned): Result = written.try_into() else { + return Err(Error); }; - if result < safe_count { - Err(Error) + if written_unsigned < s.as_bytes().len() { + return Err(Error); } else { - Ok(()) + return Ok(()); } } } +// TODO I am not sure if crate::fsrc::sif::Stdout is the correct way here #[macro_export] macro_rules! sifln { ($(,)?) => ( - //let mut stdout = Outbytes {}; - writeln!(Stdout {}); + {let _alwaysok = writeln!(crate::fsrc::sif::Stdout {});} ); ($($arg:tt)*) => ( {let _alwaysok = writeln!(crate::fsrc::sif::Stdout {}, $($arg)*);} @@ -82,6 +70,9 @@ macro_rules! sifln { #[macro_export] macro_rules! sif { + ($(,)?) => ( + {let _alwaysok = writeln!(crate::fsrc::sif::Stdout {});} + ); ($($arg:tt)*) => ( let _alwaysok = write!(crate::fsrc::sif::Stdout {}, $($arg)*); ); diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 1b63256..f05e40c 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -186,17 +186,9 @@ static THREAD_3: StaticReadOnceLock< Duration::from_millis(200), )); -extern "C" { - fn done() -> !; -} - fn init_task() -> ! { sifln!("Mission enter"); - // unsafe{done()}; - - // panic!("Oh no!"); - let commands = [dh::Command(0), dh::Command(1), dh::Command(2)]; let mut debugger = DeviceHandlerDebugger::new( EchoHandler { buffer: [0; 10] }, @@ -207,13 +199,7 @@ fn init_task() -> ! { 0.5, ); - let result = debugger.run(); - if let Err(e) = result { - sifln!("{e}"); - panic!(""); - } - - panic!("done"); + debugger.run().unwrap(); let test1 = TEST1.take().unwrap(); let test2 = TEST2.take().unwrap();