forked from ROMEO/fsw-ws
big box of fixes and cleanup
This commit is contained in:
+2
-2
@@ -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})
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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,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})
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -15,6 +15,7 @@ use crate::{
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
IoError(osal::io::Error),
|
||||
ToDo
|
||||
}
|
||||
|
||||
impl From<osal::io::Error> for Error {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user