From d3d2b51fa21187c8b1bedbf52e9fa19553a50c1c Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Fri, 17 Jul 2015 10:43:55 -0300 Subject: [PATCH] galileo: Initial stdio support This patch introduces the initial support for stdio library in Galileo platform. For now, only standard output and error are supported. Both streams use the UART1 device. Newlib doesn't call open() for stdin, stdout, and stderr which means that the _write_r call is the first activity the stub will see on those streams. For that reason, we initialize the UART1 device in Galileo's platform main() function instead of in open() system call. --- platform/galileo/README.md | 5 +++ platform/galileo/contiki-main.c | 7 ++++ platform/galileo/newlib-syscalls.c | 58 ++++++++++++++++++++++++++---- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/platform/galileo/README.md b/platform/galileo/README.md index 121bf2471..5b3ff9715 100644 --- a/platform/galileo/README.md +++ b/platform/galileo/README.md @@ -28,11 +28,16 @@ Device drivers: * Programmable Interrupt Controller (PIC) * Programmable Intergal Timer (PIT) * Real-Time Clock (RTC) + * UART Contiki APIs: * Clock module * Timer, Stimer, Etimer, Ctimer, and Rtimer libraries +Standard APIs: + * Stdio library (stdout and stderr only). Console output through UART 1 + device (connected to Galileo Gen2 FTDI header) + Building -------- diff --git a/platform/galileo/contiki-main.c b/platform/galileo/contiki-main.c index 199ae45cc..7e8658d60 100644 --- a/platform/galileo/contiki-main.c +++ b/platform/galileo/contiki-main.c @@ -28,17 +28,24 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include "contiki.h" #include "cpu.h" #include "interrupt.h" +#include "uart.h" int main(void) { cpu_init(); + /* Initialize UART connected to Galileo Gen2 FTDI header */ + quarkX1000_uart_init(QUARK_X1000_UART_1); clock_init(); rtimer_init(); + printf("Starting Contiki\n"); + ENABLE_IRQ(); process_init(); diff --git a/platform/galileo/newlib-syscalls.c b/platform/galileo/newlib-syscalls.c index 6adcccd19..6c3be2d4c 100644 --- a/platform/galileo/newlib-syscalls.c +++ b/platform/galileo/newlib-syscalls.c @@ -31,6 +31,10 @@ #include #include +#include "uart.h" + +#define CONSOLE_OUTPUT_DEV QUARK_X1000_UART_1 + #define HEAP_MAX_SIZE 2048 static char _heap[HEAP_MAX_SIZE]; @@ -62,9 +66,40 @@ _read_r(struct _reent *ptr, int file, char *buf, int len) int _write_r(struct _reent *ptr, int file, const char *buf, int len) { - /* Stubbed function */ - ptr->_errno = ENOTSUP; - return -1; + int ret; + int i; + + switch(file) { + case 0: + ptr->_errno = EBADF; + ret = -1; + break; + + case 1: + case 2: + for(i = 0; i < len; i++) { + /* Since file descriptors 1 and 2 (stdout and stderr) are mapped to a + * serial console, we should translate the 'newline' escape sequence + * to 'carriage return' (CR) followed by 'line feed' (LF) ASCII + * characters. + */ + if(buf[i] == '\n') { + quarkX1000_uart_tx(CONSOLE_OUTPUT_DEV, '\r'); + } + quarkX1000_uart_tx(CONSOLE_OUTPUT_DEV, buf[i]); + } + + ret = len; + break; + + default: + /* We don't support any filesystem yet. */ + ptr->_errno = ENOTSUP; + ret = -1; + break; + } + + return ret; } /*---------------------------------------------------------------------------*/ int @@ -78,9 +113,20 @@ _lseek_r(struct _reent *ptr, int file, int p, int dir) int _fstat_r(struct _reent *ptr, int file, struct stat *st) { - /* Stubbed function */ - ptr->_errno = ENOTSUP; - return -1; + /* We don't support the standard input yet so file descriptor 0 is not + * supported by this function. Additionally, we don't have support for + * any filesystem thus file descriptors greater than 2 are not supported + * as well. + * + * We support standard ouput and error (file descriptors 1 and 2) only. + */ + if(file == 0 || file > 2) { + ptr->_errno = ENOTSUP; + return -1; + } + + st->st_mode = S_IFCHR; + return 0; } /*---------------------------------------------------------------------------*/ caddr_t