Services and Modeling for Embedded Software Development
Embecosm divider strip
Prev  Next

5.3.20.  Write to a File, write

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.

Embecosm divider strip