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.
This commit is contained in:
Andre Guedes 2015-07-17 10:43:55 -03:00 committed by Jesus Sanchez-Palencia
parent ee82304211
commit d3d2b51fa2
3 changed files with 64 additions and 6 deletions

View file

@ -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
--------

View file

@ -28,17 +28,24 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#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();

View file

@ -31,6 +31,10 @@
#include <sys/stat.h>
#include <errno.h>
#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