From 02a7d525be572bd8599966a5d6606f35d272d5c2 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Tue, 16 Jul 2024 14:12:15 +0200 Subject: [PATCH 1/4] Using write() for output for better portability --- bsp_linux/main.c | 11 +-- bsp_z7/CMakeLists.txt | 1 + bsp_z7/newlib/CMakeLists.txt | 1 + bsp_z7/newlib/write.c | 15 +++++ .../libsrc/standalone/CMakeLists.txt | 2 +- mission_rust/src/fsrc/sif.rs | 67 +++++++++++++++---- mission_rust/src/lib.rs | 14 ++-- 7 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 bsp_z7/newlib/CMakeLists.txt create mode 100644 bsp_z7/newlib/write.c diff --git a/bsp_linux/main.c b/bsp_linux/main.c index d884385..f56f989 100644 --- a/bsp_linux/main.c +++ b/bsp_linux/main.c @@ -2,10 +2,12 @@ #include #include +#include + 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; } \ No newline at end of file diff --git a/bsp_z7/CMakeLists.txt b/bsp_z7/CMakeLists.txt index 732ad32..d5d3e3d 100644 --- a/bsp_z7/CMakeLists.txt +++ b/bsp_z7/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(freeRTOS) add_subdirectory(ps7_cortexa9_0) +add_subdirectory(newlib) target_sources(${TARGET_NAME} PRIVATE main.c) \ No newline at end of file diff --git a/bsp_z7/newlib/CMakeLists.txt b/bsp_z7/newlib/CMakeLists.txt new file mode 100644 index 0000000..09d4bd8 --- /dev/null +++ b/bsp_z7/newlib/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${TARGET_NAME} PRIVATE write.c) \ No newline at end of file diff --git a/bsp_z7/newlib/write.c b/bsp_z7/newlib/write.c new file mode 100644 index 0000000..365fb29 --- /dev/null +++ b/bsp_z7/newlib/write.c @@ -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; +} \ No newline at end of file diff --git a/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt b/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt index 416de1f..bfb6e99 100644 --- a/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt +++ b/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt @@ -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 diff --git a/mission_rust/src/fsrc/sif.rs b/mission_rust/src/fsrc/sif.rs index f56438b..ec31dc1 100644 --- a/mission_rust/src/fsrc/sif.rs +++ b/mission_rust/src/fsrc/sif.rs @@ -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)*); ); } - diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 8ebd689..6ce067a 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -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� Encoding"); + _ = writeln!(crate::fsrc::sif::Stderr {},"Schei� 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] From 49c19ba6753c06caafee73ef68ec74279cdece17 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Tue, 16 Jul 2024 23:11:38 +0200 Subject: [PATCH 2/4] procmac to not forget writing open calls --- bsp_linux/main.c | 7 ++-- mission_rust/Cargo.lock | 34 ++++++++++++++++++ mission_rust/Cargo.toml | 3 +- mission_rust/descriptor_procmac/Cargo.toml | 10 ++++++ mission_rust/descriptor_procmac/src/lib.rs | 41 ++++++++++++++++++++++ mission_rust/src/lib.rs | 11 ++++++ 6 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 mission_rust/descriptor_procmac/Cargo.toml create mode 100644 mission_rust/descriptor_procmac/src/lib.rs diff --git a/bsp_linux/main.c b/bsp_linux/main.c index f56f989..2d8ba34 100644 --- a/bsp_linux/main.c +++ b/bsp_linux/main.c @@ -6,6 +6,10 @@ void mission(void); +int get_descriptor_rw() { + return 1; +} + void done() { printf("done.\n"); exit(0); @@ -18,9 +22,6 @@ void rust_eh_personality() { } int main(void) { - printf("std %i sterr %i\n", stdout, stderr); - const char * buffer ="123"; - write(STDOUT_FILENO, buffer, 3); mission(); return 0; } \ No newline at end of file diff --git a/mission_rust/Cargo.lock b/mission_rust/Cargo.lock index c0a15a2..3d7ef28 100644 --- a/mission_rust/Cargo.lock +++ b/mission_rust/Cargo.lock @@ -2,6 +2,40 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "descriptor_procmac" +version = "0.1.0" +dependencies = [ + "quote", +] + [[package]] name = "mission_rust" version = "0.1.0" +dependencies = [ + "descriptor_procmac", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/mission_rust/Cargo.toml b/mission_rust/Cargo.toml index d39fbfe..8dc6e3d 100644 --- a/mission_rust/Cargo.toml +++ b/mission_rust/Cargo.toml @@ -12,6 +12,5 @@ panic = 'abort' [profile.release] panic = 'abort' -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +descriptor_procmac = { path = "./descriptor_procmac" } \ No newline at end of file diff --git a/mission_rust/descriptor_procmac/Cargo.toml b/mission_rust/descriptor_procmac/Cargo.toml new file mode 100644 index 0000000..24704c8 --- /dev/null +++ b/mission_rust/descriptor_procmac/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "descriptor_procmac" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0" \ No newline at end of file diff --git a/mission_rust/descriptor_procmac/src/lib.rs b/mission_rust/descriptor_procmac/src/lib.rs new file mode 100644 index 0000000..b04c0b5 --- /dev/null +++ b/mission_rust/descriptor_procmac/src/lib.rs @@ -0,0 +1,41 @@ +#![crate_type = "proc-macro"] +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn Device_Descriptor(input: TokenStream) -> TokenStream { + let first_token = input.into_iter().next().unwrap(); // Do proper error handling! + let raw_string = first_token.to_string(); + let raw_string_len = raw_string.len(); + let identifier = &first_token.to_string()[1..raw_string_len-1]; + println!("first: {}", identifier); + // let value = match first_token { + // Literal { symbol, kind: Str, ..} => {println!("yes: {}", symbol); "12"}, + // _ => "13", + // }; + // let string_value = match litrs::StringLit::try_from(first_token) { + // Ok(string_lit) => string_lit, + // Err(e) => return e.to_compile_error(), + // }; + let getter_name = quote::format_ident!("get_descriptor_{}", identifier); + let struct_name = quote::format_ident!("Descriptor_{}", identifier); + let tokens = quote::quote!( + extern "C" { + pub fn #getter_name() -> core::ffi::c_int; + pub fn write(fd: core::ffi::c_int, buffer: *const core::ffi::c_void, count: usize) -> core::ffi::c_int; + } + + struct #struct_name {} + + impl Hardware_Write for #struct_name { + fn write(&mut self, buf: &[u8]) -> Result{ + unsafe { + let fd = #getter_name( ); + let written = write(fd, buf.as_ptr() as *const core::ffi::c_void, buf.len()); + Ok(written) + } + } + } + ); + tokens.into() +} diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 6ce067a..ee59741 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -11,6 +11,14 @@ use core::panic::PanicInfo; use fsrc::objectmanager::SystemObjectIF; use fsrc::*; +use descriptor_procmac::Device_Descriptor; + +trait Hardware_Write { + fn write(&mut self, buf: &[u8]) -> Result; +} + +Device_Descriptor!("rw"); + extern "C" { fn done(); } @@ -70,6 +78,9 @@ extern "C" fn rust_alloc_failed(){ #[no_mangle] extern "C" fn rust_main() { sifln!("Rust startup 🚀"); + let mut rw = Descriptor_rw{}; + let data: &[u8] = &[0x30,0x31,10]; + _ = rw.write(data); mission(); sifln!("Mission done"); } From cbe8184fab31101976fbbd1e340fe9962794100d Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Sat, 20 Jul 2024 00:27:24 +0200 Subject: [PATCH 3/4] portable device access api based on unix file descriptors --- bsp_linux/CMakeLists.txt | 2 + bsp_linux/hardware/CMakeLists.txt | 1 + bsp_linux/hardware/hardware.c | 28 +++++++++ bsp_linux/main.c | 47 +++++++++++---- bsp_z7/CMakeLists.txt | 3 +- bsp_z7/hardware/CMakeLists.txt | 1 + bsp_z7/hardware/interface_access.h | 5 ++ bsp_z7/hardware/interface_fds.h | 7 +++ bsp_z7/hardware/interfaces.c | 70 ++++++++++++++++++++++ bsp_z7/main.c | 4 ++ bsp_z7/newlib/CMakeLists.txt | 2 +- bsp_z7/newlib/close.c | 0 bsp_z7/newlib/read.c | 5 ++ bsp_z7/newlib/write.c | 40 ++++++++++--- common/CMakeLists.txt | 4 +- common/include/hardware/interfaces.h | 37 ++++++++++++ common/printChar.c | 10 ---- mission/mission.c | 7 +++ mission_rust/Cargo.lock | 34 ----------- mission_rust/Cargo.toml | 5 +- mission_rust/descriptor_procmac/Cargo.toml | 10 ---- mission_rust/descriptor_procmac/src/lib.rs | 41 ------------- mission_rust/src/lib.rs | 11 ---- 23 files changed, 241 insertions(+), 133 deletions(-) create mode 100644 bsp_linux/hardware/CMakeLists.txt create mode 100644 bsp_linux/hardware/hardware.c create mode 100644 bsp_z7/hardware/CMakeLists.txt create mode 100644 bsp_z7/hardware/interface_access.h create mode 100644 bsp_z7/hardware/interface_fds.h create mode 100644 bsp_z7/hardware/interfaces.c create mode 100644 bsp_z7/newlib/close.c create mode 100644 bsp_z7/newlib/read.c create mode 100644 common/include/hardware/interfaces.h delete mode 100644 common/printChar.c delete mode 100644 mission_rust/descriptor_procmac/Cargo.toml delete mode 100644 mission_rust/descriptor_procmac/src/lib.rs diff --git a/bsp_linux/CMakeLists.txt b/bsp_linux/CMakeLists.txt index 43c1760..86fefb8 100644 --- a/bsp_linux/CMakeLists.txt +++ b/bsp_linux/CMakeLists.txt @@ -1 +1,3 @@ +add_subdirectory(hardware) + target_sources(${TARGET_NAME} PRIVATE main.c) \ No newline at end of file diff --git a/bsp_linux/hardware/CMakeLists.txt b/bsp_linux/hardware/CMakeLists.txt new file mode 100644 index 0000000..8ca523c --- /dev/null +++ b/bsp_linux/hardware/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${TARGET_NAME} PRIVATE hardware.c) \ No newline at end of file diff --git a/bsp_linux/hardware/hardware.c b/bsp_linux/hardware/hardware.c new file mode 100644 index 0000000..973dcd6 --- /dev/null +++ b/bsp_linux/hardware/hardware.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +extern const char *device_root; + +int hw_device_open(const char *path, size_t path_len) { + int sock; + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + perror(NULL); + exit(-1); + } + struct sockaddr_un address; + address.sun_family = AF_UNIX; + snprintf(address.sun_path, sizeof(address.sun_path), "%s%.*s", device_root, + path_len, path); + if (connect(sock, (struct sockaddr *)&address, sizeof(address)) != 0) { + perror(NULL); + exit(-1); + } + return sock; +} \ No newline at end of file diff --git a/bsp_linux/main.c b/bsp_linux/main.c index 2d8ba34..4b81135 100644 --- a/bsp_linux/main.c +++ b/bsp_linux/main.c @@ -1,27 +1,52 @@ -#include +#include +#include #include +#include #include - +#include +#include +#include #include +const char *device_root = "./"; + void mission(void); -int get_descriptor_rw() { - return 1; -} +int get_descriptor_rw() { return 1; } void done() { printf("done.\n"); exit(0); } +int test_socket(); + // Don't ask me, it makes the linker happy and does not seem // to break anything ¯\_(ツ)_/¯ -void rust_eh_personality() { - puts("eh_personality"); -} +void rust_eh_personality() { puts("eh_personality"); } -int main(void) { - mission(); - return 0; +int main(int argc, char **argv) { + static struct option long_options[] = { + /* NAME ARGUMENT FLAG SHORTNAME */ + {"device-root", required_argument, NULL, 'd'}, + {"help", no_argument, NULL, 'h'}, + {NULL, 0, NULL, 0}}; + int c; + int option_index = 0; + while ((c = getopt_long(argc, argv, "hd:", long_options, &option_index)) != + -1) { + switch (c) { + case 'd': + if (optarg != NULL) { + device_root = optarg; + break; + default: + fprintf(stderr, "Usage: %s -d device-root\n", argv[0]); + exit(EXIT_FAILURE); + } + } + } + + mission(); + return 0; } \ No newline at end of file diff --git a/bsp_z7/CMakeLists.txt b/bsp_z7/CMakeLists.txt index d5d3e3d..c3ab00e 100644 --- a/bsp_z7/CMakeLists.txt +++ b/bsp_z7/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(freeRTOS) add_subdirectory(ps7_cortexa9_0) add_subdirectory(newlib) +add_subdirectory(hardware) -target_sources(${TARGET_NAME} PRIVATE main.c) \ No newline at end of file +target_sources(${TARGET_NAME} PRIVATE main.c) diff --git a/bsp_z7/hardware/CMakeLists.txt b/bsp_z7/hardware/CMakeLists.txt new file mode 100644 index 0000000..e3fa27e --- /dev/null +++ b/bsp_z7/hardware/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(${TARGET_NAME} PRIVATE interfaces.c) \ No newline at end of file diff --git a/bsp_z7/hardware/interface_access.h b/bsp_z7/hardware/interface_access.h new file mode 100644 index 0000000..5578958 --- /dev/null +++ b/bsp_z7/hardware/interface_access.h @@ -0,0 +1,5 @@ +#pragma once + +int hw_interface_write(int fd, const char *ptr, int len); + +int hw_interface_read(int fd, char *ptr, int len); \ No newline at end of file diff --git a/bsp_z7/hardware/interface_fds.h b/bsp_z7/hardware/interface_fds.h new file mode 100644 index 0000000..d0ff4a9 --- /dev/null +++ b/bsp_z7/hardware/interface_fds.h @@ -0,0 +1,7 @@ +#pragma once + +enum InterfaceFileDescriptors { + UART_0 = 3, + UART_1, + INTERFACE_FDS_NEXT +}; \ No newline at end of file diff --git a/bsp_z7/hardware/interfaces.c b/bsp_z7/hardware/interfaces.c new file mode 100644 index 0000000..c067f78 --- /dev/null +++ b/bsp_z7/hardware/interfaces.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include + +#include "interface_access.h" +#include "interface_fds.h" + +int compare_string_chars(const char *c_string, const char *chars, + size_t chars_len) { + for(int i = 0; i < chars_len; i++) { + if (c_string[i] == 0) { + return 0; + } + if (c_string[i] != chars[i]) {; + return 0; + } + } + return 1; +} + +int hw_device_open(const char *path, size_t path_len) { + if (compare_string_chars("uart0", path, path_len) == 1) { + return UART_0; + } + if (compare_string_chars("uart1", path, path_len) == 1) { + return UART_1; + } + + return -1; +} + +ssize_t hw_device_transfer(int fd, void *sendbuffer, void *receivebuffer, + size_t buffer_len) { + return -1; +} + +// 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 send_uart(uint32_t BaseAddress, const char *data, int 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) { + enum InterfaceFileDescriptors fd_enum = fd; + switch (fd) { + case UART_0: + send_uart(XPS_UART0_BASEADDR, ptr, len); + return len; + case UART_1: + send_uart(XPS_UART1_BASEADDR, ptr, len); + return len; + } + return -1; +} + +int hw_interface_read(int fd, char *ptr, int len) { + enum InterfaceFileDescriptors fd_enum = fd; + switch (fd) { + case UART_0: + return 0; + case UART_1: + return 0; + } + return -1; +} \ No newline at end of file diff --git a/bsp_z7/main.c b/bsp_z7/main.c index 0dbb160..39cf8d6 100644 --- a/bsp_z7/main.c +++ b/bsp_z7/main.c @@ -47,6 +47,10 @@ XScuGic xInterruptController; extern SemaphoreHandle_t malloc_mutex; +int get_descriptor_rw() { + return 1; +} + /*-----------------------------------------------------------*/ void mission(void); diff --git a/bsp_z7/newlib/CMakeLists.txt b/bsp_z7/newlib/CMakeLists.txt index 09d4bd8..d8479a2 100644 --- a/bsp_z7/newlib/CMakeLists.txt +++ b/bsp_z7/newlib/CMakeLists.txt @@ -1 +1 @@ -target_sources(${TARGET_NAME} PRIVATE write.c) \ No newline at end of file +target_sources(${TARGET_NAME} PRIVATE close.c read.c write.c) \ No newline at end of file diff --git a/bsp_z7/newlib/close.c b/bsp_z7/newlib/close.c new file mode 100644 index 0000000..e69de29 diff --git a/bsp_z7/newlib/read.c b/bsp_z7/newlib/read.c new file mode 100644 index 0000000..f0538ce --- /dev/null +++ b/bsp_z7/newlib/read.c @@ -0,0 +1,5 @@ + + +int _read(int file, char *ptr, int len) { + return 0; +} \ No newline at end of file diff --git a/bsp_z7/newlib/write.c b/bsp_z7/newlib/write.c index 365fb29..8d76e1b 100644 --- a/bsp_z7/newlib/write.c +++ b/bsp_z7/newlib/write.c @@ -1,15 +1,41 @@ #include "xil_printf.h" #include "xparameters.h" -int write(int file, char *ptr, int len) { +#include "../hardware/interface_access.h" +#include "../hardware/interface_fds.h" + + +// newlib offers a (weak) write implementation which +// is reentrant by calling _write_r which in turn +// relies on _write which we implement here. +// This way, we get a global, reentrant write implementation +// NOTE: This might be architecture dependent, so check your +// newlib implementation! +int _write(int fd, const char *ptr, int len) { if (ptr == NULL) { return 0; } - // TODO file descriptors - int todo; - - for (todo = 0; todo < len; todo++) { - outbyte(*ptr++); + + // 0 is stdin, do not write to it + if (fd < 1) { + return -1; // TODO error } - return len; + // we only support a single debug UART, so + // stdout and stderr are the same and go to the xiling stdout UART + // TODO switch to a hw_interface_write() instead? + if (fd < 3) { + int todo; + + for (todo = 0; todo < len; todo++) { + outbyte(*ptr++); + } + return len; + } + + if (fd < INTERFACE_FDS_NEXT) { + return hw_interface_write(fd, ptr, len); + } + + // we do not have dynamic fds, so fd is invalid + return -1; } \ No newline at end of file diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index f513753..e76b650 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,3 +1 @@ -target_sources( - ${TARGET_NAME} PRIVATE - printChar.c) \ No newline at end of file +target_include_directories(${TARGET_NAME} PRIVATE include) \ No newline at end of file diff --git a/common/include/hardware/interfaces.h b/common/include/hardware/interfaces.h new file mode 100644 index 0000000..c01f920 --- /dev/null +++ b/common/include/hardware/interfaces.h @@ -0,0 +1,37 @@ +#pragma once + +#include +#include + +/** + * Access to hardware interfaces local to the machine the code is running on. + * + * The file descriptor returned by hw_decvice_open() is to be used by the standard + * read/write calls and to be closed by close(). + * + * For some specific hardware interfaces specific transactional calls are provided here + * to increase realtime performance. + * + * So far the only example is an SPI interface, which performs synchronous transfers of + * n bytes in, n bytes out. If a write call is performed on such an interface, the number + * of bytes transfered equals the size of the hardware send buffer. For a read() call, the + * bytes contained in the hardware's receive buffer are returned. + */ + +/** + * open a hardware device + * + * if successful, returns a file descriptor to be used with read/write/transfer/close calls + * otherwise returns -1 + */ +int hw_device_open(const char * path, size_t path_len); + +/** + * Perform a transfer of buffer_len bytes in and out. + * + * sendbuffer and receivebuffer may be equal, where received bytes overwrite + * send bytes. + * + * returns actual number of bytes transfered + */ +ssize_t hw_device_transfer(int fd, void* sendbuffer, void* receivebuffer, size_t buffer_len); \ No newline at end of file diff --git a/common/printChar.c b/common/printChar.c deleted file mode 100644 index d5cc34c..0000000 --- a/common/printChar.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -void printChar(const char* character, bool errStream) { - if (errStream) { - fprintf(stderr, "%c", *character); - } else { - printf("%c", *character); - } -} diff --git a/mission/mission.c b/mission/mission.c index bfb0a3b..5e404b7 100644 --- a/mission/mission.c +++ b/mission/mission.c @@ -25,7 +25,14 @@ void init_task(void *) { vTaskDelete(NULL); } +#include +#include + void mission(void) { + int fd0 = hw_device_open("uart0", 5); + write(fd0, "uart0\n", 6); + int fd1 = hw_device_open("uart1", 5); + write(fd1, "uart1\n", 6); int taskParameters = 0; diff --git a/mission_rust/Cargo.lock b/mission_rust/Cargo.lock index 3d7ef28..c0a15a2 100644 --- a/mission_rust/Cargo.lock +++ b/mission_rust/Cargo.lock @@ -2,40 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "descriptor_procmac" -version = "0.1.0" -dependencies = [ - "quote", -] - [[package]] name = "mission_rust" version = "0.1.0" -dependencies = [ - "descriptor_procmac", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" diff --git a/mission_rust/Cargo.toml b/mission_rust/Cargo.toml index 8dc6e3d..78f6b6b 100644 --- a/mission_rust/Cargo.toml +++ b/mission_rust/Cargo.toml @@ -10,7 +10,4 @@ crate-type = ["staticlib"] panic = 'abort' [profile.release] -panic = 'abort' - -[dependencies] -descriptor_procmac = { path = "./descriptor_procmac" } \ No newline at end of file +panic = 'abort' \ No newline at end of file diff --git a/mission_rust/descriptor_procmac/Cargo.toml b/mission_rust/descriptor_procmac/Cargo.toml deleted file mode 100644 index 24704c8..0000000 --- a/mission_rust/descriptor_procmac/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "descriptor_procmac" -version = "0.1.0" -edition = "2021" - -[lib] -proc-macro = true - -[dependencies] -quote = "1.0" \ No newline at end of file diff --git a/mission_rust/descriptor_procmac/src/lib.rs b/mission_rust/descriptor_procmac/src/lib.rs deleted file mode 100644 index b04c0b5..0000000 --- a/mission_rust/descriptor_procmac/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![crate_type = "proc-macro"] -extern crate proc_macro; -use proc_macro::TokenStream; - -#[proc_macro] -pub fn Device_Descriptor(input: TokenStream) -> TokenStream { - let first_token = input.into_iter().next().unwrap(); // Do proper error handling! - let raw_string = first_token.to_string(); - let raw_string_len = raw_string.len(); - let identifier = &first_token.to_string()[1..raw_string_len-1]; - println!("first: {}", identifier); - // let value = match first_token { - // Literal { symbol, kind: Str, ..} => {println!("yes: {}", symbol); "12"}, - // _ => "13", - // }; - // let string_value = match litrs::StringLit::try_from(first_token) { - // Ok(string_lit) => string_lit, - // Err(e) => return e.to_compile_error(), - // }; - let getter_name = quote::format_ident!("get_descriptor_{}", identifier); - let struct_name = quote::format_ident!("Descriptor_{}", identifier); - let tokens = quote::quote!( - extern "C" { - pub fn #getter_name() -> core::ffi::c_int; - pub fn write(fd: core::ffi::c_int, buffer: *const core::ffi::c_void, count: usize) -> core::ffi::c_int; - } - - struct #struct_name {} - - impl Hardware_Write for #struct_name { - fn write(&mut self, buf: &[u8]) -> Result{ - unsafe { - let fd = #getter_name( ); - let written = write(fd, buf.as_ptr() as *const core::ffi::c_void, buf.len()); - Ok(written) - } - } - } - ); - tokens.into() -} diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index ee59741..6ce067a 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -11,14 +11,6 @@ use core::panic::PanicInfo; use fsrc::objectmanager::SystemObjectIF; use fsrc::*; -use descriptor_procmac::Device_Descriptor; - -trait Hardware_Write { - fn write(&mut self, buf: &[u8]) -> Result; -} - -Device_Descriptor!("rw"); - extern "C" { fn done(); } @@ -78,9 +70,6 @@ extern "C" fn rust_alloc_failed(){ #[no_mangle] extern "C" fn rust_main() { sifln!("Rust startup 🚀"); - let mut rw = Descriptor_rw{}; - let data: &[u8] = &[0x30,0x31,10]; - _ = rw.write(data); mission(); sifln!("Mission done"); } From 926ef2600027706a5a2cbcf0a876e58dae9cc6a2 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Tue, 23 Jul 2024 17:08:11 +0200 Subject: [PATCH 4/4] z7 uart0 buffered read --- bsp_z7/freeRTOS/FreeRTOSConfig.h | 2 +- bsp_z7/hardware/CMakeLists.txt | 2 +- bsp_z7/hardware/interfaces.c | 11 +- bsp_z7/hardware/uart.c | 91 +++++++++++++++ bsp_z7/hardware/uart.h | 4 + bsp_z7/newlib/read.c | 33 +++++- bsp_z7/newlib/write.c | 2 +- .../libsrc/standalone/CMakeLists.txt | 4 +- bsp_z7/testIp.c | 110 +++++++++--------- mission/mission.c | 27 ++++- 10 files changed, 214 insertions(+), 72 deletions(-) create mode 100644 bsp_z7/hardware/uart.c create mode 100644 bsp_z7/hardware/uart.h diff --git a/bsp_z7/freeRTOS/FreeRTOSConfig.h b/bsp_z7/freeRTOS/FreeRTOSConfig.h index e667c02..8c01db6 100644 --- a/bsp_z7/freeRTOS/FreeRTOSConfig.h +++ b/bsp_z7/freeRTOS/FreeRTOSConfig.h @@ -89,7 +89,7 @@ #define configUSE_APPLICATION_TASK_TAG 0 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_QUEUE_SETS 1 -#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_STATIC_ALLOCATION 1 #define configSUPPORT_DYNAMIC_ALLOCATION 1 /* Include the query-heap CLI command to query the free heap space. */ diff --git a/bsp_z7/hardware/CMakeLists.txt b/bsp_z7/hardware/CMakeLists.txt index e3fa27e..e7befc2 100644 --- a/bsp_z7/hardware/CMakeLists.txt +++ b/bsp_z7/hardware/CMakeLists.txt @@ -1 +1 @@ -target_sources(${TARGET_NAME} PRIVATE interfaces.c) \ No newline at end of file +target_sources(${TARGET_NAME} PRIVATE interfaces.c uart.c) \ No newline at end of file diff --git a/bsp_z7/hardware/interfaces.c b/bsp_z7/hardware/interfaces.c index c067f78..165ad14 100644 --- a/bsp_z7/hardware/interfaces.c +++ b/bsp_z7/hardware/interfaces.c @@ -5,6 +5,7 @@ #include "interface_access.h" #include "interface_fds.h" +#include "uart.h" int compare_string_chars(const char *c_string, const char *chars, size_t chars_len) { @@ -19,8 +20,10 @@ int compare_string_chars(const char *c_string, const char *chars, return 1; } +//TODO no dual open int hw_device_open(const char *path, size_t path_len) { if (compare_string_chars("uart0", path, path_len) == 1) { + uart0_enable_receiver(); return UART_0; } if (compare_string_chars("uart1", path, path_len) == 1) { @@ -38,7 +41,7 @@ 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 send_uart(uint32_t BaseAddress, const char *data, int data_len) { +void uart_send(uint32_t BaseAddress, const char *data, int data_len) { int todo; for (todo = 0; todo < data_len; todo++) { XUartPs_SendByte(BaseAddress, *data++); @@ -49,10 +52,10 @@ int hw_interface_write(int fd, const char *ptr, int len) { enum InterfaceFileDescriptors fd_enum = fd; switch (fd) { case UART_0: - send_uart(XPS_UART0_BASEADDR, ptr, len); + uart_send(XPS_UART0_BASEADDR, ptr, len); return len; case UART_1: - send_uart(XPS_UART1_BASEADDR, ptr, len); + uart_send(XPS_UART1_BASEADDR, ptr, len); return len; } return -1; @@ -62,7 +65,7 @@ int hw_interface_read(int fd, char *ptr, int len) { enum InterfaceFileDescriptors fd_enum = fd; switch (fd) { case UART_0: - return 0; + return uart0_read(ptr,len); case UART_1: return 0; } diff --git a/bsp_z7/hardware/uart.c b/bsp_z7/hardware/uart.c new file mode 100644 index 0000000..bfec1f1 --- /dev/null +++ b/bsp_z7/hardware/uart.c @@ -0,0 +1,91 @@ +#include + +#include "FreeRTOS.h" +#include "queue.h" + +#include +#include + +#undef XUARTPS_IXR_RXOVR +#define XUARTPS_IXR_RXOVR 0x00000020U /**< Rx Overrun error interrupt */ +#define XUARTPS_IXR_RTRIG 0x00000001U /**< RX FIFO trigger interrupt. */ + +extern XScuGic xInterruptController; /* Interrupt controller instance */ + +uint8_t uart0_receive_buffer[1024 * 1]; +StaticQueue_t uart0_static_queue; +QueueHandle_t uart0_receive_queue; + +/** this is based on XUartPs_InterruptHandler() in xuartps_intr.c*/ +void uart0_handle_interrupt(void *) { + u32 IsrStatus; + + /* + * Read the interrupt ID register to determine which + * interrupt is active + */ + IsrStatus = XUartPs_ReadReg(XPS_UART0_BASEADDR, XUARTPS_IMR_OFFSET); + + IsrStatus &= XUartPs_ReadReg(XPS_UART0_BASEADDR, XUARTPS_ISR_OFFSET); + + // Onlx RX intterupts are enabled + // We do not care which interrupt actually triggered, just get all bytes + // available into the stack + uint8_t RecievedByte; + BaseType_t xHigherPriorityTaskWoken; + while (XUartPs_IsReceiveData(STDIN_BASEADDRESS)) { + RecievedByte = XUartPs_ReadReg(STDIN_BASEADDRESS, XUARTPS_FIFO_OFFSET); + xQueueSendToBackFromISR(uart0_receive_queue, &RecievedByte, + &xHigherPriorityTaskWoken); + } + + /* Clear the interrupt status. */ + XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_ISR_OFFSET, IsrStatus); + + /* directly yield if sending to the queue woke something in ourselves */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void uart0_enable_receiver() { + uart0_receive_queue = + xQueueCreateStatic(sizeof(uart0_receive_buffer), 1, uart0_receive_buffer, + &uart0_static_queue); + + /* Install the UART Interrupt handler. */ + BaseType_t xStatus = + XScuGic_Connect(&xInterruptController, XPAR_XUARTPS_0_INTR, + (Xil_ExceptionHandler)uart0_handle_interrupt, NULL); + configASSERT(xStatus == XST_SUCCESS); + (void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */ + + // Set trigger level to 62 of 64 bytes, giving interrupt some time to react + XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_RXWM_OFFSET, 62); + + // Setting the rx timeout to n*4 -1 bits + XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_RXTOUT_OFFSET, 50); + + // enable UART Interrupts + u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | + XUARTPS_IXR_TOUT; + /* Write the mask to the IER Register */ + XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_IER_OFFSET, mask); + /* Write the inverse of the Mask to the IDR register */ + XUartPs_WriteReg(XPS_UART0_BASEADDR, XUARTPS_IDR_OFFSET, (~mask)); + + /* Enable the interrupt for the UART0 in the interrupt controller. */ + XScuGic_Enable(&xInterruptController, XPAR_XUARTPS_0_INTR); +} + +int uart0_read(char *ptr, int len) { + int received = 0; + while (len > 0) { + BaseType_t result = xQueueReceive(uart0_receive_queue, ptr, 0); + if (result == pdFAIL) { + return received; + } + received++; + ptr++; + len--; + } + return received; +} \ No newline at end of file diff --git a/bsp_z7/hardware/uart.h b/bsp_z7/hardware/uart.h new file mode 100644 index 0000000..f1da8f7 --- /dev/null +++ b/bsp_z7/hardware/uart.h @@ -0,0 +1,4 @@ +#pragma once + +void uart0_enable_receiver(); +int uart0_read(char *ptr, int len); \ No newline at end of file diff --git a/bsp_z7/newlib/read.c b/bsp_z7/newlib/read.c index f0538ce..c76c6d9 100644 --- a/bsp_z7/newlib/read.c +++ b/bsp_z7/newlib/read.c @@ -1,5 +1,34 @@ +#include "xil_printf.h" +#include "xparameters.h" +#include "../hardware/interface_access.h" +#include "../hardware/interface_fds.h" -int _read(int file, char *ptr, int len) { - return 0; +// newlib offers a (weak) write implementation which +// is reentrant by calling _read_r which in turn +// relies on _read which we implement here. +// This way, we get a global, reentrant read implementation +// NOTE: This might be architecture dependent, so check your +// newlib implementation! +int _read(int fd, char *ptr, int len) { + if (ptr == NULL) { + return 0; + } + + // 0 is stdin, TODO: do we support it? + if (fd < 1) { + return -1; + } + + // stdout and stderr + if (fd < 3) { + return -1; + } + + if (fd < INTERFACE_FDS_NEXT) { + return hw_interface_read(fd, ptr, len); + } + + // we do not have dynamic fds, so fd is invalid + return -1; } \ No newline at end of file diff --git a/bsp_z7/newlib/write.c b/bsp_z7/newlib/write.c index 8d76e1b..e388653 100644 --- a/bsp_z7/newlib/write.c +++ b/bsp_z7/newlib/write.c @@ -22,7 +22,7 @@ int _write(int fd, const char *ptr, int len) { } // we only support a single debug UART, so // stdout and stderr are the same and go to the xiling stdout UART - // TODO switch to a hw_interface_write() instead? + // We output directely to avoid loops and allow debugging (not via a write) if (fd < 3) { int todo; diff --git a/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt b/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt index bfb6e99..daa92ab 100644 --- a/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt +++ b/bsp_z7/ps7_cortexa9_0/libsrc/standalone/CMakeLists.txt @@ -31,8 +31,8 @@ target_sources(${TARGET_NAME} PUBLIC src/getentropy.c src/xil_testmem.c src/isatty.c - src/read.c - src/inbyte.c + #src/read.c + #src/inbyte.c src/close.c src/xil_sleeptimer.c src/print.c diff --git a/bsp_z7/testIp.c b/bsp_z7/testIp.c index 250b35e..786918b 100644 --- a/bsp_z7/testIp.c +++ b/bsp_z7/testIp.c @@ -160,71 +160,71 @@ static const uint16_t stackSizeWords = 512; StaticTask_t xTaskBuffer; StackType_t xStack[512]; -// void testIp() { +void testIp() { -// uartIsrQueue = -// xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue); + uartIsrQueue = + xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue); -// lwip_init(); + lwip_init(); -// ip4_addr_t slip_addr = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 32))}, -// slip_mask = {PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0))}, -// slip_gw = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 1))}; + ip4_addr_t slip_addr = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 32))}, + slip_mask = {PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0))}, + slip_gw = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 1))}; -// netif_add(&netif, &slip_addr, &slip_mask, &slip_gw, NULL, slipif_init, -// netif_input); + netif_add(&netif, &slip_addr, &slip_mask, &slip_gw, NULL, slipif_init, + netif_input); -// netif_set_default(&netif); -// // should be done by driver, which does not do it, so we do it here -// netif_set_link_up(&netif); -// netif_set_up(&netif); + netif_set_default(&netif); + // should be done by driver, which does not do it, so we do it here + netif_set_link_up(&netif); + netif_set_up(&netif); -// udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); -// if (udpecho_raw_pcb != NULL) { -// err_t err; + udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); + if (udpecho_raw_pcb != NULL) { + err_t err; -// err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7); -// if (err == ERR_OK) { -// udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL); -// } else { -// /* TODO */ -// } -// } else { -// /* TODO */ -// } + err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7); + if (err == ERR_OK) { + udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL); + } else { + /* TODO */ + } + } else { + /* TODO */ + } -// /* Install the UART Interrupt handler. */ -// BaseType_t xStatus = -// XScuGic_Connect(&xInterruptController, STDIN_INT_NR, -// (Xil_ExceptionHandler)handleUARTInt, NULL); -// configASSERT(xStatus == XST_SUCCESS); -// (void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */ + /* Install the UART Interrupt handler. */ + BaseType_t xStatus = + XScuGic_Connect(&xInterruptController, STDIN_INT_NR, + (Xil_ExceptionHandler)handleUARTInt, NULL); + configASSERT(xStatus == XST_SUCCESS); + (void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */ -// // Set trigger level to 62 of 64 bytes, giving interrupt some time to react -// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXWM_OFFSET, 62); + // Set trigger level to 62 of 64 bytes, giving interrupt some time to react + XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXWM_OFFSET, 62); -// // Setting the rx timeout to n*4 -1 bits -// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXTOUT_OFFSET, 50); + // Setting the rx timeout to n*4 -1 bits + XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXTOUT_OFFSET, 50); -// // enable UART Interrupts -// u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | -// XUARTPS_IXR_TOUT; -// /* Write the mask to the IER Register */ -// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IER_OFFSET, mask); -// /* Write the inverse of the Mask to the IDR register */ -// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IDR_OFFSET, (~mask)); + // enable UART Interrupts + u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL | + XUARTPS_IXR_TOUT; + /* Write the mask to the IER Register */ + XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IER_OFFSET, mask); + /* Write the inverse of the Mask to the IDR register */ + XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IDR_OFFSET, (~mask)); -// /* Enable the interrupt for the UART1 in the interrupt controller. */ -// XScuGic_Enable(&xInterruptController, STDIN_INT_NR); + /* Enable the interrupt for the UART1 in the interrupt controller. */ + XScuGic_Enable(&xInterruptController, STDIN_INT_NR); -// // Start lwip task -// xTaskCreateStatic( -// lwip_main, /* The function that implements the task. */ -// "lwip", /* The text name assigned to the task - for debug -// only as it is not used by the kernel. */ -// stackSizeWords, /* The size of the stack to allocate to the task. */ -// NULL, /* The parameter passed to the task - not used in this -// simple case. */ -// 4, /* The priority assigned to the task. */ -// xStack, &xTaskBuffer); -// } \ No newline at end of file + // Start lwip task + xTaskCreateStatic( + lwip_main, /* The function that implements the task. */ + "lwip", /* The text name assigned to the task - for debug + only as it is not used by the kernel. */ + stackSizeWords, /* The size of the stack to allocate to the task. */ + NULL, /* The parameter passed to the task - not used in this + simple case. */ + 4, /* The priority assigned to the task. */ + xStack, &xTaskBuffer); +} \ No newline at end of file diff --git a/mission/mission.c b/mission/mission.c index 5e404b7..02d330e 100644 --- a/mission/mission.c +++ b/mission/mission.c @@ -9,6 +9,24 @@ void rust_main(); +#include +#include + +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); + + vTaskDelay(3000 / portTICK_PERIOD_MS); + + uint8_t buffer[100]; + 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 (either a panic or program ended) // to be implemented by bsp (do not return from it!) void done(); @@ -16,6 +34,8 @@ void done(); void init_task(void *) { // printf("Starting Mission\n"); + test_hardware(); + rust_main(); // printf("Started Tasks, deleting init task\n"); @@ -25,14 +45,9 @@ void init_task(void *) { vTaskDelete(NULL); } -#include -#include + void mission(void) { - int fd0 = hw_device_open("uart0", 5); - write(fd0, "uart0\n", 6); - int fd1 = hw_device_open("uart1", 5); - write(fd1, "uart1\n", 6); int taskParameters = 0;