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:
parent
ee82304211
commit
d3d2b51fa2
|
@ -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
|
||||
--------
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 */
|
||||
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;
|
||||
return -1;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
|
@ -78,10 +113,21 @@ _lseek_r(struct _reent *ptr, int file, int p, int dir)
|
|||
int
|
||||
_fstat_r(struct _reent *ptr, int file, struct stat *st)
|
||||
{
|
||||
/* Stubbed function */
|
||||
/* 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
|
||||
_sbrk_r(struct _reent *ptr, int incr)
|
||||
|
|
Loading…
Reference in a new issue