forked from ROMEO/obsw
portable device access api based on unix file descriptors
This commit is contained in:
@ -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)
|
||||
target_sources(${TARGET_NAME} PRIVATE main.c)
|
||||
|
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)
|
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
|
||||
};
|
70
bsp_z7/hardware/interfaces.c
Normal file
70
bsp_z7/hardware/interfaces.c
Normal file
@ -0,0 +1,70 @@
|
||||
#include <hardware/interfaces.h>
|
||||
#include <xparameters_ps.h>
|
||||
#include <xuartps.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -47,6 +47,10 @@ XScuGic xInterruptController;
|
||||
|
||||
extern SemaphoreHandle_t malloc_mutex;
|
||||
|
||||
int get_descriptor_rw() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
void mission(void);
|
||||
|
||||
|
@ -1 +1 @@
|
||||
target_sources(${TARGET_NAME} PRIVATE write.c)
|
||||
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
5
bsp_z7/newlib/read.c
Normal file
5
bsp_z7/newlib/read.c
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
int _read(int file, char *ptr, int len) {
|
||||
return 0;
|
||||
}
|
@ -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;
|
||||
}
|
Reference in New Issue
Block a user