![]() |
![]() |
![]() |
![]() |
This chapter includes:
The Character DDK currently includes the source code for the 8250 serial driver. You may not have to change much:
You'll find the register addresses defined in ddk_working_dir/ddk-char/src/hardware/devc/public/hw/8250.h.
The <8250.h> file defines:
See the documentation for your hardware for information about its registers and bit definitions.
The source code for the 8250 serial driver is in ddk_working_dir/ddk-char/src/hardware/devc/ser8250. This directory includes:
There are also platform-specific directories, each of which includes:
![]() |
Change as little of the given source code as possible, because it's easy to mess things up. |
The most important parts of the code are those associated with output and interrupts.
Different chips use interrupts in different ways. Typically, interrupts occurs when:
The driver code adds characters only to the Input queue/buffer. The Canonical buffer is handled by io-char and is manipulated when the client read request is handled.
The ser8250 driver includes the following functions, defined in proto.h:
The driver's main() routine (defined in main.c) calls:
This function is defined in init.c and is called by options(). The prototype is:
DEV_8250 *create_device(TTYINIT *dip,
unsigned unit);
This function gets a device entry and its input/output buffers and creates a new device based on the options passed in.
This function is defined in init.c. The prototype is:
int enable_device( DEV_8250 *dev)
This function enables all the serial ports. You must call it for each port before returning from options() to complete the port initialization.
This function is defined in options.c. The prototype is:
unsigned options( int argc,
char *argv[] )
This function parses the driver's command-line arguments. For information about the arguments, see devc-ser8250 in the Utilities Reference.
Depending on the options specified, this function may call:
The options() function returns the number of ports that are enabled.
This function is defined in query_defdev.c. The prototype is:
void *query_default_device(TTYINIT *dip,
void *link )
This function returns a placeholder that's used for overwrites in the platform directory.
This function is defined in intr.c. The prototype is:
const struct sigevent *ser_intr( void *area,
int id )
The ser_attach_intr() function, which is called by create_device(), calls InterruptAttach() (see the QNX Neutrino Library Reference) to attach ser_intr() to the first handler. If you don't want to transmit at interrupt time, then you can set the EVENT_TTO event and return. This will trigger io-char's tte() function to call into tto() at thread time rather then interrupt time.
The ser_intr() function calls:
This function is defined in tto.c. The prototype is:
void ser_stty( DEV_8250 *dev )
This function configures registers that can be changed dynamically at runtime (baud, parity, stop bits, etc.). Don't use this function for any initialization that you need to do when first setting up the driver; use create_device() instead.
This function is defined in <init.c>. The prototype is:
void set_port( unsigned port,
unsigned mask,
unsigned data )
This function sets the specified bit(s) of the UART port to the given value (0 or 1). The arguments are:
This function is defined in <sys_ttyinit.c> in the platform-specific directories under ddk_working_dir/ddk-char/src/hardware/devc/ser8250.
The prototype is:
void sys_ttyinit( TTYINIT *dip )
This function initializes the TTYINIT clock and divisor default as appropriate for the platform.
This function is defined in tto.c. The prototype is:
int tto( TTYDEV *ttydev,
int action,
int arg1 )
This function takes data from io-char's output buffer and gives it to the hardware. It also deals with stty commands, by calling ser_stty(), and provides line control and line status information.
The arguments are:
![]() |
![]() |
![]() |
![]() |