big box of fixes and cleanup

This commit is contained in:
2025-11-05 18:28:35 +01:00
parent f3e17fc7a1
commit e31b632bc8
17 changed files with 77 additions and 120 deletions
+2 -2
View File
@@ -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})
-2
View File
@@ -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);
+11 -11
View File
@@ -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 <hardware/interfaces.h>
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;
}
+4 -2
View File
@@ -1,5 +1,7 @@
#pragma once
int hw_interface_write(int fd, const char *ptr, int len);
#include <stddef.h>
int hw_interface_read(int fd, char *ptr, int len);
int hw_interface_write(int fd, const char *ptr, size_t len);
int hw_interface_read(int fd, char *ptr, size_t len);
+3 -3
View File
@@ -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:
+2 -2
View File
@@ -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;
+2 -2
View File
@@ -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);
int uart1_read(char *ptr, int size_t);
+2 -1
View File
@@ -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 *****************************/
@@ -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 *****************************/
+1 -1
View File
@@ -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})
-30
View File
@@ -1,14 +1,11 @@
/* Standard includes. */
#include <limits.h>
#include <stdio.h>
/* Scheduler include files. */
#include "freeRTOS_rust_helper.h"
#include "semphr.h"
#include "task.h"
#include <hardware/interfaces.h>
#include <unistd.h>
#include <git_version.h>
@@ -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
+4 -1
View File
@@ -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}/$<IF:$<CONFIG:Release>,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/$<IF:$<CONFIG:Release>,release,debug>/)
add_library(mission_rust INTERFACE)
add_dependencies(mission_rust mission_rust_internal)
+1
View File
@@ -15,6 +15,7 @@ use crate::{
#[derive(Debug)]
pub enum Error {
IoError(osal::io::Error),
ToDo
}
impl From<osal::io::Error> for Error {
+2 -2
View File
@@ -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)
+12 -8
View File
@@ -22,7 +22,6 @@ impl Display for Error {
}
}
pub type Result<T> = core::result::Result<T, Error>;
pub trait Read {
@@ -41,11 +40,16 @@ pub struct HardwareInterface {
impl HardwareInterface {
pub fn new(path: &str) -> Result<Self> {
// 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,
+28 -37
View File
@@ -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<usize, _> = 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<usize, _> = 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)*);
);
+1 -15
View File
@@ -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();