refactoring, added second binary for sim interface, added second lwip implementation for sim interface

This commit is contained in:
2024-09-30 17:38:37 +02:00
parent 8fa5cddc23
commit 944e45cad2
69 changed files with 537 additions and 4936 deletions

View File

@ -0,0 +1,7 @@
add_executable(sim_interface 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_libraries(sim_interface PRIVATE bsp lwip_xil freertos_kernel)
target_link_options(sim_interface PRIVATE "-Wl,--gc-sections")

49
sim_interface/mission.c Normal file
View File

@ -0,0 +1,49 @@
/* Scheduler include files. */
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
int testEth();
void mission(void) {
testEth();
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) {
(void)pcTaskName;
(void)pxTask;
/* Run time stack overflow checking is performed if
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
taskDISABLE_INTERRUPTS();
// TODO panic
for (;;)
;
}
/*-----------------------------------------------------------*/
void vApplicationMallocFailedHook(void) {
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
taskDISABLE_INTERRUPTS();
for (;;)
;
}
void rust_assert_called(const char *pcFile, unsigned long ulLine);
void vAssertCalled(const char *pcFile, unsigned long ulLine) {
taskDISABLE_INTERRUPTS();
for (;;)
;
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/

152
sim_interface/testEth.c Normal file
View File

@ -0,0 +1,152 @@
#include "lwip/api.h"
#include "lwip/priv/sockets_priv.h"
#include "lwip/tcpip.h"
#include "sys/socket.h"
#include "FreeRTOS.h"
#include "task.h"
#include "xethernet.h"
#include "hardware/interfaces.h"
#include <unistd.h>
// Those three are a hack, but a quite performant one
struct lwip_sock *get_socket(int fd); // only works with a patched lwip
extern QueueHandle_t uart0_receive_queue;
extern QueueHandle_t uart1_receive_queue;
void udp_echo_thread(void *_) {
vTaskDelay(5000 * portTICK_RATE_MS);
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
xil_printf("no sock\n");
}
struct sockaddr_in our_addr;
memset(&our_addr, 0, sizeof(our_addr));
our_addr.sin_family = AF_INET;
our_addr.sin_port = htons(8100);
int ret = inet_aton("192.168.1.10", &our_addr.sin_addr);
if (ret == 0) {
xil_printf("no addr");
}
ret = bind(sock, (struct sockaddr *)&our_addr, sizeof(our_addr));
if (ret == -1) {
xil_printf("no bind");
}
struct sockaddr_in peer_addr;
memset(&peer_addr, 0, sizeof(peer_addr));
peer_addr.sin_family = AF_INET;
peer_addr.sin_port = htons(8100);
ret = inet_aton("192.168.1.5", &peer_addr.sin_addr);
if (ret == 0) {
xil_printf("no addr");
}
int uart0_fd = hw_device_open("uart0", 5);
int uart1_fd = hw_device_open("uart1", 5);
// char buffer[] = {'1','2','3','4'};
// ret = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)
// &peer_addr, sizeof(peer_addr)); if (ret <= 0) {
// xil_printf("no send");
// }
uint8_t rec_buffer[1024];
QueueSetHandle_t listening_set = xQueueCreateSet(100);
if (listening_set == NULL) {
xil_printf("no set");
}
struct lwip_sock *raw_socket = get_socket(sock);
sys_mbox_t queue_id = raw_socket->conn->recvmbox;
xQueueAddToSet(queue_id, listening_set);
xQueueAddToSet(uart0_receive_queue, listening_set);
xQueueAddToSet(uart1_receive_queue, listening_set);
while (1) {
QueueSetMemberHandle_t readable =
xQueueSelectFromSet(listening_set, portMAX_DELAY);
if (readable == queue_id) {
socklen_t peer_len = sizeof(peer_addr);
ret = lwip_recvfrom(sock, rec_buffer, sizeof(rec_buffer), 0,
(struct sockaddr *)&peer_addr, &peer_len);
if (peer_len > sizeof(peer_addr)) {
xil_printf("invalid peer");
continue;
}
if (ret < 0) {
continue;
}
uint16_t port = ntohs(peer_addr.sin_port);
switch (port) {
case 8100:
// xil_printf("udp rec 8100 len: %i\n", ret);
write(uart0_fd, rec_buffer, ret);
break;
case 8101:
xil_printf("udp rec 8101 len: %i\n", ret);
write(uart1_fd, rec_buffer, ret);
break;
default:
xil_printf("invalid port %i\n", port);
break;
}
} else if (readable == uart1_receive_queue) {
ret = read(uart1_fd, rec_buffer, sizeof(rec_buffer));
// Do not send empty packets
if (ret <= 0) {
continue;
}
xil_printf("uart got %i\n", ret);
peer_addr.sin_port = htons(8101);
// TODO sending 1 byte gives invalid UDP checksum
lwip_sendto(sock, rec_buffer, ret, 0, (struct sockaddr *)&peer_addr,
sizeof(peer_addr));
} else if (readable == uart0_receive_queue) {
ret = read(uart0_fd, rec_buffer, sizeof(rec_buffer));
// xil_printf("uart got %i\n", ret);
// Do not send empty packets
if (ret <= 0) {
continue;
}
peer_addr.sin_port = htons(8100);
// TODO sending 1 byte gives invalid UDP checksum
lwip_sendto(sock, rec_buffer, ret, 0, (struct sockaddr *)&peer_addr,
sizeof(peer_addr));
} else {
xil_printf("invalid handle");
}
}
xQueueRemoveFromSet(queue_id, listening_set);
while (1) {
ret = recv(sock, rec_buffer, sizeof(rec_buffer), 0);
xil_printf("received %i\n", ret);
vTaskDelay(100 * portTICK_RATE_MS);
}
}
int testEth() {
tcpip_init(NULL, NULL);
xethernet_init();
sys_thread_new("echo", udp_echo_thread, 0, 1024, DEFAULT_THREAD_PRIO);
vTaskStartScheduler();
}