X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=doc%2Fhtml%2Fref%2Fio-how-to-write-a-driver.html;fp=doc%2Fhtml%2Fref%2Fio-how-to-write-a-driver.html;h=0000000000000000000000000000000000000000;hb=739c21725ce2774a605a0f1de3edaac2c43aea0f;hp=82be9e42286bd3c2948900a14d87fac1955ff4fe;hpb=ae71e0fa8076a1b59600b3a0ea10155a2cb534ae;p=karo-tx-redboot.git diff --git a/doc/html/ref/io-how-to-write-a-driver.html b/doc/html/ref/io-how-to-write-a-driver.html deleted file mode 100644 index 82be9e42..00000000 --- a/doc/html/ref/io-how-to-write-a-driver.html +++ /dev/null @@ -1,1154 +0,0 @@ - - - - - - - - -
A device driver is nothing more than a -named entity that supports the basic I/O functions - read, write, get -config, and set config. Typically a device driver also uses and -manages interrupts from the device. While the interface is generic and -device driver independent, the actual driver implementation is -completely up to the device driver designer.
That said, the reason for using a device driver is to provide -access to a device from application code in as general purpose a -fashion as reasonable. Most driver writers are also concerned with -making this access as simple as possible while being as efficient -as possible.
Most device drivers are concerned with the movement of information, -for example data bytes along a serial interface, or packets in a -network. In order to make the most efficient use of system resources, -interrupts are used. This will allow other application processing -to take place while the data transfers are under way, with interrupts -used to indicate when various events have occurred. For example, -a serial port typically generates an interrupt after a character -has been sent “down the wire” and the interface -is ready for another. It makes sense to allow further application -processing while the data is being sent since this can take quite -a long time. The interrupt can be used to allow the driver to send -a character as soon as the current one is complete, without any -active participation by the application code.
The main building blocks for device drivers are found in the -include file: <cyg/io/devtab.h>
All device drivers in eCos are described -by a device table entry, using the cyg_devtab_entry_t type. -The entry should be created using the DEVTAB_ENTRY() macro, -like this:
DEVTAB_ENTRY(l, name, dep_name, handlers, init, lookup, priv) |
Arguments
The "C" label for this device table entry.
The "C" string name for the device.
For a layered device, the "C" string name of the - device this device is built upon.
A pointer to the I/O function "handlers" (see below).
A function called when eCos is initialized. This - function can query the device, setup hardware, etc.
A function called when cyg_io_lookup() is called - for this device.
A placeholder for any device specific data - required by the driver.
The interface to the driver is through the handlers field. This is a pointer to -a set of functions which implement the various cyg_io_XXX() -routines. This table is defined by the macro:
DEVIO_TABLE(l, write, read, get_config, set_config) |
Arguments
The "C" label for this table of handlers.
The function called as a result of - cyg_io_write().
The function called as a result of - cyg_io_read().
The function called as a result of - cyg_io_get_config().
The function called as a result of - cyg_io_set_config().
When eCos is initialized (sometimes called -“boot” time), the init() function is called -for all devices in the system. The init() function is -allowed to return an error in which case the device will be placed -“off line” and all I/O requests to that device will be -considered in error.
The lookup() function is called whenever -the cyg_io_lookup() function -is called with this device name. The lookup function may cause the device -to come “on line” which would then allow I/O -operations to proceed. Future versions of the I/O system -will allow for other states, including power saving modes, -etc.
The standard serial driver supplied with -eCos is structured as a hardware independent -portion and a hardware dependent interface module. To add support for -a new serial port, the user should be able to use the existing -hardware independent portion and just add their own interface driver which handles the details of the -actual device. The user should have no need to change the hardware -independent portion.
The interfaces used by the serial driver and serial implementation -modules are contained in the file <cyg/io/serial.h>
Note: In the sections below we use the notation <<xx>> to -mean a module specific value, referred to as “xx” below.
The interface module contains the devtab entry (or entries -if a single module supports more than one interface). This entry -should have the form:
DEVTAB_ENTRY(<<module_name>>, - <<device_name>>, - 0, - &serial_devio, - <<module_init>>, - <<module_lookup>>, - &<<serial_channel>> - ); |
Arguments
The "C" label for this devtab entry
The "C" string for the - device. E.g. /dev/serial0.
The table of I/O functions. This set is defined in - the hardware independent serial driver and should be used.
The module initialization function.
The device lookup function. This function - typically sets up the device for actual use, turning on - interrupts, configuring the port, etc.
This table (defined below) contains the interface - between the interface module and the serial driver proper.
Each serial device must have a “serial channel”. -This is a set of data which describes all operations on the device. -It also contains buffers, etc., if the device is to be buffered. -The serial channel is created by the macro:
SERIAL_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,stop, parity, word_length, - flags, out_buf, out_buflen, in_buf, in_buflen) |
Arguments
The "C" label for this structure.
The set of interface functions (see below).
A placeholder for any device specific data for - this channel.
The initial baud rate value - (cyg_serial_baud_t).
The initial stop bits value - (cyg_serial_stop_bits_t).
The initial parity mode value - (cyg_serial_parity_t).
The initial word length value - (cyg_serial_word_length_t).
The initial driver flags value.
Pointer to the output - buffer. NULL if none required.
The length of the output buffer.
pointer to the input - buffer. NULL if none required.
The length of the input buffer.
If either buffer length is zero, no buffering will take place -in that direction and only polled mode functions will be used.
The interface from the hardware independent driver into the -hardware interface module is contained in the funs table. -This is defined by the macro:
SERIAL_FUNS(l, putc, getc, set_config, start_xmit, stop_xmit) |
Arguments
The "C" label for this structure.
bool (*putc)(serial_channel *priv, unsigned char - c)
This function sends one character to the interface. It should - return true if the character is actually consumed. It should - return false if there is no space in the interface -
unsigned char (*getc)(serial_channel *priv)
This function fetches one character from the interface. It will - be only called in a non-interrupt driven mode, thus it should - wait for a character by polling the device until ready. -
bool (*set_config)(serial_channel - *priv,cyg_serial_info_t *config)
This function is used to configure the port. It should return - true if the hardware is updated to match the desired - configuration. It should return false if the port cannot - support some parameter specified by the given - configuration. E.g. selecting 1.5 stop bits and 8 data bits is - invalid for most serial devices and should not be allowed. -
void (*start_xmit)(serial_channel *priv)
In interrupt mode, turn on the transmitter and allow for - transmit interrupts. -
void (*stop_xmit)(serial_channel *priv)
In interrupt mode, turn off the transmitter.
The device interface module can execute functions in the -hardware independent driver via chan->callbacks. -These functions are available:
void (*serial_init)( serial_channel *chan ) |
This function is used to initialize the serial channel. It -is only required if the channel is being used in interrupt -mode.
void (*xmt_char)( serial_channel *chan ) |
This function would be called from an interrupt handler after a -transmit interrupt indicating that additional characters may be -sent. The upper driver will call the putc -function as appropriate to send more data to the device.
void (*rcv_char)( serial_channel *chan, unsigned char c ) |
This function is used to tell the driver that a character has arrived -at the interface. This function is typically called from the interrupt -handler.
Furthermore, if the device has a FIFO it should require the hardware -independent driver to provide block transfer functionality (driver CDL -should include "implements -CYGINT_IO_SERIAL_BLOCK_TRANSFER"). In that case, the following -functions are available as well:
bool (*data_xmt_req)(serial_channel *chan, - int space, - int* chars_avail, - unsigned char** chars) -void (*data_xmt_done)(serial_channel *chan) |
Instead of calling xmt_char() to get a single -character for transmission at a time, the driver should call -data_xmt_req() in a loop, requesting character -blocks for transfer. Call with a space argument of how much space -there is available in the FIFO.
If the call returns true, the driver can read -chars_avail characters from -chars and copy them into the FIFO.
If the call returns false, there are -no more buffered characters and the driver should continue without -filling up the FIFO.
When all data has been unloaded, the -driver must call data_xmt_done().
bool (*data_rcv_req)(serial_channel *chan, - int avail, - int* space_avail, - unsigned char** space) -void (*data_rcv_done)(serial_channel *chan) |
Instead of calling rcv_char() with a single -character at a time, the driver should call -data_rcv_req() in a loop, requesting space to -unload the FIFO to. avail is the number of -characters the driver wishes to unload.
If the call returns true, the driver can copy -space_avail characters to -space.
If the call returns false, the input buffer is -full. It is up to the driver to decide what to do in that case -(callback functions for registering overflow are being planned for -later versions of the serial driver).
When all data has been unloaded, the driver must call -data_rcv_done().