The I/O package is designed as a general purpose framework for supporting device drivers. This includes all classes of drivers from simple serial to networking stacks and beyond.
Components of the I/O package, such as device drivers, are configured into the system just like all other components. Additionally, end users may add their own drivers to this set.
While the set of drivers (and the devices they represent) may be
considered static, they must be accessed via an opaque
“handle”. Each device in the system has a unique name and
cyg_io_lookup() function is used to map that
name onto the handle for the device. This “hiding” of the
device implementation allows for generic, named devices, as well as
more flexibility. Also, the
function provides drivers the opportunity to initialize the device
when usage actually starts.
All devices have a name. The standard provided devices use names such as “/dev/console” and “/dev/serial0”, where the “/dev/” prefix indicates that this is the name of a device.
The entire I/O package API, as well as the standard set of provided drivers, is written in C.
Basic functions are provided to send data to and receive data from a device. The details of how this is done is left to the device [class] itself. For example, writing data to a block device like a disk drive may have different semantics than writing to a serial port.
Additional functions are provided to manipulate the state of the driver and/or the actual device. These functions are, by design, quite specific to the actual driver.
This driver model supports layering; in other words, a device may actually be created “on top of” another device. For example, the “tty” (terminal-like) devices are built on top of simple serial devices. The upper layer then has the flexibility to add features and functions not found at the lower layers. In this case the “tty” device provides for line buffering and editing not available from the simple serial drivers.
Some drivers will support visibility of the layers they depend upon. The “tty” driver allows information about the actual serial device to be manipulated by passing get/set config calls that use a serial driver “key” down to the serial driver itself.