From ee06c79bf42e290646fdbf59b0074f5bb0b2e827 Mon Sep 17 00:00:00 2001 From: Ulrich Mohr Date: Mon, 26 Aug 2024 12:03:31 +0200 Subject: [PATCH] xilinx eth in own folder. found another bug/challenge with dma --- bsp_z7/CMakeLists.txt | 1 + bsp_z7/eth/CMakeLists.txt | 5 + bsp_z7/eth/include/xethernet.h | 3 + bsp_z7/eth/xethernet.c | 123 ++++++++++++++++ bsp_z7/lwip/include/lwipopts.h | 9 +- bsp_z7/lwip/netif/xemacpsif.c | 16 ++- bsp_z7/lwip/netif/xemacpsif_dma.c | 5 + bsp_z7/testEth.c | 230 +----------------------------- mission_rust/src/lib.rs | 4 +- 9 files changed, 163 insertions(+), 233 deletions(-) create mode 100644 bsp_z7/eth/CMakeLists.txt create mode 100644 bsp_z7/eth/include/xethernet.h create mode 100644 bsp_z7/eth/xethernet.c diff --git a/bsp_z7/CMakeLists.txt b/bsp_z7/CMakeLists.txt index 596ab69..ebc62ae 100644 --- a/bsp_z7/CMakeLists.txt +++ b/bsp_z7/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(ps7_cortexa9_0) add_subdirectory(lwip) add_subdirectory(newlib) add_subdirectory(hardware) +add_subdirectory(eth) target_sources(${TARGET_NAME} PRIVATE main.c testEth.c) diff --git a/bsp_z7/eth/CMakeLists.txt b/bsp_z7/eth/CMakeLists.txt new file mode 100644 index 0000000..05690e1 --- /dev/null +++ b/bsp_z7/eth/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(${TARGET_NAME} PRIVATE + xethernet.c +) + +target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) \ No newline at end of file diff --git a/bsp_z7/eth/include/xethernet.h b/bsp_z7/eth/include/xethernet.h new file mode 100644 index 0000000..3175008 --- /dev/null +++ b/bsp_z7/eth/include/xethernet.h @@ -0,0 +1,3 @@ +#pragma once + +void xethernet_init(); \ No newline at end of file diff --git a/bsp_z7/eth/xethernet.c b/bsp_z7/eth/xethernet.c new file mode 100644 index 0000000..1cae547 --- /dev/null +++ b/bsp_z7/eth/xethernet.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2017 - 2022 Xilinx, Inc. + * Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "lwip/inet.h" +#include "lwip/tcpip.h" +#include "netif/xadapter.h" + +#define PLATFORM_EMAC_BASEADDR 0xE000B000 + +#define THREAD_STACKSIZE 1024 + +#define DEFAULT_IP_ADDRESS "192.168.1.10" +#define DEFAULT_IP_MASK "255.255.255.0" +#define DEFAULT_GW_ADDRESS "192.168.1.1" + +struct netif server_netif; + +// u32_t sys_now(void) { return xTaskGetTickCount() * portTICK_PERIOD_MS; } + +static void print_ip(char *msg, ip_addr_t *ip) { + xil_printf(msg); + xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), ip4_addr3(ip), + ip4_addr4(ip)); +} + +static void print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw) { + print_ip("Board IP: ", ip); + print_ip("Netmask : ", mask); + print_ip("Gateway : ", gw); +} + +// static void assign_default_ip(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw) +// { +// int err; + +// xil_printf("Configuring default IP %s \r\n", DEFAULT_IP_ADDRESS); + +// err = inet_aton(DEFAULT_IP_ADDRESS, ip); +// if (!err) +// xil_printf("Invalid default IP address: %d\r\n", err); + +// err = inet_aton(DEFAULT_IP_MASK, mask); +// if (!err) +// xil_printf("Invalid default IP MASK: %d\r\n", err); + +// err = inet_aton(DEFAULT_GW_ADDRESS, gw); +// if (!err) +// xil_printf("Invalid default gateway address: %d\r\n", err); +// } + +void init_thread(void *_) { + + /* the mac address of the board. this should be unique per board */ + u8_t mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x00, 0x01, 0x02}; + + /* Add network interface to the netif_list, and set it as default */ + ip_addr_t ip, mask, gw; + int err = inet_aton(DEFAULT_IP_ADDRESS, &ip); + if (!err) + xil_printf("Invalid default IP address: %d\r\n", err); + + err = inet_aton(DEFAULT_IP_MASK, &mask); + if (!err) + xil_printf("Invalid default IP MASK: %d\r\n", err); + + err = inet_aton(DEFAULT_GW_ADDRESS, &gw); + if (!err) + xil_printf("Invalid default gateway address: %d\r\n", err); + if (!xemac_add(&server_netif, &ip, &mask, &gw, mac_ethernet_address, + PLATFORM_EMAC_BASEADDR)) { + xil_printf("Error adding N/W interface\r\n"); + return; + } + + netif_set_default(&server_netif); + + /* specify that the network if is up */ + netif_set_up(&server_netif); + + /* start packet receive thread - required for lwIP operation */ + sys_thread_new("xemacif_input_thread", (void (*)(void *))xemacif_input_thread, + &server_netif, THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); + + print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), + &(server_netif.gw)); + xil_printf("\r\n"); + + // Some allocations do not allow task deletion + // vTaskDelete(NULL); + vTaskSuspend(NULL); +} + +void xethernet_init() { + // pushed into thread so it only starts after threads are started + sys_thread_new("initxeth_thread", init_thread, 0, THREAD_STACKSIZE, + DEFAULT_THREAD_PRIO); +} \ No newline at end of file diff --git a/bsp_z7/lwip/include/lwipopts.h b/bsp_z7/lwip/include/lwipopts.h index 0950476..4c6d126 100644 --- a/bsp_z7/lwip/include/lwipopts.h +++ b/bsp_z7/lwip/include/lwipopts.h @@ -114,7 +114,9 @@ byte alignment -> define MEM_ALIGNMENT to 2. */ /* MSVC port: intel processors don't need 4-byte alignment, but are faster that way! */ -#define MEM_ALIGNMENT 8U + //TODO documentation + //Zynq needs 32 for DMA to work (something about cache I guess...) +#define MEM_ALIGNMENT 32U #define MEM_USE_POOLS 1 #define MEMP_USE_CUSTOM_POOLS MEM_USE_POOLS @@ -166,6 +168,7 @@ a lot of data that needs to be copied, this should be set high. */ #define PBUF_POOL_SIZE 120 /* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ +/* Needs to be large enough to fit eth MTU to be able to use DMA for xemacps rx*/ #define PBUF_POOL_BUFSIZE 1600 /** SYS_LIGHTWEIGHT_PROT @@ -177,7 +180,7 @@ a lot of data that needs to be copied, this should be set high. */ /* ---------- TCP options ---------- */ -#define LWIP_TCP 1 +#define LWIP_TCP 0 #define TCP_TTL 255 #define LWIP_ALTCP (LWIP_TCP) @@ -288,7 +291,7 @@ a lot of data that needs to be copied, this should be set high. */ #endif /* LWIP_STATS */ /* ---------- NETBIOS options ---------- */ -#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1 +#define LWIP_NETBIOS_RESPOND_NAME_QUERY 0 /* ---------- PPP options ---------- */ diff --git a/bsp_z7/lwip/netif/xemacpsif.c b/bsp_z7/lwip/netif/xemacpsif.c index 7072b6a..ea0030b 100644 --- a/bsp_z7/lwip/netif/xemacpsif.c +++ b/bsp_z7/lwip/netif/xemacpsif.c @@ -279,6 +279,14 @@ s32_t xemacpsif_input(struct netif *netif) /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; + // xil_printf("\n %p %i\n",p->payload, p->len); + // for (int j = 0; j < 6; j++) { + // for (int i = 0; i < 8; i++) { + // xil_printf(" %02x", *((uint8_t *)(p->payload) + i + j * 8 ) ); + // } + // xil_printf("\n"); + // } + #if LINK_STATS lwip_stats.link.recv++; #endif /* LINK_STATS */ @@ -305,9 +313,11 @@ s32_t xemacpsif_input(struct netif *netif) break; default: - for (int i = 0; i < 14; i++) { - xil_printf(" %02x", *((uint8_t *)(p->payload) + i ) ); - } + //TODO debug + // for (int i = 0; i < 14; i++) { + // xil_printf(" %02x", *((uint8_t *)(p->payload) + i ) ); + // } + // xil_printf("invalid eth type\n"); pbuf_free(p); p = NULL; break; diff --git a/bsp_z7/lwip/netif/xemacpsif_dma.c b/bsp_z7/lwip/netif/xemacpsif_dma.c index 74112e1..fd4f884 100644 --- a/bsp_z7/lwip/netif/xemacpsif_dma.c +++ b/bsp_z7/lwip/netif/xemacpsif_dma.c @@ -538,6 +538,7 @@ void emacps_recv_handler(void *arg) } for (k = 0, curbdptr=rxbdset; k < bd_processed; k++) { + // outbyte('r'); bdindex = XEMACPS_BD_TO_INDEX(rxring, curbdptr); p = (struct pbuf *)rx_pbufs_storage[index + bdindex]; @@ -552,6 +553,8 @@ void emacps_recv_handler(void *arg) #endif pbuf_realloc(p, rx_bytes); + // xil_printf("reading bd index %i bdindex %i p %p payload %p len %i\n", index, bdindex, p, p->payload, p->len); + /* Invalidate RX frame before queuing to handle * L1 cache prefetch conditions on any architecture. */ @@ -775,6 +778,8 @@ XStatus init_dma(struct xemac_s *xemac) #endif XEmacPs_BdSetAddressRx(rxbd, (UINTPTR)p->payload); + xil_printf("setting bd index %i bdindex %i p %p payload %p\n", index, bdindex, p, p->payload); + rx_pbufs_storage[index + bdindex] = (UINTPTR)p; } XEmacPs_SetQueuePtr(&(xemacpsif->emacps), xemacpsif->emacps.RxBdRing.BaseBdAddr, 0, XEMACPS_RECV); diff --git a/bsp_z7/testEth.c b/bsp_z7/testEth.c index 02de8e0..62fc939 100644 --- a/bsp_z7/testEth.c +++ b/bsp_z7/testEth.c @@ -1,232 +1,12 @@ -/* - * Copyright (C) 2017 - 2022 Xilinx, Inc. - * Copyright (C) 2022 - 2023 Advanced Micro Devices, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "lwip/inet.h" -#include "lwip/init.h" -#include "lwip/udp.h" #include "lwip/tcpip.h" -#include "lwip/timeouts.h" -#include "netif/xadapter.h" -#include "xil_printf.h" -#include "xparameters.h" -#include -#include -#include - -#define PLATFORM_EMAC_BASEADDR 0xE000B000 - -#if LWIP_DHCP == 1 -#include "lwip/dhcp.h" -extern volatile int dhcp_timoutcntr; -err_t dhcp_start(struct netif *netif); -#endif - -#ifdef XPS_BOARD_ZCU102 -#if defined(XPAR_XIICPS_0_DEVICE_ID) || defined(XPAR_XIICPS_0_BASEADDR) -int IicPhyReset(void); -#endif -#endif - -void print_app_header(); -void start_application(); - -#define THREAD_STACKSIZE 1024 - -#define DEFAULT_IP_ADDRESS "192.168.1.10" -#define DEFAULT_IP_MASK "255.255.255.0" -#define DEFAULT_GW_ADDRESS "192.168.1.1" - -struct netif server_netif; - -// u32_t sys_now(void) { return xTaskGetTickCount() * portTICK_PERIOD_MS; } - -static void print_ip(char *msg, ip_addr_t *ip) { - xil_printf(msg); - xil_printf("%d.%d.%d.%d\n\r", ip4_addr1(ip), ip4_addr2(ip), ip4_addr3(ip), - ip4_addr4(ip)); -} - -static void print_ip_settings(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw) { - print_ip("Board IP: ", ip); - print_ip("Netmask : ", mask); - print_ip("Gateway : ", gw); -} - -static void assign_default_ip(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw) { - int err; - - xil_printf("Configuring default IP %s \r\n", DEFAULT_IP_ADDRESS); - - err = inet_aton(DEFAULT_IP_ADDRESS, ip); - if (!err) - xil_printf("Invalid default IP address: %d\r\n", err); - - err = inet_aton(DEFAULT_IP_MASK, mask); - if (!err) - xil_printf("Invalid default IP MASK: %d\r\n", err); - - err = inet_aton(DEFAULT_GW_ADDRESS, gw); - if (!err) - xil_printf("Invalid default gateway address: %d\r\n", err); -} - -void network_thread() { -#if LWIP_DHCP == 1 - int mscnt = 0; -#endif - /* the mac address of the board. this should be unique per board */ - u8_t mac_ethernet_address[] = {0x00, 0x0a, 0x35, 0x00, 0x01, 0x02}; - - /* Add network interface to the netif_list, and set it as default */ - if (!xemac_add(&server_netif, NULL, NULL, NULL, mac_ethernet_address, - PLATFORM_EMAC_BASEADDR)) { - xil_printf("Error adding N/W interface\r\n"); - return; - } - - netif_set_default(&server_netif); - - /* specify that the network if is up */ - netif_set_up(&server_netif); - - /* start packet receive thread - required for lwIP operation */ - sys_thread_new("xemacif_input_thread", - (void(*)(void*))xemacif_input_thread, &server_netif, - THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); - -#if LWIP_DHCP == 1 - dhcp_start(&server_netif); - while (1) { - vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); - dhcp_fine_tmr(); - mscnt += DHCP_FINE_TIMER_MSECS; - if (mscnt >= DHCP_COARSE_TIMER_SECS * 1000) { - dhcp_coarse_tmr(); - mscnt = 0; - } - } -#else - // vTaskDelete(NULL); -#endif -} - -void udp_receiver(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port){ - u32_t now = sys_now(); - xil_printf("%i received len: %i tot_len: %i data: ", now, p->len, p->tot_len); - char * pointer = p->payload; - for(uint8_t i = 0; i < p->len; i++) { - xil_printf(" %02x", *(pointer + i)); - } - xil_printf("\n"); -} - -int main_thread(void * _) { - -#if LWIP_DHCP == 1 - int mscnt = 0; -#endif - -#ifdef XPS_BOARD_ZCU102 - IicPhyReset(); -#endif - xil_printf("\n\r\n\r"); - xil_printf("-----lwIP Socket Mode UDP Client Application------\r\n"); - - /* initialize lwIP before calling sys_thread_new */ - //lwip_init(); - tcpip_init(NULL, NULL); - //give init some time - vTaskDelay(1000 * portTICK_PERIOD_MS); - - /* any thread using lwIP should be created using sys_thread_new */ - network_thread(); - -#if LWIP_DHCP == 1 - while (1) { - vTaskDelay(DHCP_FINE_TIMER_MSECS / portTICK_RATE_MS); - if (server_netif.ip_addr.addr) { - xil_printf("DHCP request success\r\n"); - break; - } - mscnt += DHCP_FINE_TIMER_MSECS; - if (mscnt >= 10000) { - xil_printf("ERROR: DHCP request timed out\r\n"); - assign_default_ip(&(server_netif.ip_addr), &(server_netif.netmask), - &(server_netif.gw)); - break; - } - } - -#else - assign_default_ip(&(server_netif.ip_addr), &(server_netif.netmask), - &(server_netif.gw)); -#endif - - print_ip_settings(&(server_netif.ip_addr), &(server_netif.netmask), - &(server_netif.gw)); - xil_printf("\r\n"); - - /* print all application headers */ - // print_app_header(); - xil_printf("\r\n"); +#include "FreeRTOS.h" +#include "task.h" - uint8_t data[] = {'1','2','3','4','5'}; - - struct pbuf* tx = pbuf_alloc_reference(data, sizeof(data), PBUF_REF); - - ip_addr_t addr = IPADDR4_INIT_BYTES(192,168,1,5); - - struct udp_pcb *udpecho_raw_pcb = udp_new(); - - u32_t now = sys_now(); - xil_printf("%i pcb: %p\r\n", now, udpecho_raw_pcb); - - udp_sendto(udpecho_raw_pcb, tx, &addr, 8100); - udp_recv(udpecho_raw_pcb,udp_receiver,NULL); - - while (1) { - //sys_check_timeouts(); - - vTaskDelay(200 * portTICK_PERIOD_MS); - } - - pbuf_free(tx); - - /* start the application*/ - // start_application(); - return 0; -} +#include "xethernet.h" int testEth(){ - sys_thread_new("main_thread", (void(*)(void*))main_thread, 0, - THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); + tcpip_init(NULL, NULL); + xethernet_init(); vTaskStartScheduler(); } \ No newline at end of file diff --git a/mission_rust/src/lib.rs b/mission_rust/src/lib.rs index 62f7041..65b0fdc 100644 --- a/mission_rust/src/lib.rs +++ b/mission_rust/src/lib.rs @@ -24,8 +24,8 @@ fn panic(panic: &PanicInfo<'_>) -> ! { _ = 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()); + //TODO this breaks all the time... + let task_name = core::ffi::CStr::from_ptr(osal::get_task_name()); let task_name_utf8 = core::str::from_utf8(task_name.to_bytes()); match task_name_utf8 { Ok(string) => {