For a namespace clean function, implement
_write
, otherwise implement
write
. The detailed implementation will
depend on the file handling functionality available.
A minimal implementation only supports writing to standard output. The core of the implementation is:
int _write (int file, char *buf, int nbytes) { int i; /* Output character at at time */ for (i = 0; i < nbytes; i++) { outbyte (buf[i]); } return nbytes; } /* _write () */
The function outbyte
must use the
functionality of the target platform to write a single character
to standard output. For example copying the character to a serial
line for display. There can be no standard implementation of this
function.
For the OpenRISC 1000 two versions are needed one for the BSP without a UART one for the BSP with a UART.
Without a UART the implementation uses the
l.nop
opcode with a parameter, as with the
implementation of _exit
(Section 5.3.3). In this case the parameter 4 will cause the
simulator to print out the value in register r3
as an ASCII character.
#include "or1ksim-board.h" static void outbyte (char c) { register char t1 asm ("r3") = c; asm volatile ("\tl.nop\t%0" : : "K" (NOP_PUTC), "r" (t1)); } /* outbyte () */
We also use a stricter implementation of the main
write
function, only permitting a write if
the standard output or standard error stream is specified.
#include <errno.h> #include <unistd.h> #undef errno extern int errno; int _write (int file, char *buf, int nbytes) { int i; /* We only handle stdout and stderr */ if ((file != STDOUT_FILENO) && (file != STDERR_FILENO)) { errno = EBADF; return -1; } /* Output character at at time */ for (i = 0; i < nbytes; i++) { outbyte (buf[i]); } return nbytes; } /* _write () */
For the BSP supporting a UART, all that is needed is to change
the outbyte
function to use the routines to
drive the UART
static void outbyte (char c) { _uart_putc (c); } /* outbyte () */
The UART support routines are provided separately, driving the interface via its memory mapped registers.