The system calls

We now present the system calls used to access the serial port, and we will give an example at the end.

Cyg_ErrNo cyg_read_blocking(cyg_addrword_t cookie, Cyg_IORB *iorb);

Cyg_ErrNo cyg_write_blocking(cyg_addrword_t cookie, Cyg_IORB *iorb);

Cyg_ErrNo cyg_read_asynchronous(cyg_addrword_t cookie, Cyg_IORB *iorb);

Cyg_ErrNo cyg_write_asynchronous(cyg_addrword_t cookie, Cyg_IORB *iorb);

Cyg_ErrNo cyg_serial_rs232_set_kmode(cyg_addrword_t cookie, cyg_uint32 kmode);

This sets the kernel mode for the RS232 driver. The kernel mode is 0 for polled and 1 for interrupt driven.

Cyg_ErrNo cyg_serial_rs232_get_baud_rate(cyg_addrword_t cookie, cyg_uint32 *baud);

Cyg_ErrNo cyg_serial_rs232_set_baud_rate(cyg_addrword_t cookie, cyg_uint32 new_baud, cyg_uint32 *old_baud);

cyg_serial_rs232_get_baud_rate() gets the current baud rate on the serial port denoted by cookie and places it in *baud. cyg_serial_rs232_set_baud_rate() sets the baud rate to new_baud, while storing the previous one in *old_baud.

The baud rates are denoted by the standard POSIX codes for baud rates, which can be found in cyg/devs/serial/rs232/common/rs232.h and are listed here:

// Various baud rates
#define B0 	 0
#define B50 	 1
#define B75 	 2
#define B110 	 3
#define B134 	 4
#define B150 	 5
#define B200 	 6
#define B300 	 7
#define B600 	 8
#define B1200 	 9
#define B1800 	10
#define B2400 	11
#define B4800 	12
#define B9600 	13
#define B19200 	14
#define B38400 	15 

Cyg_ErrNo cyg_serial_rs232_get_line_mode(cyg_addrword_t cookie, cyg_uint32 *mode);

Cyg_ErrNo cyg_serial_rs232_set_line_mode(cyg_addrword_t cookie, cyg_uint32 new_mode, cyg_uint32 *old_mode);

cyg_serial_rs232_get_line_mode() gets the current line mode on the serial port denoted by cookie and places it in *mode. cyg_serial_rs232_set_baud_rate() sets the line mode to new_mode, while storing the previous one in *old_mode.

The line modes are denoted by the standard POSIX codes for line modes, which can be found in cyg/devs/serial/rs232/common/rs232.h.

The following program, which is based on the test case for the serial driver C API, sets up a single thread, prepares an IORB (simply by putting data in it and setting its length) and then writes the data out with cyg_write_blocking().

 

#include <stdio.h>

#include <cyg/kernel/kapi.h>            /* All the kernel specific stuff */
#include <cyg/devs/common/table.h>
/* also include pkgconf/system.h because it has the CYG_HAL_POWERPC
   macro to check if the POWERPC architecture is defined */
#include <pkgconf/system.h>

#define NTHREADS 1
#define STACKSIZE 4096

static cyg_handle_t thread[NTHREADS];
static cyg_thread thread_obj[NTHREADS];
static char stack[NTHREADS][STACKSIZE];

static void simple_prog(CYG_ADDRESS data)
{
    /* we do not yet have serial drivers for the PowerPC, so just
       don't compile this code for that platform */
#ifndef CYG_HAL_POWERPC

    Cyg_IORB iorb;
    cyg_addrword_t my_io_cookie;
    
    /* set the I/O cookie to point to our favorite serial device */
#ifdef CYGPKG_DEVICES_SERIAL_RS232_MN10300_1
    my_io_cookie = stdeval1_serial1;
#endif /* CYGPKG_DEVICES_SERIAL_RS232_MN10300 */
#ifdef CYGPKG_DEVICES_SERIAL_RS232_TX39
    my_io_cookie = jmr3904_serial;
#endif /* CYGPKG_DEVICES_SERIAL_RS232_TX39 */

    iorb.buffer = "This is test 1\n";
    iorb.buffer_length = 15; /* strlen(iorb.data); */
    cyg_write_blocking(my_io_cookie, &iorb);
    printf("Done with my non-blocking serial write\n");
#else  /* CYG_HAL_POWERPC */
    printf("No serial driver is available for the PowerPC yet\n");
#endif /* CYG_HAL_POWERPC */
}

void cyg_user_start(void)
{
    cyg_thread_create(4, simple_prog, (cyg_addrword_t) 0, "serial1",
                      (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
    cyg_thread_resume(thread[0]);
}  

MN10300 note: Please note that for the MN10300 stdeval1 board, the serial uses serial port 1 when the cookie is set to stdeval1_serial1.

If you wish to use a cookie value of stdeval1_serial2, you cannot use CygMon, since CygMon uses serial port 2.

TX39 note: Please note that to use the serial driver on the jmr3904 evaluation board, you need to burn in the ROM image that supports SREC downloading. This is located in loaders\tx39-jmr3904\sload.bin under the root of your eCos installation.

You must also modify the hal.h configuration file to set the CYG_HAL_USE_ROM_MONITOR_SLOAD option and comment out the CYG_HAL_USE_ROM_MONITOR_CYGMON option:

//#define CYG_HAL_USE_ROM_MONITOR_CYGMON

#define CYG_HAL_USE_ROM_MONITOR_SLOAD

And finally, if the CYGDBG_INFRA_DIAG_USE_DEVICE option in infra.h is configured (in this release it can only be configured by hand), all diagnostic and tracing output will go the default serial device for the evaluation board, rather than going to the gdb console. Note that assertions (which are meant to work even without kernel support) will bypass the interrupt mechanism and be output to the RS232 port directly.

To configure the device drivers, the configuration file pkgconf/devs.h allows you to specify the default diagnostics device. It can also reference device-specific files that have further configuration options.