forked from ROMEO/obsw
Merge remote-tracking branch 'origin/mohr/rust' into nehlich/ffs
This commit is contained in:
@ -1 +1,3 @@
|
|||||||
|
add_subdirectory(hardware)
|
||||||
|
|
||||||
target_sources(${TARGET_NAME} PRIVATE main.c)
|
target_sources(${TARGET_NAME} PRIVATE main.c)
|
1
bsp_linux/hardware/CMakeLists.txt
Normal file
1
bsp_linux/hardware/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE hardware.c)
|
28
bsp_linux/hardware/hardware.c
Normal file
28
bsp_linux/hardware/hardware.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <hardware/interfaces.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
@ -1,25 +1,52 @@
|
|||||||
#include <stdio.h>
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
const char *device_root = "./";
|
||||||
|
|
||||||
void mission(void);
|
void mission(void);
|
||||||
|
|
||||||
|
int get_descriptor_rw() { return 1; }
|
||||||
|
|
||||||
void done() {
|
void done() {
|
||||||
printf("done.");
|
printf("done.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_socket();
|
||||||
|
|
||||||
// Don't ask me, it makes the linker happy and does not seem
|
// Don't ask me, it makes the linker happy and does not seem
|
||||||
// to break anything ¯\_(ツ)_/¯
|
// to break anything ¯\_(ツ)_/¯
|
||||||
void rust_eh_personality() {
|
void rust_eh_personality() { puts("eh_personality"); }
|
||||||
puts("eh_personality");
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void outbyte(uint8_t byte){
|
|
||||||
printf("%c", byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
mission();
|
mission();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,4 +1,6 @@
|
|||||||
add_subdirectory(freeRTOS)
|
add_subdirectory(freeRTOS)
|
||||||
add_subdirectory(ps7_cortexa9_0)
|
add_subdirectory(ps7_cortexa9_0)
|
||||||
|
add_subdirectory(newlib)
|
||||||
|
add_subdirectory(hardware)
|
||||||
|
|
||||||
target_sources(${TARGET_NAME} PRIVATE main.c)
|
target_sources(${TARGET_NAME} PRIVATE main.c)
|
||||||
|
@ -89,7 +89,7 @@
|
|||||||
#define configUSE_APPLICATION_TASK_TAG 0
|
#define configUSE_APPLICATION_TASK_TAG 0
|
||||||
#define configUSE_COUNTING_SEMAPHORES 1
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
#define configUSE_QUEUE_SETS 1
|
#define configUSE_QUEUE_SETS 1
|
||||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||||
|
|
||||||
/* Include the query-heap CLI command to query the free heap space. */
|
/* Include the query-heap CLI command to query the free heap space. */
|
||||||
|
1
bsp_z7/hardware/CMakeLists.txt
Normal file
1
bsp_z7/hardware/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE interfaces.c uart.c)
|
5
bsp_z7/hardware/interface_access.h
Normal file
5
bsp_z7/hardware/interface_access.h
Normal file
@ -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);
|
7
bsp_z7/hardware/interface_fds.h
Normal file
7
bsp_z7/hardware/interface_fds.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum InterfaceFileDescriptors {
|
||||||
|
UART_0 = 3,
|
||||||
|
UART_1,
|
||||||
|
INTERFACE_FDS_NEXT
|
||||||
|
};
|
73
bsp_z7/hardware/interfaces.c
Normal file
73
bsp_z7/hardware/interfaces.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include <hardware/interfaces.h>
|
||||||
|
#include <xparameters_ps.h>
|
||||||
|
#include <xuartps.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#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) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//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) {
|
||||||
|
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 uart_send(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:
|
||||||
|
uart_send(XPS_UART0_BASEADDR, ptr, len);
|
||||||
|
return len;
|
||||||
|
case UART_1:
|
||||||
|
uart_send(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 uart0_read(ptr,len);
|
||||||
|
case UART_1:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
91
bsp_z7/hardware/uart.c
Normal file
91
bsp_z7/hardware/uart.c
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "queue.h"
|
||||||
|
|
||||||
|
#include <xscugic.h>
|
||||||
|
#include <xuartps.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
4
bsp_z7/hardware/uart.h
Normal file
4
bsp_z7/hardware/uart.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void uart0_enable_receiver();
|
||||||
|
int uart0_read(char *ptr, int len);
|
@ -47,6 +47,10 @@ XScuGic xInterruptController;
|
|||||||
|
|
||||||
extern SemaphoreHandle_t malloc_mutex;
|
extern SemaphoreHandle_t malloc_mutex;
|
||||||
|
|
||||||
|
int get_descriptor_rw() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
void mission(void);
|
void mission(void);
|
||||||
|
|
||||||
|
1
bsp_z7/newlib/CMakeLists.txt
Normal file
1
bsp_z7/newlib/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
target_sources(${TARGET_NAME} PRIVATE close.c read.c write.c)
|
0
bsp_z7/newlib/close.c
Normal file
0
bsp_z7/newlib/close.c
Normal file
34
bsp_z7/newlib/read.c
Normal file
34
bsp_z7/newlib/read.c
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "xil_printf.h"
|
||||||
|
#include "xparameters.h"
|
||||||
|
|
||||||
|
#include "../hardware/interface_access.h"
|
||||||
|
#include "../hardware/interface_fds.h"
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
41
bsp_z7/newlib/write.c
Normal file
41
bsp_z7/newlib/write.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include "xil_printf.h"
|
||||||
|
#include "xparameters.h"
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 is stdin, do not write to it
|
||||||
|
if (fd < 1) {
|
||||||
|
return -1; // TODO error
|
||||||
|
}
|
||||||
|
// we only support a single debug UART, so
|
||||||
|
// stdout and stderr are the same and go to the xiling stdout UART
|
||||||
|
// We output directely to avoid loops and allow debugging (not via a write)
|
||||||
|
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;
|
||||||
|
}
|
@ -22,7 +22,7 @@ target_sources(${TARGET_NAME} PUBLIC
|
|||||||
src/xil_testio.c
|
src/xil_testio.c
|
||||||
src/xplatform_info.c
|
src/xplatform_info.c
|
||||||
src/getpid.c
|
src/getpid.c
|
||||||
src/write.c
|
#src/write.c
|
||||||
src/xil_mem.c
|
src/xil_mem.c
|
||||||
src/kill.c
|
src/kill.c
|
||||||
src/xil_mmu.c
|
src/xil_mmu.c
|
||||||
@ -31,8 +31,8 @@ target_sources(${TARGET_NAME} PUBLIC
|
|||||||
src/getentropy.c
|
src/getentropy.c
|
||||||
src/xil_testmem.c
|
src/xil_testmem.c
|
||||||
src/isatty.c
|
src/isatty.c
|
||||||
src/read.c
|
#src/read.c
|
||||||
src/inbyte.c
|
#src/inbyte.c
|
||||||
src/close.c
|
src/close.c
|
||||||
src/xil_sleeptimer.c
|
src/xil_sleeptimer.c
|
||||||
src/print.c
|
src/print.c
|
||||||
|
110
bsp_z7/testIp.c
110
bsp_z7/testIp.c
@ -160,71 +160,71 @@ static const uint16_t stackSizeWords = 512;
|
|||||||
StaticTask_t xTaskBuffer;
|
StaticTask_t xTaskBuffer;
|
||||||
StackType_t xStack[512];
|
StackType_t xStack[512];
|
||||||
|
|
||||||
// void testIp() {
|
void testIp() {
|
||||||
|
|
||||||
// uartIsrQueue =
|
uartIsrQueue =
|
||||||
// xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue);
|
xQueueCreateStatic(QUEUE_LENGTH, 1, ucQueueStorageArea, &xStaticQueue);
|
||||||
|
|
||||||
// lwip_init();
|
lwip_init();
|
||||||
|
|
||||||
// ip4_addr_t slip_addr = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 32))},
|
ip4_addr_t slip_addr = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 32))},
|
||||||
// slip_mask = {PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0))},
|
slip_mask = {PP_HTONL(LWIP_MAKEU32(255, 255, 255, 0))},
|
||||||
// slip_gw = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 1))};
|
slip_gw = {PP_HTONL(LWIP_MAKEU32(10, 0, 0, 1))};
|
||||||
|
|
||||||
// netif_add(&netif, &slip_addr, &slip_mask, &slip_gw, NULL, slipif_init,
|
netif_add(&netif, &slip_addr, &slip_mask, &slip_gw, NULL, slipif_init,
|
||||||
// netif_input);
|
netif_input);
|
||||||
|
|
||||||
// netif_set_default(&netif);
|
netif_set_default(&netif);
|
||||||
// // should be done by driver, which does not do it, so we do it here
|
// should be done by driver, which does not do it, so we do it here
|
||||||
// netif_set_link_up(&netif);
|
netif_set_link_up(&netif);
|
||||||
// netif_set_up(&netif);
|
netif_set_up(&netif);
|
||||||
|
|
||||||
// udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
|
||||||
// if (udpecho_raw_pcb != NULL) {
|
if (udpecho_raw_pcb != NULL) {
|
||||||
// err_t err;
|
err_t err;
|
||||||
|
|
||||||
// err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7);
|
err = udp_bind(udpecho_raw_pcb, IP_ANY_TYPE, 7);
|
||||||
// if (err == ERR_OK) {
|
if (err == ERR_OK) {
|
||||||
// udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL);
|
udp_recv(udpecho_raw_pcb, udpecho_raw_recv, NULL);
|
||||||
// } else {
|
} else {
|
||||||
// /* TODO */
|
/* TODO */
|
||||||
// }
|
}
|
||||||
// } else {
|
} else {
|
||||||
// /* TODO */
|
/* TODO */
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /* Install the UART Interrupt handler. */
|
/* Install the UART Interrupt handler. */
|
||||||
// BaseType_t xStatus =
|
BaseType_t xStatus =
|
||||||
// XScuGic_Connect(&xInterruptController, STDIN_INT_NR,
|
XScuGic_Connect(&xInterruptController, STDIN_INT_NR,
|
||||||
// (Xil_ExceptionHandler)handleUARTInt, NULL);
|
(Xil_ExceptionHandler)handleUARTInt, NULL);
|
||||||
// configASSERT(xStatus == XST_SUCCESS);
|
configASSERT(xStatus == XST_SUCCESS);
|
||||||
// (void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
|
(void)xStatus; /* Remove compiler warning if configASSERT() is not defined. */
|
||||||
|
|
||||||
// // Set trigger level to 62 of 64 bytes, giving interrupt some time to react
|
// Set trigger level to 62 of 64 bytes, giving interrupt some time to react
|
||||||
// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXWM_OFFSET, 62);
|
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXWM_OFFSET, 62);
|
||||||
|
|
||||||
// // Setting the rx timeout to n*4 -1 bits
|
// Setting the rx timeout to n*4 -1 bits
|
||||||
// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXTOUT_OFFSET, 50);
|
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_RXTOUT_OFFSET, 50);
|
||||||
|
|
||||||
// // enable UART Interrupts
|
// enable UART Interrupts
|
||||||
// u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL |
|
u32 mask = XUARTPS_IXR_RTRIG | XUARTPS_IXR_RXOVR | XUARTPS_IXR_RXFULL |
|
||||||
// XUARTPS_IXR_TOUT;
|
XUARTPS_IXR_TOUT;
|
||||||
// /* Write the mask to the IER Register */
|
/* Write the mask to the IER Register */
|
||||||
// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IER_OFFSET, mask);
|
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IER_OFFSET, mask);
|
||||||
// /* Write the inverse of the Mask to the IDR register */
|
/* Write the inverse of the Mask to the IDR register */
|
||||||
// XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IDR_OFFSET, (~mask));
|
XUartPs_WriteReg(STDIN_BASEADDRESS, XUARTPS_IDR_OFFSET, (~mask));
|
||||||
|
|
||||||
// /* Enable the interrupt for the UART1 in the interrupt controller. */
|
/* Enable the interrupt for the UART1 in the interrupt controller. */
|
||||||
// XScuGic_Enable(&xInterruptController, STDIN_INT_NR);
|
XScuGic_Enable(&xInterruptController, STDIN_INT_NR);
|
||||||
|
|
||||||
// // Start lwip task
|
// Start lwip task
|
||||||
// xTaskCreateStatic(
|
xTaskCreateStatic(
|
||||||
// lwip_main, /* The function that implements the task. */
|
lwip_main, /* The function that implements the task. */
|
||||||
// "lwip", /* The text name assigned to the task - for debug
|
"lwip", /* The text name assigned to the task - for debug
|
||||||
// only as it is not used by the kernel. */
|
only as it is not used by the kernel. */
|
||||||
// stackSizeWords, /* The size of the stack to allocate to the task. */
|
stackSizeWords, /* The size of the stack to allocate to the task. */
|
||||||
// NULL, /* The parameter passed to the task - not used in this
|
NULL, /* The parameter passed to the task - not used in this
|
||||||
// simple case. */
|
simple case. */
|
||||||
// 4, /* The priority assigned to the task. */
|
4, /* The priority assigned to the task. */
|
||||||
// xStack, &xTaskBuffer);
|
xStack, &xTaskBuffer);
|
||||||
// }
|
}
|
@ -1,3 +1 @@
|
|||||||
target_sources(
|
target_include_directories(${TARGET_NAME} PRIVATE include)
|
||||||
${TARGET_NAME} PRIVATE
|
|
||||||
printChar.c)
|
|
37
common/include/hardware/interfaces.h
Normal file
37
common/include/hardware/interfaces.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
@ -1,10 +0,0 @@
|
|||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
void printChar(const char* character, bool errStream) {
|
|
||||||
if (errStream) {
|
|
||||||
fprintf(stderr, "%c", *character);
|
|
||||||
} else {
|
|
||||||
printf("%c", *character);
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,6 +9,24 @@
|
|||||||
|
|
||||||
void rust_main();
|
void rust_main();
|
||||||
|
|
||||||
|
#include <hardware/interfaces.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
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)
|
// called to stop execution (either a panic or program ended)
|
||||||
// to be implemented by bsp (do not return from it!)
|
// to be implemented by bsp (do not return from it!)
|
||||||
void done();
|
void done();
|
||||||
@ -16,6 +34,8 @@ void done();
|
|||||||
void init_task(void *) {
|
void init_task(void *) {
|
||||||
// printf("Starting Mission\n");
|
// printf("Starting Mission\n");
|
||||||
|
|
||||||
|
test_hardware();
|
||||||
|
|
||||||
rust_main();
|
rust_main();
|
||||||
|
|
||||||
// printf("Started Tasks, deleting init task\n");
|
// printf("Started Tasks, deleting init task\n");
|
||||||
@ -25,6 +45,8 @@ void init_task(void *) {
|
|||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void mission(void) {
|
void mission(void) {
|
||||||
|
|
||||||
int taskParameters = 0;
|
int taskParameters = 0;
|
||||||
|
@ -11,7 +11,3 @@ panic = 'abort'
|
|||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
panic = 'abort'
|
panic = 'abort'
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
@ -1,37 +1,76 @@
|
|||||||
// TODO this is platform specific
|
// TODO this is platform specific
|
||||||
|
|
||||||
pub struct Outbytes {}
|
pub struct Stdout {}
|
||||||
|
pub struct Stderr {}
|
||||||
|
|
||||||
use core::fmt::{Error, Write};
|
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> {
|
fn write_str(&mut self, s: &str) -> Result<(), Error> {
|
||||||
for c in s.as_bytes() {
|
|
||||||
unsafe {
|
// Safe because write will only read the pointer an then return
|
||||||
crate::fsrc::osal::outbyte(*c);
|
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(())
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sifln {
|
macro_rules! sifln {
|
||||||
($(,)?) => (
|
($(,)?) => (
|
||||||
let mut stdout = Outbytes {};
|
//let mut stdout = Outbytes {};
|
||||||
writeln!(stdout);
|
writeln!(Stdout {});
|
||||||
);
|
);
|
||||||
($($arg:tt)*) => (
|
($($arg:tt)*) => (
|
||||||
let mut stdout = crate::fsrc::sif::Outbytes {};
|
let _alwaysok = writeln!(crate::fsrc::sif::Stdout {}, $($arg)*);
|
||||||
let _alwaysok = writeln!(stdout, $($arg)*);
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sif {
|
macro_rules! sif {
|
||||||
($($arg:tt)*) => (
|
($($arg:tt)*) => (
|
||||||
let mut stdout = crate::fsrc::sif::Outbytes {};
|
let _alwaysok = write!(crate::fsrc::sif::Stdout {}, $($arg)*);
|
||||||
let _alwaysok = write!(stdout, $($arg)*);
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ fn panic(panic: &PanicInfo<'_>) -> ! {
|
|||||||
osal::stop_it();
|
osal::stop_it();
|
||||||
}
|
}
|
||||||
// TODO: Make this unicode-safe
|
// TODO: Make this unicode-safe
|
||||||
sifln!("");
|
_ = writeln!(crate::fsrc::sif::Stderr {},"");
|
||||||
sif!("in task \"");
|
_ = write!(crate::fsrc::sif::Stderr {},"in task \"");
|
||||||
unsafe {
|
unsafe {
|
||||||
//TODO is from_ptr safe enough?
|
//TODO is from_ptr safe enough?
|
||||||
let task_name = core::ffi::CStr::from_ptr(osal::get_task_name());
|
let task_name = core::ffi::CStr::from_ptr(osal::get_task_name());
|
||||||
@ -32,12 +32,12 @@ fn panic(panic: &PanicInfo<'_>) -> ! {
|
|||||||
sif!("{}", string);
|
sif!("{}", string);
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
sif!("Schei<EFBFBD> Encoding");
|
_ = writeln!(crate::fsrc::sif::Stderr {},"Schei<EFBFBD> Encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sifln!("\":");
|
_ = writeln!(crate::fsrc::sif::Stderr {},"\":");
|
||||||
sifln!("{}", panic);
|
_ = writeln!(crate::fsrc::sif::Stderr {},"{}", panic);
|
||||||
//TODO: stop RTOS, exit if hosted
|
//TODO: stop RTOS, exit if hosted
|
||||||
unsafe { done() };
|
unsafe { done() };
|
||||||
loop {}
|
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]
|
#[no_mangle]
|
||||||
|
Reference in New Issue
Block a user