diff --git a/CMakeLists.txt b/CMakeLists.txt index 659f195..6a61652 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,25 +3,21 @@ cmake_minimum_required(VERSION 3.13) # Project Name project(romeo-obsw C ASM) -# ############################################################################## -# Pre-Sources preparation -# ############################################################################## - - - -# Set names and variables -set(TARGET_NAME ${CMAKE_PROJECT_NAME}) - # Set path names +set(OBSW_NAME romeo-obsw) set(FreeRTOS_PATH FreeRTOS-Kernel/) -set(MISSION_PATH mission/) +# Compiler Options +set(ROMEO_Z7_COMPILE_OPTIONS -c -fmessage-length=0 -g -O0 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -ffunction-sections -fdata-sections) +set(ROMEO_LINUX_COMPILE_OPTIONS -c -fmessage-length=0 -g -O0 -ffunction-sections -fdata-sections) +set(ROMEO_Z7_LINK_OPTIONS -Wl,--cref -Wl,-Map=${OBSW_NAME}.map -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -T${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/lscript.ld -specs=${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/Xilinx.spec ) +set(ROMEO_WARNING_FLAGS + -Wall + -Wextra + -Wpedantic + -Werror) - -# ############################################################################## -# Configuration -# ############################################################################## - +# CMake options which are only available when crosscompiling if (${CMAKE_CROSSCOMPILING}) set(ZYNQ_UART UART1 CACHE STRING "Which PS UART to use for stdout") set_property(CACHE ZYNQ_UART PROPERTY STRINGS UART0 UART1) @@ -34,85 +30,95 @@ else() unset(ZYNQ_UART CACHE) endif() -# ############################################################################## -# Executable and Sources -# ############################################################################## +# Add main executable +add_executable(${OBSW_NAME}) -# Add executable -add_executable(${TARGET_NAME}) - -# lwip +# export lwip path, so the bsp can find it if(${CMAKE_CROSSCOMPILING}) set (LWIP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/lwip) endif() -# Add freeRTOS - +# Platform dependend configuration +# Includes setting the FreeRTOS port, compiler options and +# selecting the bsp if(${CMAKE_CROSSCOMPILING}) #TODO: this somewhat hardcodes zynq as the only cross target set(FREERTOS_PORT GCC_ARM_CA9 CACHE STRING "") set(FREERTOS_HEAP 1 CACHE STRING "") + + # config library for FreeRTOS add_library(freertos_config INTERFACE) + + # The config file directory target_include_directories(freertos_config SYSTEM - INTERFACE bsp_z7/freeRTOS) # The config file directory + INTERFACE bsp_z7/freeRTOS) + + # no coverage tests target_compile_definitions(freertos_config INTERFACE projCOVERAGE_TEST=0) + + # FreeRTOS config depends on bsp headers target_include_directories( freertos_config INTERFACE bsp_z7/ps7_cortexa9_0/include) - if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL armv7a-none-eabihf) - # our compiler options, will trickle down through the project - target_compile_options(freertos_config INTERFACE -c -fmessage-length=0 -g -O0 -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -ffunction-sections -fdata-sections) - else() - message(FATAL_ERROR "invalid architecture ${CMAKE_SYSTEM_PROCESSOR}") - endif() + + # Compiler options, we set them on the FreeRTOS config, will trickle down from there + target_compile_options(freertos_config INTERFACE ${ROMEO_Z7_COMPILE_OPTIONS}) + + # add the bsp add_subdirectory(bsp_z7) - target_link_options(${TARGET_NAME} PRIVATE -Wl,--cref -Wl,-Map=${TARGET_NAME}.map -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -T${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/lscript.ld -specs=${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/Xilinx.spec ) + + # Link options for cross build + target_link_options(${OBSW_NAME} PRIVATE ${ROMEO_Z7_LINK_OPTIONS}) else() + # So far, only unix port supported when not crosscompiling set(FREERTOS_PORT GCC_POSIX CACHE STRING "") + + # config library for FreeRTOS add_library(freertos_config INTERFACE) + + # The config file directory target_include_directories(freertos_config SYSTEM - INTERFACE bsp_linux/freeRTOS) # The config file directory - target_compile_options(freertos_config INTERFACE -c -fmessage-length=0 -g -O0 -ffunction-sections -fdata-sections) + INTERFACE bsp_linux/freeRTOS) + + # Compiler options, we set them on the FreeRTOS config, will trickle down from there + target_compile_options(freertos_config INTERFACE ${ROMEO_LINUX_COMPILE_OPTIONS}) + + # No coverage tests, no tracing target_compile_definitions(freertos_config INTERFACE projCOVERAGE_TEST=0 projENABLE_TRACING=0) + + # add the bsp add_subdirectory(bsp_linux) endif() + +# Add FreeRTOS add_subdirectory(${FreeRTOS_PATH}) - +# Common stuff that is not mission code, mostly code shared between bsps add_subdirectory(common) -add_subdirectory(${MISSION_PATH}) +# Mission code, in our case C glue between rust and bsp +add_subdirectory(mission) + +# The actual mission code, in rust, exported as library `mission_rust` add_subdirectory(mission_rust) +# We provide a firmware image for an interface board as part of the z7 build +# This is a second executable, excluded from `all` builds if(${CMAKE_CROSSCOMPILING}) add_subdirectory(sim_interface) endif() -# ############################################################################## -# Post-Sources preparation -# ############################################################################## +# Link all libraries into the binary +# bsp depends on FreeRTOS, so we do not need to link it again +target_link_libraries(${OBSW_NAME} PUBLIC bsp mission_rust ) -# Add libraries for all sources. -if(${CMAKE_CROSSCOMPILING}) - -endif() - -target_link_libraries(${TARGET_NAME} PUBLIC bsp mission_rust lwip ) - -# target_include_directories( -# ${TARGET_NAME} PUBLIC ${BSP_PATH}) +# Common link options +target_link_options(${OBSW_NAME} PRIVATE "-Wl,--gc-sections") -# Removed unused sections. -target_link_options(${TARGET_NAME} PRIVATE "-Wl,--gc-sections") - -if(CMAKE_VERBOSE) - message(STATUS "Warning flags: ${WARNING_FLAGS}") -endif() - -# Compile options for all sources. -target_compile_options(${TARGET_NAME} PRIVATE ${WARNING_FLAGS}) \ No newline at end of file +# Common compile options +target_compile_options(${OBSW_NAME} PRIVATE ${ROMEO_WARNING_FLAGS}) \ No newline at end of file diff --git a/bsp_linux/CMakeLists.txt b/bsp_linux/CMakeLists.txt index 86fefb8..c5bba34 100644 --- a/bsp_linux/CMakeLists.txt +++ b/bsp_linux/CMakeLists.txt @@ -1,3 +1,8 @@ +add_library(bsp STATIC) + add_subdirectory(hardware) -target_sources(${TARGET_NAME} PRIVATE main.c) \ No newline at end of file +target_sources(bsp PRIVATE main.c) + +# bsp depends on FreeRTOS +target_link_libraries(bsp PUBLIC freertos_kernel) \ No newline at end of file diff --git a/bsp_linux/hardware/CMakeLists.txt b/bsp_linux/hardware/CMakeLists.txt index 8ca523c..794e7de 100644 --- a/bsp_linux/hardware/CMakeLists.txt +++ b/bsp_linux/hardware/CMakeLists.txt @@ -1 +1 @@ -target_sources(${TARGET_NAME} PRIVATE hardware.c) \ No newline at end of file +target_sources(bsp PRIVATE hardware.c) \ No newline at end of file diff --git a/bsp_z7/CMakeLists.txt b/bsp_z7/CMakeLists.txt index 470eb1d..8ff73be 100644 --- a/bsp_z7/CMakeLists.txt +++ b/bsp_z7/CMakeLists.txt @@ -1,14 +1,23 @@ +# export all code as a static library add_library(bsp) +# Add code to the bsp add_subdirectory(freeRTOS) add_subdirectory(ps7_cortexa9_0) -add_subdirectory(lwip) add_subdirectory(newlib) add_subdirectory(hardware) +# this exports two libraries +# `lwip` for embedded use +# `lwip_xil` to use the ps eth +# the subdirectory contains mostly configuration code +# actual lwip is at ${LWIP_DIR}, to be set in main CMakeLists.txt +add_subdirectory(lwip) + target_sources(bsp PRIVATE main.c) +# bsp depends on FreeRTOS target_link_libraries(bsp PUBLIC freertos_kernel) -#target_sources(${TARGET_NAME} PRIVATE testEth.c) - +# export lwip as part of bsp +target_link_libraries(bsp INTERFACE lwip) \ No newline at end of file diff --git a/bsp_z7/lwip/CMakeLists.txt b/bsp_z7/lwip/CMakeLists.txt index 5f7075c..38ad16b 100644 --- a/bsp_z7/lwip/CMakeLists.txt +++ b/bsp_z7/lwip/CMakeLists.txt @@ -1,3 +1,4 @@ +# LWIP_DIR should point to the lwip source, to be set in main CMakeLists.txt include(${LWIP_DIR}/src/Filelists.cmake) diff --git a/bsp_z7/main.c b/bsp_z7/main.c index e5bedae..7b00dc3 100644 --- a/bsp_z7/main.c +++ b/bsp_z7/main.c @@ -58,13 +58,9 @@ void initFreeRTOSHelper(); int main(void) { - /* Configure the hardware ready to run the demo. */ + /* Configure the hardware ready to run. */ prvSetupHardware(); - // printf("Booting Software\n"); - - //testEth(); - mission(); } @@ -95,20 +91,12 @@ static void prvSetupHardware(void) { configASSERT(xStatus == XST_SUCCESS); (void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */ - /* Initialise the LED port. */ - // vParTestInitialise(); - + // TODO we can alter the startup code... /* The Xilinx projects use a BSP that do not allow the start up code to be altered easily. Therefore the vector table used by FreeRTOS is defined in FreeRTOS_asm_vectors.S, which is part of this project. Switch to use the FreeRTOS vector table. */ vPortInstallFreeRTOSVectorTable(); - - /* Initialise UART for use with QEMU. */ - // XUartPs_ResetHw(0xE0000000); - // XUartPs_WriteReg(0xE0000000, XUARTPS_CR_OFFSET, - // ((u32)XUARTPS_CR_RX_DIS | (u32)XUARTPS_CR_TX_EN | - // (u32)XUARTPS_CR_STOPBRK)); } /*-----------------------------------------------------------*/ diff --git a/bsp_z7/newlib/close.c b/bsp_z7/newlib/close.c index e69de29..ab61f57 100644 --- a/bsp_z7/newlib/close.c +++ b/bsp_z7/newlib/close.c @@ -0,0 +1,6 @@ + +// TODO +int close(int _) { + (void)_; + return -1; +} \ No newline at end of file diff --git a/bsp_z7/testIp.c b/bsp_z7/testIp.c deleted file mode 100644 index 786918b..0000000 --- a/bsp_z7/testIp.c +++ /dev/null @@ -1,230 +0,0 @@ -#include "FreeRTOS.h" -#include "lwip/init.h" -#include "lwip/sio.h" -#include "lwip/timeouts.h" -#include "lwip/udp.h" - -#include "queue.h" -#include "task.h" -#include -#include -#include - -#include -#include - -#undef XUARTPS_IXR_RXOVR -#define XUARTPS_IXR_RXOVR 0x00000020U /**< Rx Overrun error interrupt */ -#define XUARTPS_IXR_RTRIG 0x00000001U /**< RX FIFO trigger interrupt. */ - - - -// #include - -// void slipif_rxbyte_input(struct netif *netif, u8_t c); - -// uint8_t packets = 0; - -// static void *tftp_open(const char *fname, const char *mode, u8_t is_write) { -// LWIP_UNUSED_ARG(mode); -// packets = 100; -// return (void *)13; -// } - -// static void tftp_close(void *handle) {} - -// static int tftp_read(void *handle, void *buf, int bytes) { -// memset(buf, 'x', bytes); -// if (packets == 0) { -// return 0; -// } else { -// packets--; -// return bytes; -// } -// } - -// static int tftp_write(void *handle, struct pbuf *p) { return 0; } - -// /* For TFTP client only */ -// static void tftp_error(void *handle, int err, const char *msg, int size) {} - -// static const struct tftp_context tftp = {tftp_open, tftp_close, tftp_read, -// tftp_write, tftp_error}; - - -struct netif netif; - -QueueHandle_t uartIsrQueue; - -extern XScuGic xInterruptController; /* Interrupt controller instance */ - -/** this is based on XUartPs_InterruptHandler() in xuartps_intr.c*/ -void handleUARTInt(void *) { - u32 IsrStatus; - - /* - * Read the interrupt ID register to determine which - * interrupt is active - */ - IsrStatus = XUartPs_ReadReg(STDIN_BASEADDRESS, XUARTPS_IMR_OFFSET); - - IsrStatus &= XUartPs_ReadReg(STDIN_BASEADDRESS, 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(uartIsrQueue, &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); -} - -static struct udp_pcb *udpecho_raw_pcb; - -static void -udpecho_raw_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port) -{ - LWIP_UNUSED_ARG(arg); - if (p != NULL) { - /* send received packet back to sender */ - udp_sendto(upcb, p, addr, port); - /* free the pbuf */ - pbuf_free(p); - } -} - -uint8_t data[] = {'1','2','3','4','5'}; - -void lwip_main(void *) { - - struct pbuf* tx = pbuf_alloc_reference(data, sizeof(data), PBUF_REF); - - ip_addr_t addr = IPADDR4_INIT_BYTES(10,0,0,13); - - udp_sendto(udpecho_raw_pcb, tx, &addr, 1177); - - pbuf_free(tx); - - while (1) { - // slipif_rxbyte_input() is private, so we use slipif_poll and implement - // sio_tryread() - // sio_tryread() will do a blocking read with a timeout, so we get to check - // the timeouts even if no data is incoming - slipif_poll(&netif); - sys_check_timeouts(); - } -} - -// TODO define sio_fd_t to an int -uint32_t sio_data; - -sio_fd_t sio_open(u8_t devnum) { return &sio_data; } - -void sio_send(u8_t c, sio_fd_t fd) { XUartPs_SendByte(STDOUT_BASEADDRESS, c); } - -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len) { - if (len < 1) { - return 0; - } - BaseType_t result; - //need a timeout because lwip task needs to do background work - result = xQueueReceive(uartIsrQueue, data, pdMS_TO_TICKS(250)); - if (result == pdTRUE) { - return 1; - } else { - return 0; - } -} - -#ifdef LWIP_DEBUG -const char *lwip_strerr(err_t err) { return "Dafuq i know? I am a NOSYS"; } -#endif - -u32_t sys_now(void) { return xTaskGetTickCount() * portTICK_PERIOD_MS; } - -static StaticQueue_t xStaticQueue; -static const uint16_t QUEUE_LENGTH = 512; -uint8_t ucQueueStorageArea[512 * 1]; - -static const uint16_t stackSizeWords = 512; -StaticTask_t xTaskBuffer; -StackType_t xStack[512]; - -void testIp() { - - uartIsrQueue = - xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue); - - 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))}; - - 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); - - 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 */ - } - - /* 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); - - // 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 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 diff --git a/mission/CMakeLists.txt b/mission/CMakeLists.txt index 3ebc801..8501596 100644 --- a/mission/CMakeLists.txt +++ b/mission/CMakeLists.txt @@ -1,3 +1,6 @@ +################################################ +# Mission code in C +# adds directly to the OBSW target +################################################ - -target_sources(${TARGET_NAME} PRIVATE mission.c freeRTOS_rust_helper.c) \ No newline at end of file +target_sources(${OBSW_NAME} PRIVATE mission.c freeRTOS_rust_helper.c) \ No newline at end of file diff --git a/mission/mission.c b/mission/mission.c index 8c1e065..021ca5f 100644 --- a/mission/mission.c +++ b/mission/mission.c @@ -43,7 +43,8 @@ void test_hardware() { // to be implemented by bsp (do not return from it!) void done(); -void init_task(void *) { +void init_task(void * _) { + (void )_; // printf("Starting Mission\n"); test_hardware(); @@ -63,9 +64,9 @@ void mission(void) { int taskParameters = 0; - static const size_t stackSizeWords = 102400; - StaticTask_t xTaskBuffer; - StackType_t xStack[stackSizeWords]; + // static const size_t stackSizeWords = 102400; + // StaticTask_t xTaskBuffer; + // StackType_t xStack[stackSizeWords]; xTaskCreate(init_task, /* The function that implements the task. */ "init", /* The text name assigned to the task - for debug only as diff --git a/mission_rust/CMakeLists.txt b/mission_rust/CMakeLists.txt index e850a3e..06fbb87 100644 --- a/mission_rust/CMakeLists.txt +++ b/mission_rust/CMakeLists.txt @@ -1,3 +1,10 @@ +################################################ +# Mission code in rust +# exports code as static library `mission_rust` +################################################ + + + #TODO can we get CMake to configure cmake --build --clean to run cargo clean? #TODO look into corrosion cmake plugin diff --git a/sim_interface/CMakeLists.txt b/sim_interface/CMakeLists.txt index 8dd83c3..6cea932 100644 --- a/sim_interface/CMakeLists.txt +++ b/sim_interface/CMakeLists.txt @@ -1,7 +1,7 @@ add_executable(sim_interface EXCLUDE_FROM_ALL mission.c testEth.c) -target_link_options(sim_interface PRIVATE -Wl,--cref -Wl,-Map=${TARGET_NAME}.map -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -Wl,-build-id=none -T${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/lscript.ld -specs=${CMAKE_SOURCE_DIR}/bsp_z7/freeRTOS/Xilinx.spec ) +target_link_options(sim_interface PRIVATE ${ROMEO_Z7_LINK_OPTIONS} ) -target_link_libraries(sim_interface PRIVATE lwip_xil bsp freertos_kernel) +target_link_libraries(sim_interface PRIVATE lwip_xil bsp) target_link_options(sim_interface PRIVATE "-Wl,--gc-sections") \ No newline at end of file