changeset 2420:113240d85246

* doc/can.sgml: Callback on event documentation. * src/can.c: Change one wakeup to callback in a comment. * include/canio.h: changed cyg_addrword_t to CYG_ADDRWORD so can will compile without the kernel.
author asl
date Fri, 24 Aug 2007 13:41:25 +0000
parents 2e7c1dfc434c
children 51899a482fdd
files packages/io/can/current/ChangeLog packages/io/can/current/doc/can.sgml packages/io/can/current/include/canio.h packages/io/can/current/src/can.c
diffstat 4 files changed, 2153 insertions(+), 2068 deletions(-) [+]
line wrap: on
line diff
--- a/packages/io/can/current/ChangeLog
+++ b/packages/io/can/current/ChangeLog
@@ -1,162 +1,169 @@
-2007-08-06 Alexey Shusharin <mrfinch@mail.ru>
-           Andrew Lunn <andrew.lunn@ascom.ch>
-	
-	* cdl/io_can.cdl: Added option CYGOPT_IO_CAN_SUPPORT_CALLBACK
-      
-	* include/canio.h: Added struct cyg_can_callback_cfg for setting
-          callback configurations.
-       
-	* include/can.h: Added declaration and initialization of callback 
-          configuration in struct can_channel.
-       
-	* src/can.c: Added callback configuration changing and
-          application function call.
-
-2007-07-02 Uwe Kindler <uwe_kindler@web.de>
-    
-	* cdl/io_can.cdl: Added interface CYGINT_IO_CAN_CHANNELS for
-	  counting available CAN channels
-      
-	* include/canio.h: Changed type cyg_can_msgbuf_info. The two
-	  fields are 16 bit now because device drivers may support more
-	  than 256 message buffers (i.e. the LPC2xxx CAN driver)
-    
-2007-06-20  Uwe Kindler  <uwe_kindler@web.de>
-
-	* test/can_filter: Changed filter loop counter from cyg_uint8 to
-	  cyg_uint16 because LPC2xxx CAN driver supports more than 256
-	  message buffers.
-
-2007-03-23  Uwe Kindler  <uwe_kindler@web.de>
-
-	* cdl/io_can.cdl: Added several interfaces for implementation by
-	  device drivers.
-	  Moved several configuration options from device drivers to the
-	  generic CAN driver. With this design a device driver does not
-	  need to provide all configuration options in its CDL file - it
-	  simply needs to implement the provided interfaces. The drawback
-	  of this decicsion is, that it is not possible to control these
-	  options independently for several CAN devices. (But most platforms
-	  will have only 1 channel)
-	  Added configuration option CYGBLD_IO_CAN_EXTRA_TESTS. This option
-	  enables the build of the interactive CAN tests.
-	  
-	* test/can_filter: Added interactive message filtering test
-	
-	* test/can_hdi: Added interactive hardware description interface
-	  test
-	  
-	* test/can_load: Added interactive message handling (reception,
-	  transmission) test.
-	  
-	* test/can_remote: Added interactive remote response buffer test
-	  
-	* test/can_tx: Added interactive basic TX test. All tests are not
-	  part of the eCos test framework because they are interactive. That
-	  means, they require interaction with another user controlled 
-	  CAN node.
-	  
-	* include/can.h: Added identifier masks for standard and extended
-	  identifiers.
-	  Added the line #include CYGDAT_IO_CAN_DEVICE_INL. This enables a
-	  device driver to provide an own device inline file. In this inline
-	  file the driver may define own data types for CAN messages (for
-	  internal storage of CAN messages (see AT91SAM7 CAN driver))
-
-	* include/canio.h: Added baudrate CYGNUM_CAN_KBAUD_AUTO - support of 
-	  automatic baudrate detection if a driver supports such a feature.
-	  Added state CYGNUM_CAN_STATE_CONFIG and mode CYGNUM_CAN_MODE_CONFIG.
-	  The application may use these identifiers to set the CAN device into
-	  a state where it is safe to add/remove/configure message buffers.
-	  Added union data type cyg_can_msg_data. With this data type a 4 byte
-	  alignment of message data is guaranteed, an byte, word and dword 
-	  access to the data is possible and an assignment of two CAN datas are
-	  possible now.
-	  cyg_can_message now uses cyg_can_msg_data union for CAN data.
-	  Replaced SW-Filt flag by autobaud flag in HDI.
-	  Added CAN message access macros for read/write acces of CAN message
-	  structures. These macros hide implementation of CAN message from 
-	  application.
- 
-	* src/can.c: Added support for device driver defined CAN message 
-	  data types
-
-2006-12-19  Sergei Gavrikov  <sg@sgs.gomel.by>
-
-	* doc/can.sgml: Correctly close para tag.
-
-2006-12-13  Uwe Kindler  <uwe_kindler@web.de>
-
-	* doc/can.sgml: CAN driver SGML documentation added.
-
-2006-08-25  Gary Thomas  <gary@mlbassoc.com>
-
-	* cdl/io_can.cdl: Set parent for more intuitive ConfigTool layout.
-
-2006-03-27  Uwe Kindler  <uwe_kindler@web.de>
-
-	* src/can.c can_rcv_event() Clear the flag field in new event before
-	calling into low level hardware driver.
-
-2006-02-15  Uwe Kindler  <uwe_kindler@web.de>
-
-	* include/can_io.h Added message buffer configuration identifier:
-	CYGNUM_CAN_MSGBUF_RESET_ALL, CYGNUM_CAN_MSGBUF_RX_FILTER_ALL ...
-	Added cfg_id field to cyg_can_msgbuf_cfg data structure.
-
-2005-09-11  Uwe Kindler  <uwe_kindler@web.de>
-
-	* include/can_io.h Added support for get_config to CAN_LOWLEVEL_FUNS
-	structure. 
-	Added additional CAN events. 
-	Added support for can state (cyg_can_state) and CAN mode (cyg_can_mode).  
-	Changed data type of cyg_can_buf_info_t data structure from cyg_int32 
-	to cyg_uint32. 
-	Added support for message box configuration (cyg_can_msgbuf_info).
-	Added support for message filtering (cyg_cn_filter). 
-	Renamed cyg_can_rtr_buf to cyg_can_remote_buf. 
-	Renamed CYGNUM_CAN_RTR_BUF_NA and CYGNUM_CAN_RTR_BUF_INIT to 
-	CYGNUM_CAN_MSGBUF_NA and CYGNUM_CAN_MSGBUF_INIT because they are
-	also used for message filtering. 
-	Added support for hardware description interface. 
-	Added support for CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH,
-	CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN.
-	
-	* doc/can_driver_doc.html Additional configuration options
-	documented.
-	
-2005-05-24  Uwe Kindler  <uwe_kindler@web.de>
-
-	* Generic CAN driver package created
-
-//===========================================================================
-//####ECOSGPLCOPYRIGHTBEGIN####
-// -------------------------------------------
-// This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 2003, 2004 eCosCentric Limited
-//
-// eCos is free software; you can redistribute it and/or modify it under
-// the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 or (at your option) any later version.
-//
-// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or
-// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with eCos; if not, write to the Free Software Foundation, Inc.,
-// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// As a special exception, if other files instantiate templates or use macros
-// or inline functions from this file, or you compile this file and link it
-// with other works to produce a work based on this file, this file does not
-// by itself cause the resulting work to be covered by the GNU General Public
-// License. However the source code for this file must still be made available
-// in accordance with section (3) of the GNU General Public License.
-//
-// This exception does not invalidate any other reasons why a work based on
-// this file might be covered by the GNU General Public License.
-// -------------------------------------------
-//####ECOSGPLCOPYRIGHTEND####
-//===========================================================================
+2007-08-23 Alexey Shusharin <mrfinch@mail.ru>
+	
+	* doc/can.sgml: Callback on event documentation.
+	* src/can.c:  Change one wakeup to callback in a comment.
+	* include/canio.h: changed cyg_addrword_t to CYG_ADDRWORD so
+	  can will compile without the kernel.
+	
+2007-08-06 Alexey Shusharin <mrfinch@mail.ru>
+           Andrew Lunn <andrew.lunn@ascom.ch>
+	
+	* cdl/io_can.cdl: Added option CYGOPT_IO_CAN_SUPPORT_CALLBACK
+      
+	* include/canio.h: Added struct cyg_can_callback_cfg for setting
+          callback configurations.
+       
+	* include/can.h: Added declaration and initialization of callback 
+          configuration in struct can_channel.
+       
+	* src/can.c: Added callback configuration changing and
+          application function call.
+
+2007-07-02 Uwe Kindler <uwe_kindler@web.de>
+    
+	* cdl/io_can.cdl: Added interface CYGINT_IO_CAN_CHANNELS for
+	  counting available CAN channels
+      
+	* include/canio.h: Changed type cyg_can_msgbuf_info. The two
+	  fields are 16 bit now because device drivers may support more
+	  than 256 message buffers (i.e. the LPC2xxx CAN driver)
+    
+2007-06-20  Uwe Kindler  <uwe_kindler@web.de>
+
+	* test/can_filter: Changed filter loop counter from cyg_uint8 to
+	  cyg_uint16 because LPC2xxx CAN driver supports more than 256
+	  message buffers.
+
+2007-03-23  Uwe Kindler  <uwe_kindler@web.de>
+
+	* cdl/io_can.cdl: Added several interfaces for implementation by
+	  device drivers.
+	  Moved several configuration options from device drivers to the
+	  generic CAN driver. With this design a device driver does not
+	  need to provide all configuration options in its CDL file - it
+	  simply needs to implement the provided interfaces. The drawback
+	  of this decicsion is, that it is not possible to control these
+	  options independently for several CAN devices. (But most platforms
+	  will have only 1 channel)
+	  Added configuration option CYGBLD_IO_CAN_EXTRA_TESTS. This option
+	  enables the build of the interactive CAN tests.
+	  
+	* test/can_filter: Added interactive message filtering test
+	
+	* test/can_hdi: Added interactive hardware description interface
+	  test
+	  
+	* test/can_load: Added interactive message handling (reception,
+	  transmission) test.
+	  
+	* test/can_remote: Added interactive remote response buffer test
+	  
+	* test/can_tx: Added interactive basic TX test. All tests are not
+	  part of the eCos test framework because they are interactive. That
+	  means, they require interaction with another user controlled 
+	  CAN node.
+	  
+	* include/can.h: Added identifier masks for standard and extended
+	  identifiers.
+	  Added the line #include CYGDAT_IO_CAN_DEVICE_INL. This enables a
+	  device driver to provide an own device inline file. In this inline
+	  file the driver may define own data types for CAN messages (for
+	  internal storage of CAN messages (see AT91SAM7 CAN driver))
+
+	* include/canio.h: Added baudrate CYGNUM_CAN_KBAUD_AUTO - support of 
+	  automatic baudrate detection if a driver supports such a feature.
+	  Added state CYGNUM_CAN_STATE_CONFIG and mode CYGNUM_CAN_MODE_CONFIG.
+	  The application may use these identifiers to set the CAN device into
+	  a state where it is safe to add/remove/configure message buffers.
+	  Added union data type cyg_can_msg_data. With this data type a 4 byte
+	  alignment of message data is guaranteed, an byte, word and dword 
+	  access to the data is possible and an assignment of two CAN datas are
+	  possible now.
+	  cyg_can_message now uses cyg_can_msg_data union for CAN data.
+	  Replaced SW-Filt flag by autobaud flag in HDI.
+	  Added CAN message access macros for read/write acces of CAN message
+	  structures. These macros hide implementation of CAN message from 
+	  application.
+ 
+	* src/can.c: Added support for device driver defined CAN message 
+	  data types
+
+2006-12-19  Sergei Gavrikov  <sg@sgs.gomel.by>
+
+	* doc/can.sgml: Correctly close para tag.
+
+2006-12-13  Uwe Kindler  <uwe_kindler@web.de>
+
+	* doc/can.sgml: CAN driver SGML documentation added.
+
+2006-08-25  Gary Thomas  <gary@mlbassoc.com>
+
+	* cdl/io_can.cdl: Set parent for more intuitive ConfigTool layout.
+
+2006-03-27  Uwe Kindler  <uwe_kindler@web.de>
+
+	* src/can.c can_rcv_event() Clear the flag field in new event before
+	calling into low level hardware driver.
+
+2006-02-15  Uwe Kindler  <uwe_kindler@web.de>
+
+	* include/can_io.h Added message buffer configuration identifier:
+	CYGNUM_CAN_MSGBUF_RESET_ALL, CYGNUM_CAN_MSGBUF_RX_FILTER_ALL ...
+	Added cfg_id field to cyg_can_msgbuf_cfg data structure.
+
+2005-09-11  Uwe Kindler  <uwe_kindler@web.de>
+
+	* include/can_io.h Added support for get_config to CAN_LOWLEVEL_FUNS
+	structure. 
+	Added additional CAN events. 
+	Added support for can state (cyg_can_state) and CAN mode (cyg_can_mode).  
+	Changed data type of cyg_can_buf_info_t data structure from cyg_int32 
+	to cyg_uint32. 
+	Added support for message box configuration (cyg_can_msgbuf_info).
+	Added support for message filtering (cyg_cn_filter). 
+	Renamed cyg_can_rtr_buf to cyg_can_remote_buf. 
+	Renamed CYGNUM_CAN_RTR_BUF_NA and CYGNUM_CAN_RTR_BUF_INIT to 
+	CYGNUM_CAN_MSGBUF_NA and CYGNUM_CAN_MSGBUF_INIT because they are
+	also used for message filtering. 
+	Added support for hardware description interface. 
+	Added support for CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH,
+	CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH and CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN.
+	
+	* doc/can_driver_doc.html Additional configuration options
+	documented.
+	
+2005-05-24  Uwe Kindler  <uwe_kindler@web.de>
+
+	* Generic CAN driver package created
+
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2003, 2004 eCosCentric Limited
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
--- a/packages/io/can/current/doc/can.sgml
+++ b/packages/io/can/current/doc/can.sgml
@@ -1,1902 +1,1980 @@
-<!-- {{{ Banner                         -->
-
-<!-- =============================================================== -->
-<!--                                                                 -->
-<!--     can.sgml                                                    -->
-<!--                                                                 -->
-<!--     Generic CAN documentation.                                  -->
-<!--                                                                 -->
-<!-- =============================================================== -->
-<!-- ####COPYRIGHTBEGIN####                                          -->
-<!--                                                                 -->
-<!-- =============================================================== -->
-<!-- Copyright (C) 2004 eCosCentric Limited                          -->
-<!-- This material may be distributed only subject to the terms      -->
-<!-- and conditions set forth in the Open Publication License, v1.0  -->
-<!-- or later (the latest version is presently available at          -->
-<!-- http://www.opencontent.org/openpub/)                            -->
-<!-- Distribution of the work or derivative of the work in any       -->
-<!-- standard (paper) book form is prohibited unless prior           -->
-<!-- permission obtained from the copyright holder                   -->
-<!-- =============================================================== -->
-<!--                                                                 -->
-<!-- ####COPYRIGHTEND####                                            -->
-<!-- =============================================================== -->
-<!-- #####DESCRIPTIONBEGIN####                                       -->
-<!--                                                                 -->
-<!-- Author(s):   Uwe Kindler                                        -->
-<!-- Date:        2006/12/04                                         -->
-<!--                                                                 -->
-<!-- ####DESCRIPTIONEND####                                          -->
-<!-- =============================================================== -->
-
-<!-- }}} -->
-
-<PART id="io-can"><title>CAN Support</title>
-
-<CHAPTER id="io-can-overview">
-<TITLE>Overview</TITLE>
-
-<SECTION id="io-can-overview-descr">
-<TITLE>Description</TITLE>
-
-<PARA>
-The Controller Area Network, CAN, is a multicast shared, differential 
-serial bus standard especially suited for networking "intelligent" 
-devices as well as sensors and actuators within a system or sub-system. 
-The protocol was originally developed in the 1980s by Robert Bosch GmbH 
-aiming at automotive applications. Nowadays CAN has gained widespread use 
-and is used in industrial automation as well as in automotive, mobile 
-machines and in many embedded control applications.
-</PARA>
-    
-<PARA>
-The CAN protocol is defined by the ISO 11898-1 standard. The physical layer 
-uses differential transmission on a twisted pair wire.  CAN uses a 
-non-destructive bit-wise arbitration to control access to the bus.
-</PARA>
-    
-<PARA>
-There is no explicit address in the messages because in CAN networks there 
-is no addressing of subscribers or stations, but instead, each message carries 
-a prioritized identifier. A transmitter sends a message to all CAN nodes 
-(broadcasting). The identifier may serve as an identification of the contents 
-of the message and also determines the priority that the message enjoys in 
-competition for bus access. A node decides on the basis of this identifier 
-received whether it should process the message or not.
-</PARA>
-    
-<PARA>
-The CAN messages are small (at most eight data bytes) and are protected 
-by a checksum. Each CAN message consists of  an 11 bit message ID, up to 8 
-bytes of data and, a CRC checksum and a number of  control bits. These 
-short messages ensure a robust transfer of data in electromagnetically 
-noisy environments. An extended version of the CAN frame supports 29 bit 
-message identifiers.
-</PARA>
-    
-<PARA>
-Basically there are two different operational modes for CAN receivers - 
-FullCAN and BasicCAN.  The difference between these two modes is the 
-Object Storage function. The BasicCAN architecture is quite similar to a 
-simple UART. A BasicCAN device has typically one transmit buffer and two 
-receive buffers. The CAN chip handles only the transmitting and receiving 
-of the data (and the error handling) and so most of the manipulation of the 
-data has to be done by the CPU. The CPU has to request the transmitting or 
-acknowledge the receiving of the data through the interrupt flags. This will 
-burden the CPU and take up much of the CPU time. 
-</PARA>
-
-<PARA>
-The FullCAN architecture is more suitable for high-speed performance. It 
-has its own storage area on chip and works with a number of message buffers 
-or message boxes. The CAN controller has its own Acceptance Filtering Mask 
-on chip. It can thus determine which frames are to be received by examining 
-the identifiers. The CPU in this case will only receive the valid (wanted) 
-frames and hence improve the performance of the CPU.
-</PARA>
-    
-<PARA>
-You can find more information at the 
-<ulink url="http://www.can-cia.org/">CAN in Automation</ulink> website.
-</PARA>
-
-</SECTION> <!-- "io-can-description" -->
-
-<SECTION id="io-can-ecos-support">
-<TITLE>eCos Support for CAN</TITLE>
-
-<PARA>
-The eCos CAN subsystem supports the BasicCAN and FullCAN mode. The architecture 
-and the interface of the eCos CAN driver is quite similar to the eCos serial 
-driver and supports the same interface.
-</PARA>
-
-<PARA>
-The eCos CAN support for any given platform is spread over a number of different 
-packages: 
-</PARA>
-
-<itemizedlist>
-  <listitem>
-    <para>
-
-This package, <varname>CYGPKG_IO_CAN</varname>, exports a generic
-device independent CAN I/O API for accessing devices attached to a CAN
-network. This API handles issues such as locking between threads. The
-package does not contain any hardware-specific code. Instead it will
-call into a CAN device driver to handle the hardware device
-access. This package also defines the inderface that such hardware
-drivers should provide.
-    </para>
-  </listitem>
-  <listitem>
-    <para>
-Each CAN device will have its own device driver, which is implemented 
-as a separate package, for example 
-<varname>CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN</varname>. For devices that may 
-be attached to a variety of different boards the device driver will be 
-generic and a second platform specific package will be used to customize 
-it to each platform. For devices that are associated with a specific 
-chipset, only a single package may be present.
-    </para>
-  </listitem>
-</itemizedlist>
-
-<PARA>
-Typically all appropriate packages will be loaded automatically when 
-you configure eCos for a given platform. If the application does not use 
-any of the CAN I/O facilities, directly or indirectly, then linker garbage 
-collection should eliminate all unnecessary code and data. All necessary 
-initialization should happen automatically. However the exact details may 
-depend on the platform, so the platform HAL documentation should be 
-checked for further details.
-</PARA>
-    
-<PARA>
-There is an important exception to this: if the CAN devices are attached 
-to an expansion connector, such as PCI, then the platform HAL will not 
-know about these devices. Instead the necessary packages will need to be 
-added explicitly during configuration.
-</PARA>
-</SECTION>
-</CHAPTER>
-
-<CHAPTER id="io-can-api">
-<TITLE>User API</TITLE>
-
-<PARA>
-The CAN driver uses the standard eCos I/O API functions. All functions 
-except <function>cyg_io_lookup()</function> require an I/O "handle".
-</PARA>
-
-<PARA>
-All functions return a value of the type <type>Cyg_ErrNo</type>. 
-If an error condition is detected, this value will be negative and the 
-absolute value indicates the actual error, as specified in 
-<filename>cyg/error/codes.h</filename>. The only other legal return values 
-will be <varname>ENOERR</varname>, <varname>-EINTR</varname> and 
-<varname>-EAGAIN</varname>. All other function arguments are pointers 
-(references). This allows the drivers to pass information efficiently, 
-both into and out of the driver. The most striking example of this is the 
-<parameter>len</parameter> value passed to the read and write functions. 
-This parameter contains the desired length of data on input to the 
-function and the actual transferred length on return.
-</PARA>
-    
-<PROGRAMLISTING>
-// Lookup a CAN device and return its handle 
-Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_lookup</function>( 
-    const char <parameter>*name</parameter>,
-    cyg_io_handle_t <parameter>*handle</parameter> )
-</PROGRAMLISTING>
-
-<PARA>
-This function maps a CAN device name onto an appropriate handle. If the
-named device is not in the system, then the error
-<varname>-ENOENT</varname> is returned. If the device is found, then
-the handle for the device is returned by way of the handle pointer
-<parameter>*handle</parameter>.
-</PARA>
-
-<PROGRAMLISTING>
-// Send a CAN message
-Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_write</function>( 
-    cyg_io_handle_t <parameter>handle</parameter>,
-    const void <parameter>*buf</parameter>,
-    cyg_uint32 <parameter>*len</parameter> )
-</PROGRAMLISTING>
-
-<PARA>
-This function sends one single CAN message (not a buffer of CAN messages) 
-to a device. The size of data to send is contained in 
-<parameter>*len</parameter> and the actual size sent will be returned in 
-the same place.
-</PARA>
-
-<PROGRAMLISTING>
-// Read one CAN event from device
-Cyg_ErrNo <!-- <index></index> --><function>cyg_io_read</function>( 
-    cyg_io_handle_t <parameter>handle</parameter>,
-    void <parameter>*buf</parameter>,
-    cyg_uint32 <parameter>*len</parameter> )
-</PROGRAMLISTING>
-
-<PARA>
-This function receives one single CAN event from a device. The desired size 
-of data to receive is contained in <parameter>*len</parameter> and the 
-actual size obtained will be returned in the same place. 
-</PARA>
-
-<PROGRAMLISTING>
-// Read configuration of a CAN device
-Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_get_config</FUNCTION>( 
-    cyg_io_handle_t <parameter>handle</parameter>,
-    cyg_uint32 <parameter>key</parameter>,
-    void *<parameter>buf</parameter>,
-    cyg_uint32 *<parameter>len</parameter> )
-</PROGRAMLISTING>
-
-<PARA>
-This function is used to obtain run-time configuration about a
-device. The type of information retrieved is specified by the
-<parameter>key</parameter>. The data will be returned in the given
-buffer. The value of <parameter>*len</parameter> should contain the
-amount of data requested, which must be at least as large as the size
-appropriate to the selected key. The actual size of data retrieved is
-placed in <parameter>*len</parameter>. The appropriate key values 
-are all listed in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.
-</PARA>
-
-<PROGRAMLISTING>
-// Change configuration of a CAN device
-Cyg_ErrNo <!-- <index></index> --><function>cyg_io_set_config</function>( 
-    cyg_io_handle_t <parameter>handle</parameter>,
-    cyg_uint32 <parameter>key</parameter>,
-    const void <parameter>*buf</parameter>,
-    cyg_uint32 <parameter>*len</parameter> )
-</PROGRAMLISTING>
-
-<PARA>
-This function is used to manipulate or change the run-time
-configuration of a device. The type of information is specified by the
-<parameter>key</parameter>. The data will be obtained from the given
-buffer. The value of <parameter>*len</parameter> should contain the
-amount of data provided, which must match the size appropriate to the
-selected key.  The appropriate key values are all listed in the file
-<filename>&lt;cyg/io/config_keys.h&gt;</filename>.
-</PARA> 
-</CHAPTER>   
-
-<CHAPTER id="io-can-driver-details">
-<TITLE>CAN driver details</TITLE>
-
-<PARA>
-Allow applications and other packages to access CAN devices.
-</PARA>
-
-<SECTION id="io-can-driver-description">
-<TITLE>Description</TITLE>
-
-<PARA>
-A raw CAN driver is is provided as a standard part of the eCos system.
-</PARA>
-
-<PARA>
-Use the include file <filename>&lt;cyg/io/canio.h&gt;</filename> for this driver.
-</PARA>
-    
-<PARA>
-The CAN driver is capable of sending single CAN messages to a device and 
-receiving single CAN events from a CAN device. Controls are provided to 
-configure the actual hardware, but there is no manipulation of the data by 
-this driver. 
-</PARA>
-    
-<PARA>
-There may be many instances of this driver in a given system, one for each 
-CAN channel. Each channel corresponds to a physical device and there will 
-typically be a device module created for this purpose. The device modules 
-themselves are configurable, allowing specification of the actual hardware 
-details.     
-</PARA>
-</SECTION>
-
-<SECTION id="io-can-api-details">
-<TITLE>API Details</TITLE>
-
-<SECTION>
-<TITLE>cyg_io_write</TITLE>
-  
-<PROGRAMLISTING>
-cyg_io_write(handle, buf, len)
-</PROGRAMLISTING>
-
-<PARA>
-To transmit a message an application must fill a <type>cyg_can_message</type>
-buffer and call <function>cyg_io_write()</function>.
-This function sends one single CAN message (not a buffer of CAN messages) 
-to a device. The size of data to send is contained in <parameter>*len</parameter> 
-and the actual size sent will be returned in the same place. A pointer to a
-<type>cyg_can_message</type> is contained in <parameter>*buf</parameter>. 
-The driver maintains a buffer to hold the data. The size of the intermediate
-buffer is configurable within the interface module. The data is not modified 
-at all while it is being buffered. On return, <parameter>*len</parameter> 
-contains the amount of characters actually consumed - that means 
-<parameter>*len</parameter> always contains 
-<function>sizeof(cyg_can_message)</function>.
-</PARA>
-    
-<PARA>
-It is possible to configure the write call to be blocking (default) or 
-non-blocking. Non-blocking mode requires both the configuration option 
-<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, and 
-the specific device to be set to non-blocking mode for writes 
-(see <function>cyg_io_set_config()</function>). In blocking mode, the 
-call will not return until there is space in the buffer and the content 
-of the CAN message has been consumed. In non-blocking mode, if there is 
-no space in buffer for the CAN message, <varname>-EAGAIN</varname> is 
-returned and the caller must try again.
-</PARA>
-    
-<PARA>
-It is possible to configure the write call to be non-blocking with timeout. 
-None-blocking mode with timeout requires the configuration option 
-<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
-<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, requires 
-the eCos kernel package to be included and the specific device to be set 
-to non-blocking mode for writes (see <function>cyg_io_set_config()
-</function>). 
-In non-blocking mode with timeouts, if there is no space in buffer for the 
-CAN message, the driver waits a certain amount of time (the timeout time) 
-for space in the buffer. If there is still no space in buffer after 
-expiration of the timeout time, <varname>-EINTR</varname> is returned and 
-the caller must try again.
-</PARA>
-    
-<PARA>
-If a message was sucessfully sent, the function returns <varname>ENOERR</varname>.
-</PARA>
-</SECTION>
-    
-<SECTION>  
-<TITLE>CAN Messages</TITLE>
-    
-<PARA>
-The CAN driver uses <structname>cyg_can_message</structname> structures to 
-pass messages between the application and the CAN driver. The type 
-cyg_can_message provides a device independent type of CAN message. 
-Before calling the write function this message should be setup properly.
-</PARA>
-
-<PROGRAMLISTING>
-typedef struct can_message
-{
-    cyg_uint32         id;
-    cyg_uint8          data[8];
-    cyg_can_id_type    ext;
-    cyg_can_frame_type rtr;
-    cyg_uint8          dlc;
-} cyg_can_message;
-</PROGRAMLISTING>
-
-<PARA>
-The structure contains the following fields:
-</PARA>
- 
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>id</varname></term>
-           <listitem><para>
-Message ID. This is the ID to be transmitted with the message, or the 
-ID received. If the <structfield>ext</structfield> field is set, then 
-this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>data</varname></term>
-           <listitem><para>
-Message data. Only the first <structfield>dlc</structfield> bytes of 
-data are valid. If the <structfield>rtr</structfield> field is set, 
-then the contents of this field are ignored.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_can_id_type</type> <varname>ext</varname></term>
-           <listitem><para>
-Extended ID. If this field is <varname>CYGNUM_CAN_ID_EXT</varname> then the 
-<structname>id</structname> field contains a 29 bit extended ID. If it 
-contains <varname>CYGNUM_CAN_ID_STD</varname> then the ID is 11 bits.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_can_frame_type</type> <varname>rtr</varname></term>
-           <listitem><para>
-Remote Transmission Request. If this field contains 
-<varname>CYGNUM_CAN_FRAME_RTR</varname> then the RTR bit on the message 
-will be set and the <structfield>data</structfield> field will be ignored. 
-If the field contains <varname>CYGNUM_CAN_FRAME_DATA</varname> then a 
-normal data frame will be send.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint8</type> <varname>dlc</varname></term>
-           <listitem><para>
-The length of the data carried in the message. This can range from 
-zero to 8. In a message with the <structfield>rtr</structfield> field set, 
-this indicates the size of data being requested.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-Example code for sending one single CAN message:
-</PARA>
-
-<PROGRAMLISTING>
-cyg_can_message tx_msg;
-cyg_uint32      len;
-Cyg_ErrNo       ret;
-
-tx_msg.id  = 0x100;
-tx_msg.ext = CYGNUM_CAN_ID_EXT;
-tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
-tx_msg.dlc = 1;
-tx_msg.data[0] = 0xF1;
-
-len = sizeof(tx_msg);
-ret = cyg_io_write(hDrvCAN, &amp;tx_msg, &amp;len);
-</PROGRAMLISTING>       
-</SECTION><!-- can-cyg_can_message -->
-
-<SECTION>
-<TITLE>cyg_io_read</TITLE> 
- 
-<PROGRAMLISTING>
-cyg_io_read(handle, buf, len)
-</PROGRAMLISTING>
-
-<PARA>
-To receive a message the application calls <function>cyg_can_recv()</function>.
-This function receives one single event from a device. The desired size 
-of data to receive is contained in <parameter>*len</parameter> and the
-actual size obtained will be returned in the same place. A pointer to 
-a <type>cyg_can_event</type> is contained in <parameter>*buf</parameter>. 
-No manipulation of the data is performed before being transferred. 
-Again, this buffering is completely configurable. On return, 
-<parameter>*len</parameter> contains <function>sizeof(cyg_can_event)</function>.
-</PARA>
-   
-<PARA>    
-It is possible to configure the read call to be blocking (default) or 
-non-blocking. Non-blocking mode requires both the configuration option 
-<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, 
-and the specific device to be set to non-blocking mode for reads 
-(see <function>cyg_io_set_config()</function>). In blocking mode, 
-the call will not return until one single CAN event has been read. 
-In non-blocking mode, if there is no CAN event in buffer, the call 
-returns immediately with <varname>-EAGAIN</varname> and the caller must 
-try again.
-</PARA>
-    
-<PARA>
-It is possible to configure the write call to be non-blocking with timeout. 
-None-blocking mode with timeout requires the configuration option 
-<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
-<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, 
-requires the eCos kernel package to be included and the specific device 
-to be set to non-blocking mode for reads (see 
-<function>cyg_io_set_config()</function>). In non-blocking mode with timeouts, 
-if there is no CAN event in receive buffer, the driver waits a certain amount 
-of time (the timeout time) for a CAN event to arrive. If there is still no 
-CAN event in buffer after expiration of the timeout time, <varname>-EINTR</varname> 
-is returned and the caller must try again.
-</PARA>
-    
-<PARA>
-If a event was sucessfully received, the function returns <varname>ENOERR</varname>.    
-</PARA>
-</SECTION><!-- cyg_io_read -->
-
-
-<SECTION>  
-<TITLE>CAN Events</TITLE>
-
-<PARA>
-The CAN driver uses <structname>cyg_can_event</structname> structures to
-pass events from hardware device driver to the generic CAN driver.
-A <structname>cyg_can_event</structname> provides a generic device 
-independent type for handling CAN events that may occur.
-</PARA> 
-
-<PROGRAMLISTING>
-typedef struct cyg_can_event_st
-{
-    cyg_uint32      timestamp;
-    cyg_can_message msg;
-    cyg_uint16      flags;
-} cyg_can_event;
-</PROGRAMLISTING>
-
-<PARA>
-The structure contains the following fields:
-</PARA>
- 
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>timestamp</varname></term>
-           <listitem><para>
-If the hardware CAN device driver supports timestamps then this field may 
-contain a timestamp value for an event that occured.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_can_message</type> <varname>msg</varname></term>
-           <listitem><para>
-CAN message. The msg field contains a CAN message if an RX or TX event
-occured.  If another type of event occured,
-the <structfield>data</structfield> field of
-the <structfield>msg</structfield> may contain additional event
-specific data.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint16</type> <varname>flags</varname></term>
-           <listitem><para>
-Event flags. The <varname>flags</varname> field contains 16 bits that 
-indicate which kind of events occured. 
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-    
-<PARA>
-The following events are supported and after receiving an event the 
-application should check the flag field against these values:
-</PARA>
-    
-<PROGRAMLISTING>
-typedef enum
-{
-  CYGNUM_CAN_EVENT_RX               = 0x0001, // message received
-  CYGNUM_CAN_EVENT_TX               = 0x0002, // message transmitted
-  CYGNUM_CAN_EVENT_WARNING_RX       = 0x0004, // (TEC) reached warning level (>96)
-  CYGNUM_CAN_EVENT_WARNING_TX       = 0x0008, // (REC) reached warning level (>96)
-  CYGNUM_CAN_EVENT_ERR_PASSIVE      = 0x0010, // CAN "error passive" occured
-  CYGNUM_CAN_EVENT_BUS_OFF          = 0x0020, // CAN "bus off" error occured
-  CYGNUM_CAN_EVENT_OVERRUN_RX       = 0x0040, // overrun in RX queue or hardware 
-  CYGNUM_CAN_EVENT_OVERRUN_TX       = 0x0080, // overrun in TX queue occured
-  CYGNUM_CAN_EVENT_CAN_ERR          = 0x0100, // a CAN bit or frame error occured
-  CYGNUM_CAN_EVENT_LEAVING_STANDBY  = 0x0200, // CAN hardware leaves standby
-  CYGNUM_CAN_EVENT_ENTERING_STANDBY = 0x0400, // CAN hardware enters standby
-  CYGNUM_CAN_EVENT_ARBITRATION_LOST = 0x0800, // arbitration lost
-  CYGNUM_CAN_EVENT_DEVICE_CHANGED   = 0x1000, // device changed event
-  CYGNUM_CAN_EVENT_PHY_FAULT        = 0x2000, // General failure of physical layer 
-  CYGNUM_CAN_EVENT_PHY_H            = 0x4000, // Fault on CAN-H (Low Speed CAN)
-  CYGNUM_CAN_EVENT_PHY_L            = 0x8000, // Fault on CAN-L (Low Speed CAN)
-} cyg_can_event_flags;
-</PROGRAMLISTING>
-
-<PARA>
-Often the flags field will contain only one single set flag. But it is 
-possible that a number of flags is set and so the flag field should always 
-be checked by a receiver. I.e. if the <varname>CYGNUM_CAN_EVENT_RX</varname> 
-is set then also the <varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> 
-may be set if the received message caused an RX overrun.
-</PARA>
-    
-<PARA>
-The internal receive buffers of the CAN device driver are circular buffers. 
-That means that even if the buffers are completely filled new messages 
-will be received. In this case the newest message will always overwrite 
-the oldest message in receive buffer. If this happens the 
-<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set for this 
-new message that caused overwriting of the old one. The 
-<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set also if 
-a overrun occures in hardware message buffers of the CAN device.
-</PARA>
-    
-<PARA>
-Example code for receiving one single CAN event:
-</PARA>
-
-<PROGRAMLISTING>
-cyg_can_event rx_event;
-cyg_uint32    len;
-Cyg_ErrNo     ret;
-
-len = sizeof(rx_event);
-ret = cyg_io_read(hDrvCAN, &amp;rx_event, &amp;len);
-
-if (ENOERR == ret)
-{
-    if (rx_event.flags &amp; CYGNUM_CAN_EVENT_RX)
-    {
-        // handle RX event
-    }
-    
-    if (rx_event.flags &amp; ~CYGNUM_CAN_EVENT_RX)
-    {
-        // handle other events
-    }
-}
-else if (-EINTR == ret)
-{
-    // handle timeout
-}
-</PROGRAMLISTING>       
-</SECTION><!-- can-cyg_can_event -->
-
-  
-<SECTION>
-<TITLE>cyg_io_get_config</TITLE> 
-  
-<PROGRAMLISTING>
-cyg_io_get_config(handle, key, buf, len)
-</PROGRAMLISTING>
-
-<PARA>
-This function is used to obtain run-time configuration about a device. 
-The type of information retrieved is specified by the <parameter>key</parameter>. 
-The data will be returned in the given buffer. The value of 
-<parameter>*len</parameter> should contain the amount of data requested, 
-which must be at least as large as the size appropriate to the selected 
-<parameter>key</parameter>. The actual size of data retrieved is placed 
-in <parameter>*len</parameter>. The appropriate key values are all listed 
-in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.    
-</PARA>   
-    
-<PARA>
-The following config keys are currently supported:
-</PARA>  
-    
-<PROGRAMLISTING>
-CYG_IO_GET_CONFIG_READ_BLOCKING
-CYG_IO_GET_CONFIG_WRITE_BLOCKING
-CYG_IO_GET_CONFIG_CAN_INFO
-CYG_IO_GET_CONFIG_CAN_BUFFER_INFO
-CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO
-CYG_IO_GET_CONFIG_CAN_TIMEOUT
-CYG_IO_GET_CONFIG_CAN_HDI
-CYG_IO_GET_CONFIG_CAN_STATE
-</PROGRAMLISTING>
-</SECTION><!-- can-cyg-io-get-config -->
-  
-<SECTION>
-<TITLE>cyg_io_set_config</TITLE> 
-  
-<PROGRAMLISTING>
-cyg_io_set_config(handle, key, buf, len)
-</PROGRAMLISTING>
-
-<PARA>
-This function is used to manipulate or change the run-time configuration 
-of a device. The type of information is specified by the <parameter>key</parameter>. 
-The data will be obtained from the given buffer. The value of 
-<parameter>*len</parameter> should contain the amount of data provided, 
-which must match the size appropriate to the selected <parameter>key</parameter>. 
-The appropriate key values are all listed in the file 
-<filename>&lt;cyg/io/config_keys.h&gt;</filename>.  
-</PARA>   
-    
-<PARA>
-The following config keys are currently supported:
-</PARA>  
-    
-<PROGRAMLISTING>
-CYG_IO_SET_CONFIG_READ_BLOCKING
-CYG_IO_SET_CONFIG_WRITE_BLOCKING
-CYG_IO_SET_CONFIG_CAN_INFO
-CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN
-CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH
-CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH
-CYG_IO_SET_CONFIG_CAN_TIMEOUT
-CYG_IO_SET_CONFIG_CAN_MSGBUF
-CYG_IO_SET_CONFIG_CAN_MODE
-</PROGRAMLISTING>
-</SECTION><!-- can-cyg-io-set-config -->
-</SECTION><!-- io-can-api-details -->
-
-<SECTION id="io-can-runtime-cfg">  
-<TITLE>Runtime Configuration</TITLE>
-  
-<PARA>
-Runtime configuration is achieved by exchanging data structures with the 
-driver via the <function>cyg_io_set_config()</function> and 
-<function>cyg_io_get_config()</function> functions.
-</PARA>
-
-<SECTION>
-<TITLE>Device configuration</TITLE>
-  
-<PROGRAMLISTING>
-typedef struct cyg_can_info_st {
-    cyg_can_baud_rate_t baud;
-} cyg_can_info_t;
-</PROGRAMLISTING>
-
-<PARA>
-Device configuration is achieved by by exchanging 
-<structname>cyg_can_info_t</structname> data structures with the driver 
-via the <function>cyg_io_set_config()</function> and 
-<function>cyg_io_get_config()</function> functions using the config keys 
-<varname>CYG_IO_GET_CONFIG_CAN_INFO</varname> and 
-<varname>CYG_IO_SET_CONFIG_CAN_INFO</varname>. 
-The field <structfield>baud</structfield> contains a baud rate selection. 
-This must be one of the following values:  
-</PARA>
-  
-<PROGRAMLISTING>
-CYGNUM_CAN_KBAUD_10
-CYGNUM_CAN_KBAUD_20
-CYGNUM_CAN_KBAUD_50
-CYGNUM_CAN_KBAUD_100
-CYGNUM_CAN_KBAUD_125
-CYGNUM_CAN_KBAUD_250
-CYGNUM_CAN_KBAUD_500
-CYGNUM_CAN_KBAUD_800
-CYGNUM_CAN_KBAUD_1000
-</PROGRAMLISTING>
-</SECTION><!-- can-cyg-io-set-config -->
-  
-<SECTION>
-<TITLE>Timeout configuration</TITLE>
-
-<PROGRAMLISTING>
-typedef struct cyg_can_timeout_info_st
-{
-    cyg_uint32 rx_timeout;
-    cyg_uint32 tx_timeout;
-} cyg_can_timeout_info_t;
-</PROGRAMLISTING>
-
-<PARA>
-Timeout configuration is achieved by by exchanging 
-<structname>cyg_can_timeout_info_t</structname> data structures with the 
-driver via the <function>cyg_io_set_config()</function> and 
-<function>cyg_io_get_config()</function> functions using the config keys 
-<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname> and 
-<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname>.   
-</PARA>
-
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>rx_timeout</varname></term>
-           <listitem><para>
-Timeout for <function>cyg_io_read</function> calls.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>tx_timeout</varname></term>
-           <listitem><para>
-Timeout for <function>cyg_io_write</function> calls.
-          </para></listitem>
-   </varlistentry>
-</variablelist>   
-
-<PARA>
-Timeout runtime configuration is supported if the configuration options 
-<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> 
-and <varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> are enabled. 
-</PARA>
-</SECTION><!-- can-timeout-config -->
-
-<SECTION>
-<TITLE>Reading buffer configuration</TITLE>
-    
-<PROGRAMLISTING>    
-typedef struct cyg_can_buf_info_st
-{
-    cyg_int32 rx_bufsize;
-    cyg_int32 rx_count;
-    cyg_int32 tx_bufsize;
-    cyg_int32 tx_count;
-} cyg_can_buf_info_t;
-</PROGRAMLISTING>
-
-<PARA>
-<varname>CYG_IO_GET_CONFIG_CAN_BUFFER_INFO</varname> - This function 
-retrieves the current state of the software buffers in the CAN drivers. 
-For the transmit buffer it returns the the total number of 
-<type>cyg_can_message</type> objects in buffer and the current number of 
-<type>cyg_can_message</type> objects occupied in the buffer. 
-For the receive buffer it returns the total number of 
-<type>cyg_can_event</type> objects in receive buffer and the current 
-number of <type>cyg_can_event</type> objects occupied in the buffer. 
-It does not take into account any buffering such as FIFOs or holding 
-registers that the CAN hardware device itself may have.
-</PARA>
-
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>rx_bufsize</varname></term>
-           <listitem><para>
-Total number of <type>cyg_can_event</type> buffers in receive queue.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>rx_count</varname></term>
-           <listitem><para>
-Current number of <type>cyg_can_event</type> buffers occupied in receive queue.
-          </para></listitem>
-   </varlistentry>
-      <varlistentry>
-       <term><type>cyg_uint32</type> <varname>tx_bufsize</varname></term>
-           <listitem><para>
-Total number of <type>cyg_can_message</type> buffers in transmit queue.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint32</type> <varname>rtx_count</varname></term>
-           <listitem><para>
-Current number of <type>cyg_can_message</type> buffers occupied in transmit queue.
-          </para></listitem>
-   </varlistentry>
-</variablelist>   
-</SECTION>  <!-- can-read-buffer-config -->
-  
-  
-<SECTION>
-<TITLE>Reading hardware description information</TITLE>
-    
-<PROGRAMLISTING>    
-typedef struct cyg_can_hdi_st
-{
-    cyg_uint8 support_flags;
-    cyg_uint8 controller_type;
-} cyg_can_hdi;
-</PROGRAMLISTING>
-
-<PARA>
-<varname>CYG_IO_GET_CONFIG_CAN_HDI</varname> - This function retrieves 
-information about the used hardware. The Hardware Description Interface 
-provides a method to gather information about the CAN hardware and the 
-functionality of the driver. For this purpose the structure 
-<structname>cyg_can_hdi</structname> is defined.  
-</PARA>
-     
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_uint8</type> <varname>support_flags</varname></term>
-           <listitem><para>
-Contains information about the capabilities of the used CAN hardware.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint8</type> <varname>controller_type</varname></term>
-           <listitem><para>
-A number that identifies the CAN controller type.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-The following flags are available in the field <structfield>support_flags</structfield>:  
-</PARA>
-     
-<PROGRAMLISTING>    
-|   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
-+-------+-------+-------+-------+-------+-------+-------+-------+
-|  res  |  res  |  res  |timest.|SW-Filt|FullCAN|   Frametype   |
-</PROGRAMLISTING>
-
-<variablelist>
-  <varlistentry>
-    <term><parameter>Frametype</parameter></term>
-    <listitem><para>
-Bit 0 and Bit 1 of the structure describe the possibilities of the CAN
-controller. The following values are defined:
-    <PROGRAMLISTING>    
-CYGNUM_CAN_HDI_FRAMETYPE_STD          // receives only standard frame
-CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE  // can receive but not send extended frames
-CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE   // can send and receive extended frames
-    </PROGRAMLISTING>
-    </para></listitem>
-  </varlistentry>
-    <varlistentry>
-    <term><parameter>FullCAN</parameter></term>
-    <listitem><para>
-If the Bit 2 - <varname>CYGNUM_CAN_HDI_FULLCAN </varname> - is set to one, 
-the CAN controller supports more than one message buffer.
-    </para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>SW-Filter</parameter></term>
-    <listitem><para>
-If Bit 3 - <varname>CYGNUM_CAN_HDI_FILT_SW</varname> - is set to one then 
-the CAN driver supports some kind of software message filtering.
-    </para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>Timestamp</parameter></term>
-    <listitem><para>
-If Bit 4 - <varname>CYGNUM_CAN_HDI_TIMESTAMP</varname> - is set to one then 
-the CAN hardware supports timestamps for CAN messages
-    </para></listitem>
-  </varlistentry>
-</variablelist>
-</SECTION>  <!-- can-read-buffer-config -->
-   
-<SECTION>
-<TITLE>Reading hardware message buffer configuration</TITLE>
-<PROGRAMLISTING>    
-typedef struct cyg_can_msgbox_info_st
-{
-    cyg_uint8 count; // number of message buffers available for this device
-    cyg_uint8 free;  // number of free message buffers
-} cyg_can_msgbuf_info;
-</PROGRAMLISTING>
-   
-<PARA>
-<varname>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO</varname> - If the CAN hardware supports 
-more than one message buffer for reception of CAN messages (flag 
-<varname>CYGNUM_CAN_HDI_FULLCAN</varname> is set while reading hardware description 
-interface with <varname>CYG_IO_GET_CONFIG_CAN_HDI</varname>) then this function 
-reads the number of message buffers the CAN hardware supports and the number of 
-free message buffers.   
-</PARA>
-
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_uint8</type> <varname>count</varname></term>
-           <listitem><para>
-Counts the number of message buffers supported by the device.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cyg_uint8</type> <varname>free</varname></term>
-           <listitem><para>
-Contains the number of free message buffers. The free message buffers are 
-available for setting up remote buffers (<varname>CYG_IO_SET_CONFIG_CAN_REMOTE_BUF</varname>) 
-and message filters (<varname>CYG_IO_SET_CONFIG_CAN_FILTER_MSG</varname>).
-          </para></listitem>
-   </varlistentry>
-</variablelist>   
-</SECTION> <!-- can-read-buffer-config -->
-   
-<SECTION>
-<TITLE>Reading state of CAN hardware</TITLE>
-
-<PROGRAMLISTING>    
-typedef enum
-{
-  CYGNUM_CAN_STATE_ACTIVE,      // CAN controller active, no errors
-  CYGNUM_CAN_STATE_STOPPED,     // CAN controller in stopped mode
-  CYGNUM_CAN_STATE_STANDBY,     // CAN controller in Sleep mode
-  CYGNUM_CAN_STATE_BUS_WARN,    // CAN controller active, warning level is reached
-  CYGNUM_CAN_STATE_ERR_PASSIVE, // CAN controller went into error passive mode
-  CYGNUM_CAN_STATE_BUS_OFF,     // CAN controller went into bus off mode
-  CYGNUM_CAN_STATE_PHY_FAULT,   // General failure of physical layer 
-  CYGNUM_CAN_STATE_PHY_H,       // Fault on CAN-H detected (Low Speed CAN)
-  CYGNUM_CAN_STATE_PHY_L,       // Fault on CAN-L detected (Low Speed CAN)
-} cyg_can_state;
-</PROGRAMLISTING>
-
-<PARA>
-<varname>CYG_IO_GET_CONFIG_CAN_STATE</varname> - This function retrieves the 
-present state of the CAN controller. Possible values are defined in the 
-<type>cyg_can_state</type> enumeration.
-</PARA>   
-</SECTION> <!-- can-read-hw-state -->
-
-
-<SECTION>
-<TITLE>Changing mode of CAN hardware</TITLE>
-
-<PARA>
-<varname>CYG_IO_SET_CONFIG_CAN_MODE</varname> - This function changes 
-the operating mode of the CAN controller. The identifiers for the different 
-operating modes are defined in the <type>cyg_can_mode</type> enumeration.
-</PARA>
-
-<PROGRAMLISTING> 
-typedef enum
-{
-  CYGNUM_CAN_MODE_STOP,   // set controller into stop mode
-  CYGNUM_CAN_MODE_START,  // set controller into operational mode
-  CYGNUM_CAN_MODE_STANDBY // set controller into standby / sleep mode
-} cyg_can_mode;
-</PROGRAMLISTING>
- 
-<variablelist>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MODE_STOP</type></term>
-           <listitem><para>
-Set controller into stop mode
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MODE_START</type></term>
-           <listitem><para>
-Set controller into operational mode
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MODE_STANDBY</type></term>
-           <listitem><para>
-Set controller into standby / sleep mode.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-Before the hardware configuration of the device is changed, that means
-if baud rate is changed or the message buffer and filter configuration
-is changed, the CAN hardware should be set into stop mode and if
-configuration is finished, then device should be set back into
-operational mode.  Before the device is set into standby mode, the
-output buffers should be flushed or drained because transmission of a
-CAN message may wake up the CAN hardware. If a received message wakes
-up the CAN hardware from standby mode then
-a <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> event will be
-inserted into receive message buffer or
-the <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> flag will be
-set for the message that caused wake up of CAN hardware.
-</PARA>
-</SECTION> <!-- can-mode-cfg -->
-   
-<SECTION>
-<TITLE>Flush or drain buffers</TITLE>
-
-<PARA>
-<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN</varname> - This function
-waits for any buffered output to complete. This function only
-completes when there is no more data remaining to be sent to the
-device.
-</PARA>
-   
-<PARA>
-<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH</varname> - This function
-discards any buffered output for the device.
-</PARA> 
-
-<PARA>
-<varname>CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH</varname> - This function
-discards any buffered input for the device.
-</PARA>
-</SECTION>
-   
-<SECTION>
-<TITLE>Configuring blocking/non-blocking calls</TITLE>
-<PARA>
-By default all calls to <function>cyg_io_read()</function>
-and <function>cyg_io_write()</function> are blocking calls. The config
-keys
-</PARA>
-
-<PROGRAMLISTING>
-CYG_IO_SET_CONFIG_READ_BLOCKING
-CYG_IO_SET_CONFIG_WRITE_BLOCKING
-</PROGRAMLISTING>
-
-<PARA>
-enable switching between blocking and nonblocking calls separatly for
-read and write calls.  If blocking calls are configured then the
-read/write functions return only if a message was stored into TX
-buffer or a event was received from RX buffer. If non-blocking calls
-are enabled and there is no space in TX buffer or RX buffer is empty
-then the function returns immediately
-with <varname>-EAGAIN</varname>.
-</PARA>
-   
-<PARA>
-If non-blocking calls are enabled and additionally timeouts are
-supported by driver, then the read/write functions wait until timeout
-value is expired and then return with <varname>-EINTR</varname>.  If
-the read/write operation succeeds during the timed wait then the
-functions return succesfully with
-<varname>ENOERR</varname>.
-</PARA>
-
-<PARA>
-To query if <function>cyg_io_read()</function>
-and <function>cyg_io_write()</function> are blocking or non-blocking
-you can use the config keys
-</PARA>
-
-<PROGRAMLISTING>
-CYG_IO_GET_CONFIG_READ_BLOCKING
-CYG_IO_GET_CONFIG_WRITE_BLOCKING
-</PROGRAMLISTING>
-</SECTION> <!-- can-cfg-unblock -->
-   
-<SECTION>
-<TITLE>Message buffer management</TITLE>
-
-<PARA>
-Full CAN controllers often support more the one message buffer. These
-message buffers are often configurable for transmission or reception
-of certain CAN messages or as a remote buffers.  If a CAN hardware
-supports more than one message buffer then it is possible to configure
-the CAN hardware to receive only CAN messages with certain identifiers
-or to configure hardware support for remote buffers. If message
-filtering is done by hardware, the number of received CAN messages
-decreases and so also the time for processing received CAN messages
-and the memory required for buffering received messages
-decreases. This saves valuable memory and processing time.
-</PARA>
-
-<PARA>
-The eCos CAN driver supports a generic way of adding message filters
-or remote buffers. By default the CAN driver is configured for
-reception of any kind of CAN standard and extended
-frames. Configuration of message buffers is done by
-calling <function>cyg_io_set_config()</function> with the config key
-</PARA>
-
-<PROGRAMLISTING>
-CYG_IO_SET_CONFIG_CAN_MSGBUF
-</PROGRAMLISTING>
-
-<PARA>
-and by exchanging <type>cyg_can_msgbuf_cfg</type> data structures.
-</PARA>
-
-<PROGRAMLISTING>
-typedef struct cyg_can_msgbox_cfg_st
-{
-    cyg_can_msgbuf_cfg_id cfg_id; // configuration id
-    cyg_can_msgbuf_handle handle; // handle to message buffer
-    cyg_can_message msg;          // CAN message - for configuration of buffer
-} cyg_can_msgbuf_cfg;
-</PROGRAMLISTING>
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
-           <listitem><para> The <varname>cfg_id</varname> field
-contains the configuration ID that tells the driver what to do with a
-message buffer.
-          </para></listitem>
-   </varlistentry>
-    <varlistentry>
-       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
-           <listitem><para>
-Contains a reference to a certain message buffer.
-          </para></listitem>
-   </varlistentry>
-    <varlistentry>
-       <term><type>cyg_can_message</type> <varname>msg</varname></term>
-           <listitem><para>
-Required for configuration of message buffer parameters.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-The following configuration identifiers are supported:
-</PARA>
-
-<PROGRAMLISTING>
-CYGNUM_CAN_MSGBUF_RESET_ALL        // clears alle message buffers
-CYGNUM_CAN_MSGBUF_RX_FILTER_ALL    // cfg driver for reception of all can messages
-CYGNUM_CAN_MSGBUF_RX_FILTER_ADD    // add single message filter
-CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD   // add new remote response buffer
-CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE // stores data into existing remote buffer 
-</PROGRAMLISTING>
-
-<variablelist>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MSGBUF_RESET_ALL</type></term>
-           <listitem><para>
-Clears alle message buffers - no message will be received and all remote buffers are deleted.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL</type></term>
-           <listitem><para>
-Configure driver for reception of all can messages
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ADD</type></term>
-           <listitem><para>
-Add single message filter.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</type></term>
-           <listitem><para>
-Add new remote response buffer.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</type></term>
-           <listitem><para>
-Stores data into existing remote buffer (remote buffer handle required).
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-Example code for resetting all message buffers:
-</PARA>
-
-<PROGRAMLISTING>
-cyg_can_msgbuf_cfg msgbox_cfg;
-
-msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
-len = sizeof(msgbox_cfg);
-if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
-                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
-                                &amp;msgbox_cfg, &amp;len))
-{
-    // handle configuration error
-}
-</PROGRAMLISTING> 
-</SECTION> <!-- can-msgbuf-cfg -->
-   
-   
-<SECTION>
-<TITLE>Remote frame response buffer configuration</TITLE>
-
-<PARA>
-The remote frame is a message frame which is transmitted to request a
-data frame. Some CAN hardware generates receive interrupts when a
-remote transmission request arrives. Other CAN hardware, i.e.  the
-Motorola FlexCAN module, does not generate any receive
-interrupt. These CAN hardware chips like the FlexCAN module can be
-configured to transmit a data frame automatically in response to a
-remote frame. In order to support any kind of CAN hardware the eCos CAN
-driver provides a generic handling of remote transmission requests.
-</PARA>
-
-<PARA>
-The transmission of the data frame in response to a remote frame is
-completely handled by the CAN driver.  If the hardware driver, like
-the driver for the FlexCAN module, supports hardware message buffers,
-then the response frame is automatically transmitted if a remote
-transmission request with a matching ID arrives.  If a CAN hardware
-does not provide hardware support for sending data frames in response
-to a remote frame, then this need to be implemented in software by the
-hardware device driver.
-</PARA>
-
-<PARA>
-It is always possible to add remote response buffers. It does not
-matter if the driver is configured for reception of all CAN messages
-or if message filtering is used. As long as there are free message
-buffers available, it is possible to add remote response buffers.
-</PARA>
-   
-<PARA>
-In order to respond to a remote frame, a remote frame response buffer
-need to be initialized before a data frame can be sent in response to
-a remote frame. This is achieved by by
-exchanging <type>cyg_can_remote_buf</type> data structures with the
-driver via the <function>cyg_io_set_config()</function> function using
-the config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once
-the buffer is initialized, the CAN data can be changed at any time by
-the application.
-</PARA>
-
-<PROGRAMLISTING>
-typedef struct cyg_can_msgbuf_cfg_st
-{
-    cyg_can_msgbuf_cfg_id cfg_id; // configuration id 
-    cyg_can_msgbuf_handle handle; // handle to message buffer
-    cyg_can_message msg;          // CAN message - for configuration of buffer
-} cyg_can_remote_buf;
-</PROGRAMLISTING> 
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
-           <listitem><para>
-The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
-a message buffer (<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</varname> or 
-<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</varname>).
-          </para></listitem>
-   </varlistentry>
-    <varlistentry>
-       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
-           <listitem><para>
-If there is no buffer initialized for this data, the value of the handle field need to be set to 
-<varname>CYGNUM_CAN_MSGBUF_INIT</varname>. After the call to <function>cyg_io_set_config()</function> 
-the handle field contains a valid remote buffer handle ( &gt;= 0) or the value 
-<varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available.
-          </para></listitem>
-   </varlistentry>
-    <varlistentry>
-       <term><type>cyg_can_message</type> <varname>msg</varname></term>
-           <listitem><para>
-The CAN frame that should be transmitted in response to a remote frame.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-Example code for setting up a remote response buffer:
-</PARA>
-
-<PROGRAMLISTING>
-cyg_can_remote_buf rtr_buf;
-
-// prepare the remote response buffer
-rtr_buf.cfg_id  = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
-rtr_buf.handle  = CYGNUM_CAN_MSGBUF_INIT;
-rtr_buf.msg.id  = 0x7FF;
-rtr_buf.msg.ext = CYGNUM_CAN_ID_STD;
-rtr_buf.msg.rtr = CYGNUM_CAN_FRAME_DATA;
-rtr_buf.msg.dlc = 1;
-rtr_buf.msg.data[0] = 0xAB;
-
-len = sizeof(rtr_buf);
-if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
-                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
-                                &amp;rtr_buf, &amp;len))
-{
-    // handle configuration error
-}
-
-if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
-{
-    // no free message buffer available - handle this problem here
-}
-
-
-// change CAN data for a buffer that is already initialized
-rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE;
-rtr_buf.msg.data[0] = 0x11;
-
-len = sizeof(rtr_buf);
-if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
-                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
-                                &amp;rtr_buf, &amp;len))
-{
-    // handle configuration error
-} 
-</PROGRAMLISTING> 
-</SECTION> <!-- can-rtrbuf-cfg -->
-    
-
-<SECTION>
-<TITLE>Message filter configuration</TITLE>
-
-<PARA>
-If message filtering is done by hardware the number of received CAN
-messages decreases and so also the time for processing received CAN
-messages and the memory required for buffering received messages
-decreases.  This saves valuable memory and processing time. The eCos
-CAN driver supports a generic way of adding message filters. By
-default the CAN driver is configured for reception of any kind of CAN
-standard and extended frames. As soon as a message filter is added,
-the CAN driver will only receive the CAN frames with the identifier of
-the CAN filter. By adding a number of message filters it is possible
-for the CAN hardware to receive an number of different CAN messages.
-</PARA>
-
-<PARA>
-Adding message filters is only possible if driver is not configured
-for reception of all available CAN messages. If the driver is
-configured for reception of all CAN messages then message buffers need
-to be reset before adding single message filters.
-</PARA>
-    
-<PARA>
-In order to add a message filter, a message buffer need to be
-initialized. This is achieved by
-exchanging <type>cyg_can_filter</type> data structures with the driver
-via the <function>cyg_io_set_config()</function> function using the
-config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once the
-buffer is initialized, the CAN hardware can receive messages with the
-identifier of the filter.
-</PARA>
-
-<PROGRAMLISTING> 
-typedef struct cyg_can_msgbox_cfg_st
-{
-    cyg_can_msgbuf_cfg_id cfg_id;
-    cyg_can_msgbuf_handle handle;
-    cyg_can_message       msg;
-} cyg_can_filter;
-</PROGRAMLISTING> 
-
-<variablelist>
-   <varlistentry>
-       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
-           <listitem><para>
-The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
-a message buffer.
-          </para></listitem>
-   </varlistentry>
-    <varlistentry>
-       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
-           <listitem><para>
-After the call to <function>cyg_io_set_config()</function> the handle field contains a valid value 
-( &gt;= 0) or the value <varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available. 
-          </para></listitem>
-   </varlistentry>
-    <varlistentry>
-       <term><type>cyg_can_message</type> <varname>msg</varname></term>
-           <listitem><para>
-The fields <structfield>id</structfield> and <structfield>ext</structfield> of the <structfield>msg</structfield>
-configure the type of message to receive by a certain message filter.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-
-<PARA>
-Before adding message filters the device should be stopped and after
-configuration it should be set into operational mode again.
-</PARA>
-
-<PARA>
-Example code for setting up a message filter:   
-</PARA>
-
-<PROGRAMLISTING> 
-cyg_can_msgbuf_cfg msgbox_cfg;
-cyg_can_filter rx_filter;
-
-// reset all message buffers
-msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
-len = sizeof(msgbox_cfg);
-if (ENOERR != cyg_io_set_config(hDrvFlexCAN, 
-                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
-                                &amp;msgbox_cfg, &amp;len))
-{
-    // handle configuration error
-}
-
-// prepare the message filter
-rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
-rx_filter.msg.id  = 0x800;
-rx_filter.msg.ext = CYGNUM_CAN_ID_EXT;
-
-len = sizeof(rx_filter);
-if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
-                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
-                                &amp;rx_filter, &amp;len))
-{
-    // handle configuration error;
-}
-else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
-{
-    // no free message buffer available - handle this problem here
-}
-</PROGRAMLISTING> 
-</SECTION> <!-- can-msgfilt-cfg -->
-  
-  
-<SECTION id="can-msgfilt-deact">
-<TITLE>Message filter deactivation</TITLE>
-
-<PARA>
-After startup of your device the CAN driver is configured for
-reception of all available CAN messages.  If you change this
-configuration by adding single message filters then you can reset this
-default state with the configuration ID:
-</PARA> 
-
-<PROGRAMLISTING> 
-CYGNUM_CAN_MSGBUF_RX_FILTER_ALL
-</PROGRAMLISTING> 
-
-<PARA>
-This message buffer configuration id will clear all message filters
-and remote buffers and prepares the CAN hardware for reception of any
-kind of CAN standard and extended frames. It is not necessary to reset
-the message buffer configuration before this configuration step is
-executed because this should be done by device driver.
-</PARA> 
-   
-<PARA>
-Example code for deactivation of message filtering:
-</PARA>
-
-<PROGRAMLISTING> 
-cyg_can_filter rx_filter;
-
-// now setup a RX all configuration
-rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
-len = sizeof(rx_filter);
-if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
-                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
-                                &amp;rx_filter, &amp;len))
-{
-    CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
-}
-</PROGRAMLISTING> 
-</SECTION> <!-- can-msgfilt-cfg -->
-</SECTION>  
-</CHAPTER>
-
-<CHAPTER id="io-can-configuration">
-<TITLE>Configuration</TITLE>
-
-<PARA>
-The CAN subsystem has a number of configuration options.
-</PARA>
-
-<variablelist>
-   <varlistentry>
-       <term><type>cdl_interface CYGINT_IO_CAN_TIMESTAMP</type></term>
-           <listitem><para>
-A hardware device driver that supports timestamps should implement this interface.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_TIMESTAMP</type></term>
-           <listitem><para>
-If the CAN hardware driver supports some kind of timestamps then this option enables 
-propagation of timestamps to higher layers. This may add some extra code to hardware 
-drivers.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT</type></term>
-           <listitem>
-<para> This option enables support for TX
-events. If a CAN message is transmitted successfully a TX event will
-be inserted into the receive event queue and propagated to higher
-layers.  If this option is enabled the RX event queue will be filled
-faster.
-</para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</type></term>
-           <listitem>
-<para>
-This option enables extra code in the generic CAN driver which allows
-clients to switch read() and write() call semantics from blocking to
-non-blocking.
-</para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_READ</type></term>
-           <listitem><para>
-The initial timeout value in clock ticks for <FUNCTION>cyg_io_read()</FUNCTION> calls.
-          </para></listitem>
-   </varlistentry>
-   <varlistentry>
-       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_WRITE</type></term>
-           <listitem><para> The initial timeout value in clock ticks
-for <FUNCTION>cyg_io_write()</FUNCTION> calls.
-          </para></listitem>
-   </varlistentry>
-</variablelist>
-</CHAPTER>
-
-
-<CHAPTER id="io-can-device-drivers">
-<TITLE>Writing a CAN hardware device driver</TITLE>
-
-<PARA>
-A CAN driver is nothing more than a named entity that supports the
-basic I/O functions - read, write, get config, and set config. The
-device driver 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.
-</PARA>
-
-<PARA>
-That said, the reason for using a device driver is to provide access
-to a CAN 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.
-</PARA>
-
-<PARA>
-Like other device drivers the CAN device driver is concerned with the
-movement of information - the CAN messages. 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 CAN device typically generates an
-interrupt after a CAN message has been sent or a CAN message has been
-received by a CAN hardware message buffer. 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 CAN message as soon as the current one is complete,
-without any active participation by the application code.
-</PARA>
-
-<PARA>
-The main building blocks for CAN device drivers are found in the
-include files
-<filename>&lt;cyg/io/devtab.h&gt;</filename> and <filename>&lt;cyg/io/can.h&gt;</filename>
-</PARA>
-
-<PARA>
-Like many other device drivers in eCos, CAN device drivers are described by a device 
-table entry, using the <type>cyg_devtab_entry_t</type> type. The entry should be created using 
-the <varname>DEVTAB_ENTRY()</varname> macro.
-</PARA>
-
-
-<SECTION id="io-can-how-to-write-interface-driver">
-<TITLE>How to Write a CAN Hardware Interface Driver</TITLE>
-
-<PARA>
-The standard CAN driver supplied with eCos is structured as a hardware
-independent portion and a hardware dependent interface module. To add
-support for a new CAN device, 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.
-</PARA>
-
-<PARA>
-The interfaces used by the CAN driver and CAN implementation modules
-are contained in the file <filename>&lt;cyg/io/can.h&gt;</filename>.
-</PARA>
-
-<SECTION>
-<title>DevTab Entry</TITLE>
-
-<PARA>
-The interface module contains the devtab entry (or entries if a single
-module supports more than one interface). This entry should have the
-form:
-</PARA>
-
-<PROGRAMLISTING> 
-DEVTAB_ENTRY(&lt;&lt;module_name&gt;&gt;, 
-             &lt;&lt;device_name&gt;&gt;,
-             0,
-             &amp;can_devio, 
-             &lt;&lt;module_init&gt;&gt;, 
-             &lt;&lt;module_lookup&gt;&gt;,
-             &amp;&lt;&lt;can_channel&gt;&gt;
-            );
-</PROGRAMLISTING> 
-
-<variablelist>
-<title>Arguments</title>
-  <varlistentry>
-    <term><parameter>module_name</parameter></term>
-    <listitem><para>The "C" label for this devtab entry</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>device_name</parameter></term>
-    <listitem><para>The "C" string for the
-    device. E.g. <filename>/dev/can0</filename>.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>can_devio</parameter></term>
-    <listitem><para>The table of I/O functions. This set is defined in
-    the hardware independent CAN driver and should be used.</para>
-    </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>module_init</parameter></term>
-    <listitem><para>The hardware module initialization function.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>module_lookup</parameter></term>
-    <listitem><para>The device lookup function. This function
-    typically sets up the CAN device for actual use, turning on
-    interrupts, configuring the message buffers, etc.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>can_channel</parameter></term>
-    <listitem><para>This table (defined below) contains the interface
-    between the interface module and the CAN driver proper.</para></listitem>
-  </varlistentry>
-</variablelist>
-
-<PARA>
-Example devtab entry for Motorola FlexCAN device driver:
-</PARA>
-
-<PROGRAMLISTING>
-DEVTAB_ENTRY(flexcan_devtab, 
-             CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN0_NAME,
-             0,                     // Does not depend on a lower level interface
-             &amp;cyg_io_can_devio, 
-             flexcan_init, 
-             flexcan_lookup,        // CAN driver may need initializing
-             &amp;flexcan_can0_chan
-    );
-</PROGRAMLISTING>
-</SECTION>
-
-
-<SECTION>
-<title>CAN Channel Structure</TITLE>
-
-<PARA>
-Each CAN device must have a &ldquo;CAN channel&rdquo;.
-This is a set of data which describes all operations on the device.
-It also contains buffers, etc. The CAN channel is created by the macro: 
-</PARA>
-
-<PROGRAMLISTING>
-CAN_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,
-                             out_buf, out_buflen,
-                             in_buf,  in_buflen)
-</PROGRAMLISTING>
-
-<variablelist>
-  <title>Arguments</title>
-  <varlistentry>
-    <term><parameter>l</parameter></term>
-    <listitem><para>The "C" label for this structure.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>funs</parameter></term>
-    <listitem><para>The set of interface functions (see below).</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>dev_priv</structfield></term>
-    <listitem><para>A placeholder for any device specific data for
-    this channel.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>baud</structfield></term>
-    <listitem><para>The initial baud rate value
-    (<type>cyg_can_baud_rate_t</type>).</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>out_buf</structfield></term>
-    <listitem><para>Pointer to the output buffer</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>out_buflen</structfield></term>
-    <listitem><para>The length of the output buffer.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>in_buf</structfield></term>
-    <listitem><para>pointer to the input buffer.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>in_buflen</structfield></term>
-    <listitem><para>The length of the input buffer.</PARA></listitem>
-  </varlistentry>
-</variablelist>
-
-<PARA>
-Example CAN channel implementation for Motorola FlexCAN device driver:
-</PARA>
-
-<PROGRAMLISTING>
-CAN_CHANNEL_USING_INTERRUPTS(
-    flexcan_can0_chan,
-    flexcan_lowlevel_funs,
-    flexcan_can0_info,
-    CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_KBAUD),
-    flexcan_can0_txbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_TX,
-    flexcan_can0_rxbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_RX
-);
-</PROGRAMLISTING>
-
-<PARA>
-The interface from the hardware independent driver into the hardware
-interface module is contained in the <structfield>funs</structfield>
-table.  This is defined by the macro:
-</PARA>
-</SECTION>
-
-<SECTION>
-<TITLE>CAN Lowlevel Functions Structure</TITLE>
-
-<PROGRAMLISTING>
-CAN_LOWLEVEL_FUNS(l, putmsg, getevent, get_config, set_config, start_xmit, stop_xmit)
-</PROGRAMLISTING>
-
-<variablelist>
-  <title>Arguments</title>
-  <varlistentry>
-    <term><structfield>l</structfield></term>
-    <listitem><para>The "C" label for this structure.</para></listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>putmsg</structfield></term>
-    <listitem>
-      <para><literal>
-      bool (*putmsg)(can_channel *priv, cyg_can_message *pmsg, void *pdata)
-      </literal></para>
-      <para>
-      This function sends one CAN message to the interface. It should
-      return <literal>true</literal> if the message is actually
-      consumed. It should return <literal>false</literal> if there is
-      no space in the interface
-      </para>
-    </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>getevent</structfield></term>
-    <listitem>
-      <para><literal>
-      bool (*getevent)(can_channel *priv, cyg_can_event *pevent, void *pdata)
-      </literal></para>
-      <para>
-      This function fetches one event from the interface.
-      </para>
-    </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>get_config</structfield></term>
-    <listitem>
-      <para><literal> 
-      Cyg_ErrNo (*get_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
-      </literal></para>
-      <para>
-        This function is used to query the configuration of a CAN channel.
-      </para>
-    </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><structfield>set_config</structfield></term>
-    <listitem>
-      <para><literal> 
-      Cyg_ErrNo (*set_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
-      </literal></para>
-      <para>
-        This function is used to change configuration of a CAN channel.
-      </para>
-    </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>start_xmit</parameter></term>
-    <listitem><para><literal>void (*start_xmit)(can_channel *priv)</literal></para>
-      <para>
-        Enable the transmit channel and turn on transmit interrupts.
-      </para>
-    </listitem>
-  </varlistentry>
-  <varlistentry>
-    <term><parameter>stop_xmit</parameter></term>
-    <listitem>
-      <para><literal>void (*stop_xmit)(can_channel *priv)</literal></para>
-      <para>Disable the transmit channel and turn transmit interrupts off.</PARA>
-    </listitem>
-  </varlistentry>
-</variablelist>
-
-<PARA>
-Example implementation of low level function structure for Motorola FlexCAN 
-device driver:
-</PARA>
-
-<PROGRAMLISTING>
-CAN_LOWLEVEL_FUNS(flexcan_lowlevel_funs,
-                  flexcan_putmsg,
-                  flexcan_getevent,
-                  flexcan_get_config,
-                  flexcan_set_config,
-                  flexcan_start_xmit,
-                  flexcan_stop_xmit
-     );
-</PROGRAMLISTING>
-</SECTION>
-
-<SECTION>
-<TITLE>Callbacks</TITLE>
-
-<PARA>
-The device interface module can execute functions in the
-hardware independent driver via <literal>chan-&gt;callbacks</literal>.
-These functions are available:
-</PARA>
-
-<PROGRAMLISTING>
-void (*can_init)(can_channel *chan)
-</PROGRAMLISTING>
-
-<PARA>This function is used to initialize the CAN channel.</PARA>
-
-<PROGRAMLISTING>
-void (*xmt_msg)(can_channel *chan, void *pdata)
-</PROGRAMLISTING>
-
-<PARA>
-This function would be called from an interrupt handler after a
-transmit interrupt indicating that additional messages may be
-sent. The upper driver will call the <function>putmsg</function>
-function as appropriate to send more data to the device.
-</PARA>
-
-<PROGRAMLISTING>
-void (*rcv_event)(can_channel *chan, void *pdata)
-</PROGRAMLISTING>
-
-<PARA>
-This function is used to tell the driver that a message has arrived
-at the interface or that an event has occurred. This function is typically 
-called from the interrupt handler. 
-</PARA>
-</SECTION><!-- Callbacks -->
-
-</SECTION><!-- id="io-can-how-to-write-interface-driver" -->
-</CHAPTER>
-
-</PART>
+<!-- {{{ Banner                         -->
+
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!--     can.sgml                                                    -->
+<!--                                                                 -->
+<!--     Generic CAN documentation.                                  -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- ####COPYRIGHTBEGIN####                                          -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+<!-- Copyright (C) 2004 eCosCentric Limited                          -->
+<!-- This material may be distributed only subject to the terms      -->
+<!-- and conditions set forth in the Open Publication License, v1.0  -->
+<!-- or later (the latest version is presently available at          -->
+<!-- http://www.opencontent.org/openpub/)                            -->
+<!-- Distribution of the work or derivative of the work in any       -->
+<!-- standard (paper) book form is prohibited unless prior           -->
+<!-- permission obtained from the copyright holder                   -->
+<!-- =============================================================== -->
+<!--                                                                 -->
+<!-- ####COPYRIGHTEND####                                            -->
+<!-- =============================================================== -->
+<!-- #####DESCRIPTIONBEGIN####                                       -->
+<!--                                                                 -->
+<!-- Author(s):   Uwe Kindler                                        -->
+<!-- Date:        2006/12/04                                         -->
+<!--                                                                 -->
+<!-- ####DESCRIPTIONEND####                                          -->
+<!-- =============================================================== -->
+
+<!-- }}} -->
+
+<PART id="io-can"><title>CAN Support</title>
+
+<CHAPTER id="io-can-overview">
+<TITLE>Overview</TITLE>
+
+<SECTION id="io-can-overview-descr">
+<TITLE>Description</TITLE>
+
+<PARA>
+The Controller Area Network, CAN, is a multicast shared, differential 
+serial bus standard especially suited for networking "intelligent" 
+devices as well as sensors and actuators within a system or sub-system. 
+The protocol was originally developed in the 1980s by Robert Bosch GmbH 
+aiming at automotive applications. Nowadays CAN has gained widespread use 
+and is used in industrial automation as well as in automotive, mobile 
+machines and in many embedded control applications.
+</PARA>
+    
+<PARA>
+The CAN protocol is defined by the ISO 11898-1 standard. The physical layer 
+uses differential transmission on a twisted pair wire.  CAN uses a 
+non-destructive bit-wise arbitration to control access to the bus.
+</PARA>
+    
+<PARA>
+There is no explicit address in the messages because in CAN networks there 
+is no addressing of subscribers or stations, but instead, each message carries 
+a prioritized identifier. A transmitter sends a message to all CAN nodes 
+(broadcasting). The identifier may serve as an identification of the contents 
+of the message and also determines the priority that the message enjoys in 
+competition for bus access. A node decides on the basis of this identifier 
+received whether it should process the message or not.
+</PARA>
+    
+<PARA>
+The CAN messages are small (at most eight data bytes) and are protected 
+by a checksum. Each CAN message consists of  an 11 bit message ID, up to 8 
+bytes of data and, a CRC checksum and a number of  control bits. These 
+short messages ensure a robust transfer of data in electromagnetically 
+noisy environments. An extended version of the CAN frame supports 29 bit 
+message identifiers.
+</PARA>
+    
+<PARA>
+Basically there are two different operational modes for CAN receivers - 
+FullCAN and BasicCAN.  The difference between these two modes is the 
+Object Storage function. The BasicCAN architecture is quite similar to a 
+simple UART. A BasicCAN device has typically one transmit buffer and two 
+receive buffers. The CAN chip handles only the transmitting and receiving 
+of the data (and the error handling) and so most of the manipulation of the 
+data has to be done by the CPU. The CPU has to request the transmitting or 
+acknowledge the receiving of the data through the interrupt flags. This will 
+burden the CPU and take up much of the CPU time. 
+</PARA>
+
+<PARA>
+The FullCAN architecture is more suitable for high-speed performance. It 
+has its own storage area on chip and works with a number of message buffers 
+or message boxes. The CAN controller has its own Acceptance Filtering Mask 
+on chip. It can thus determine which frames are to be received by examining 
+the identifiers. The CPU in this case will only receive the valid (wanted) 
+frames and hence improve the performance of the CPU.
+</PARA>
+    
+<PARA>
+You can find more information at the 
+<ulink url="http://www.can-cia.org/">CAN in Automation</ulink> website.
+</PARA>
+
+</SECTION> <!-- "io-can-description" -->
+
+<SECTION id="io-can-ecos-support">
+<TITLE>eCos Support for CAN</TITLE>
+
+<PARA>
+The eCos CAN subsystem supports the BasicCAN and FullCAN mode. The architecture 
+and the interface of the eCos CAN driver is quite similar to the eCos serial 
+driver and supports the same interface.
+</PARA>
+
+<PARA>
+The eCos CAN support for any given platform is spread over a number of different 
+packages: 
+</PARA>
+
+<itemizedlist>
+  <listitem>
+    <para>
+
+This package, <varname>CYGPKG_IO_CAN</varname>, exports a generic
+device independent CAN I/O API for accessing devices attached to a CAN
+network. This API handles issues such as locking between threads. The
+package does not contain any hardware-specific code. Instead it will
+call into a CAN device driver to handle the hardware device
+access. This package also defines the inderface that such hardware
+drivers should provide.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+Each CAN device will have its own device driver, which is implemented 
+as a separate package, for example 
+<varname>CYGPKG_DEVS_CAN_MCF52xx_FLEXCAN</varname>. For devices that may 
+be attached to a variety of different boards the device driver will be 
+generic and a second platform specific package will be used to customize 
+it to each platform. For devices that are associated with a specific 
+chipset, only a single package may be present.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<PARA>
+Typically all appropriate packages will be loaded automatically when 
+you configure eCos for a given platform. If the application does not use 
+any of the CAN I/O facilities, directly or indirectly, then linker garbage 
+collection should eliminate all unnecessary code and data. All necessary 
+initialization should happen automatically. However the exact details may 
+depend on the platform, so the platform HAL documentation should be 
+checked for further details.
+</PARA>
+    
+<PARA>
+There is an important exception to this: if the CAN devices are attached 
+to an expansion connector, such as PCI, then the platform HAL will not 
+know about these devices. Instead the necessary packages will need to be 
+added explicitly during configuration.
+</PARA>
+</SECTION>
+</CHAPTER>
+
+<CHAPTER id="io-can-api">
+<TITLE>User API</TITLE>
+
+<PARA>
+The CAN driver uses the standard eCos I/O API functions. All functions 
+except <function>cyg_io_lookup()</function> require an I/O "handle".
+</PARA>
+
+<PARA>
+All functions return a value of the type <type>Cyg_ErrNo</type>. 
+If an error condition is detected, this value will be negative and the 
+absolute value indicates the actual error, as specified in 
+<filename>cyg/error/codes.h</filename>. The only other legal return values 
+will be <varname>ENOERR</varname>, <varname>-EINTR</varname> and 
+<varname>-EAGAIN</varname>. All other function arguments are pointers 
+(references). This allows the drivers to pass information efficiently, 
+both into and out of the driver. The most striking example of this is the 
+<parameter>len</parameter> value passed to the read and write functions. 
+This parameter contains the desired length of data on input to the 
+function and the actual transferred length on return.
+</PARA>
+    
+<PROGRAMLISTING>
+// Lookup a CAN device and return its handle 
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_lookup</function>( 
+    const char <parameter>*name</parameter>,
+    cyg_io_handle_t <parameter>*handle</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function maps a CAN device name onto an appropriate handle. If the
+named device is not in the system, then the error
+<varname>-ENOENT</varname> is returned. If the device is found, then
+the handle for the device is returned by way of the handle pointer
+<parameter>*handle</parameter>.
+</PARA>
+
+<PROGRAMLISTING>
+// Send a CAN message
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_write</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    const void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function sends one single CAN message (not a buffer of CAN messages) 
+to a device. The size of data to send is contained in 
+<parameter>*len</parameter> and the actual size sent will be returned in 
+the same place.
+</PARA>
+
+<PROGRAMLISTING>
+// Read one CAN event from device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_read</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function receives one single CAN event from a device. The desired size 
+of data to receive is contained in <parameter>*len</parameter> and the 
+actual size obtained will be returned in the same place. 
+</PARA>
+
+<PROGRAMLISTING>
+// Read configuration of a CAN device
+Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_get_config</FUNCTION>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    cyg_uint32 <parameter>key</parameter>,
+    void *<parameter>buf</parameter>,
+    cyg_uint32 *<parameter>len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a
+device. The type of information retrieved is specified by the
+<parameter>key</parameter>. The data will be returned in the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data requested, which must be at least as large as the size
+appropriate to the selected key. The actual size of data retrieved is
+placed in <parameter>*len</parameter>. The appropriate key values 
+are all listed in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.
+</PARA>
+
+<PROGRAMLISTING>
+// Change configuration of a CAN device
+Cyg_ErrNo <!-- <index></index> --><function>cyg_io_set_config</function>( 
+    cyg_io_handle_t <parameter>handle</parameter>,
+    cyg_uint32 <parameter>key</parameter>,
+    const void <parameter>*buf</parameter>,
+    cyg_uint32 <parameter>*len</parameter> )
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time
+configuration of a device. The type of information is specified by the
+<parameter>key</parameter>. The data will be obtained from the given
+buffer. The value of <parameter>*len</parameter> should contain the
+amount of data provided, which must match the size appropriate to the
+selected key.  The appropriate key values are all listed in the file
+<filename>&lt;cyg/io/config_keys.h&gt;</filename>.
+</PARA> 
+</CHAPTER>   
+
+<CHAPTER id="io-can-driver-details">
+<TITLE>CAN driver details</TITLE>
+
+<PARA>
+Allow applications and other packages to access CAN devices.
+</PARA>
+
+<SECTION id="io-can-driver-description">
+<TITLE>Description</TITLE>
+
+<PARA>
+A raw CAN driver is is provided as a standard part of the eCos system.
+</PARA>
+
+<PARA>
+Use the include file <filename>&lt;cyg/io/canio.h&gt;</filename> for this driver.
+</PARA>
+    
+<PARA>
+The CAN driver is capable of sending single CAN messages to a device and 
+receiving single CAN events from a CAN device. Controls are provided to 
+configure the actual hardware, but there is no manipulation of the data by 
+this driver. 
+</PARA>
+    
+<PARA>
+There may be many instances of this driver in a given system, one for each 
+CAN channel. Each channel corresponds to a physical device and there will 
+typically be a device module created for this purpose. The device modules 
+themselves are configurable, allowing specification of the actual hardware 
+details.     
+</PARA>
+</SECTION>
+
+<SECTION id="io-can-api-details">
+<TITLE>API Details</TITLE>
+
+<SECTION>
+<TITLE>cyg_io_write</TITLE>
+  
+<PROGRAMLISTING>
+cyg_io_write(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To transmit a message an application must fill a <type>cyg_can_message</type>
+buffer and call <function>cyg_io_write()</function>.
+This function sends one single CAN message (not a buffer of CAN messages) 
+to a device. The size of data to send is contained in <parameter>*len</parameter> 
+and the actual size sent will be returned in the same place. A pointer to a
+<type>cyg_can_message</type> is contained in <parameter>*buf</parameter>. 
+The driver maintains a buffer to hold the data. The size of the intermediate
+buffer is configurable within the interface module. The data is not modified 
+at all while it is being buffered. On return, <parameter>*len</parameter> 
+contains the amount of characters actually consumed - that means 
+<parameter>*len</parameter> always contains 
+<function>sizeof(cyg_can_message)</function>.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be blocking (default) or 
+non-blocking. Non-blocking mode requires both the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, and 
+the specific device to be set to non-blocking mode for writes 
+(see <function>cyg_io_set_config()</function>). In blocking mode, the 
+call will not return until there is space in the buffer and the content 
+of the CAN message has been consumed. In non-blocking mode, if there is 
+no space in buffer for the CAN message, <varname>-EAGAIN</varname> is 
+returned and the caller must try again.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout. 
+None-blocking mode with timeout requires the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, requires 
+the eCos kernel package to be included and the specific device to be set 
+to non-blocking mode for writes (see <function>cyg_io_set_config()
+</function>). 
+In non-blocking mode with timeouts, if there is no space in buffer for the 
+CAN message, the driver waits a certain amount of time (the timeout time) 
+for space in the buffer. If there is still no space in buffer after 
+expiration of the timeout time, <varname>-EINTR</varname> is returned and 
+the caller must try again.
+</PARA>
+    
+<PARA>
+If a message was sucessfully sent, the function returns <varname>ENOERR</varname>.
+</PARA>
+</SECTION>
+    
+<SECTION>  
+<TITLE>CAN Messages</TITLE>
+    
+<PARA>
+The CAN driver uses <structname>cyg_can_message</structname> structures to 
+pass messages between the application and the CAN driver. The type 
+cyg_can_message provides a device independent type of CAN message. 
+Before calling the write function this message should be setup properly.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct can_message
+{
+    cyg_uint32         id;
+    cyg_uint8          data[8];
+    cyg_can_id_type    ext;
+    cyg_can_frame_type rtr;
+    cyg_uint8          dlc;
+} cyg_can_message;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+ 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>id</varname></term>
+           <listitem><para>
+Message ID. This is the ID to be transmitted with the message, or the 
+ID received. If the <structfield>ext</structfield> field is set, then 
+this will contain a 29 bit ID, otherwise it will contain an 11 bit ID.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>data</varname></term>
+           <listitem><para>
+Message data. Only the first <structfield>dlc</structfield> bytes of 
+data are valid. If the <structfield>rtr</structfield> field is set, 
+then the contents of this field are ignored.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_id_type</type> <varname>ext</varname></term>
+           <listitem><para>
+Extended ID. If this field is <varname>CYGNUM_CAN_ID_EXT</varname> then the 
+<structname>id</structname> field contains a 29 bit extended ID. If it 
+contains <varname>CYGNUM_CAN_ID_STD</varname> then the ID is 11 bits.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_frame_type</type> <varname>rtr</varname></term>
+           <listitem><para>
+Remote Transmission Request. If this field contains 
+<varname>CYGNUM_CAN_FRAME_RTR</varname> then the RTR bit on the message 
+will be set and the <structfield>data</structfield> field will be ignored. 
+If the field contains <varname>CYGNUM_CAN_FRAME_DATA</varname> then a 
+normal data frame will be send.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>dlc</varname></term>
+           <listitem><para>
+The length of the data carried in the message. This can range from 
+zero to 8. In a message with the <structfield>rtr</structfield> field set, 
+this indicates the size of data being requested.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for sending one single CAN message:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_message tx_msg;
+cyg_uint32      len;
+Cyg_ErrNo       ret;
+
+tx_msg.id  = 0x100;
+tx_msg.ext = CYGNUM_CAN_ID_EXT;
+tx_msg.rtr = CYGNUM_CAN_FRAME_DATA;
+tx_msg.dlc = 1;
+tx_msg.data[0] = 0xF1;
+
+len = sizeof(tx_msg);
+ret = cyg_io_write(hDrvCAN, &amp;tx_msg, &amp;len);
+</PROGRAMLISTING>       
+</SECTION><!-- can-cyg_can_message -->
+
+<SECTION>
+<TITLE>cyg_io_read</TITLE> 
+ 
+<PROGRAMLISTING>
+cyg_io_read(handle, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+To receive a message the application calls <function>cyg_can_recv()</function>.
+This function receives one single event from a device. The desired size 
+of data to receive is contained in <parameter>*len</parameter> and the
+actual size obtained will be returned in the same place. A pointer to 
+a <type>cyg_can_event</type> is contained in <parameter>*buf</parameter>. 
+No manipulation of the data is performed before being transferred. 
+Again, this buffering is completely configurable. On return, 
+<parameter>*len</parameter> contains <function>sizeof(cyg_can_event)</function>.
+</PARA>
+   
+<PARA>    
+It is possible to configure the read call to be blocking (default) or 
+non-blocking. Non-blocking mode requires both the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> to be enabled, 
+and the specific device to be set to non-blocking mode for reads 
+(see <function>cyg_io_set_config()</function>). In blocking mode, 
+the call will not return until one single CAN event has been read. 
+In non-blocking mode, if there is no CAN event in buffer, the call 
+returns immediately with <varname>-EAGAIN</varname> and the caller must 
+try again.
+</PARA>
+    
+<PARA>
+It is possible to configure the write call to be non-blocking with timeout. 
+None-blocking mode with timeout requires the configuration option 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> and 
+<varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> to be enabled, 
+requires the eCos kernel package to be included and the specific device 
+to be set to non-blocking mode for reads (see 
+<function>cyg_io_set_config()</function>). In non-blocking mode with timeouts, 
+if there is no CAN event in receive buffer, the driver waits a certain amount 
+of time (the timeout time) for a CAN event to arrive. If there is still no 
+CAN event in buffer after expiration of the timeout time, <varname>-EINTR</varname> 
+is returned and the caller must try again.
+</PARA>
+    
+<PARA>
+If a event was sucessfully received, the function returns <varname>ENOERR</varname>.    
+</PARA>
+</SECTION><!-- cyg_io_read -->
+
+
+<SECTION>  
+<TITLE>CAN Events</TITLE>
+
+<PARA>
+The CAN driver uses <structname>cyg_can_event</structname> structures to
+pass events from hardware device driver to the generic CAN driver.
+A <structname>cyg_can_event</structname> provides a generic device 
+independent type for handling CAN events that may occur.
+</PARA> 
+
+<PROGRAMLISTING>
+typedef struct cyg_can_event_st
+{
+    cyg_uint32      timestamp;
+    cyg_can_message msg;
+    cyg_uint16      flags;
+} cyg_can_event;
+</PROGRAMLISTING>
+
+<PARA>
+The structure contains the following fields:
+</PARA>
+ 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>timestamp</varname></term>
+           <listitem><para>
+If the hardware CAN device driver supports timestamps then this field may 
+contain a timestamp value for an event that occured.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+CAN message. The msg field contains a CAN message if an RX or TX event
+occured.  If another type of event occured,
+the <structfield>data</structfield> field of
+the <structfield>msg</structfield> may contain additional event
+specific data.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint16</type> <varname>flags</varname></term>
+           <listitem><para>
+Event flags. The <varname>flags</varname> field contains 16 bits that 
+indicate which kind of events occured. 
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+    
+<PARA>
+The following events are supported and after receiving an event the 
+application should check the flag field against these values:
+</PARA>
+    
+<PROGRAMLISTING>
+typedef enum
+{
+  CYGNUM_CAN_EVENT_RX               = 0x0001, // message received
+  CYGNUM_CAN_EVENT_TX               = 0x0002, // message transmitted
+  CYGNUM_CAN_EVENT_WARNING_RX       = 0x0004, // (TEC) reached warning level (>96)
+  CYGNUM_CAN_EVENT_WARNING_TX       = 0x0008, // (REC) reached warning level (>96)
+  CYGNUM_CAN_EVENT_ERR_PASSIVE      = 0x0010, // CAN "error passive" occured
+  CYGNUM_CAN_EVENT_BUS_OFF          = 0x0020, // CAN "bus off" error occured
+  CYGNUM_CAN_EVENT_OVERRUN_RX       = 0x0040, // overrun in RX queue or hardware 
+  CYGNUM_CAN_EVENT_OVERRUN_TX       = 0x0080, // overrun in TX queue occured
+  CYGNUM_CAN_EVENT_CAN_ERR          = 0x0100, // a CAN bit or frame error occured
+  CYGNUM_CAN_EVENT_LEAVING_STANDBY  = 0x0200, // CAN hardware leaves standby
+  CYGNUM_CAN_EVENT_ENTERING_STANDBY = 0x0400, // CAN hardware enters standby
+  CYGNUM_CAN_EVENT_ARBITRATION_LOST = 0x0800, // arbitration lost
+  CYGNUM_CAN_EVENT_FILTER_ERR       = 0x1000, // CAN message filter / acceptance filter error
+  CYGNUM_CAN_EVENT_PHY_FAULT        = 0x2000, // General failure of physical layer 
+  CYGNUM_CAN_EVENT_PHY_H            = 0x4000, // Fault on CAN-H (Low Speed CAN)
+  CYGNUM_CAN_EVENT_PHY_L            = 0x8000, // Fault on CAN-L (Low Speed CAN)
+} cyg_can_event_flags;
+</PROGRAMLISTING>
+
+<PARA>
+Often the flags field will contain only one single set flag. But it is 
+possible that a number of flags is set and so the flag field should always 
+be checked by a receiver. I.e. if the <varname>CYGNUM_CAN_EVENT_RX</varname> 
+is set then also the <varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> 
+may be set if the received message caused an RX overrun.
+</PARA>
+    
+<PARA>
+The internal receive buffers of the CAN device driver are circular buffers. 
+That means that even if the buffers are completely filled new messages 
+will be received. In this case the newest message will always overwrite 
+the oldest message in receive buffer. If this happens the 
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set for this 
+new message that caused overwriting of the old one. The 
+<varname>CYGNUM_CAN_EVENT_OVERRUN_RX</varname> flag will be set also if 
+a overrun occures in hardware message buffers of the CAN device.
+</PARA>
+    
+<PARA>
+Example code for receiving one single CAN event:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_event rx_event;
+cyg_uint32    len;
+Cyg_ErrNo     ret;
+
+len = sizeof(rx_event);
+ret = cyg_io_read(hDrvCAN, &amp;rx_event, &amp;len);
+
+if (ENOERR == ret)
+{
+    if (rx_event.flags &amp; CYGNUM_CAN_EVENT_RX)
+    {
+        // handle RX event
+    }
+    
+    if (rx_event.flags &amp; ~CYGNUM_CAN_EVENT_RX)
+    {
+        // handle other events
+    }
+}
+else if (-EINTR == ret)
+{
+    // handle timeout
+}
+</PROGRAMLISTING>       
+</SECTION><!-- can-cyg_can_event -->
+
+  
+<SECTION>
+<TITLE>cyg_io_get_config</TITLE> 
+  
+<PROGRAMLISTING>
+cyg_io_get_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to obtain run-time configuration about a device. 
+The type of information retrieved is specified by the <parameter>key</parameter>. 
+The data will be returned in the given buffer. The value of 
+<parameter>*len</parameter> should contain the amount of data requested, 
+which must be at least as large as the size appropriate to the selected 
+<parameter>key</parameter>. The actual size of data retrieved is placed 
+in <parameter>*len</parameter>. The appropriate key values are all listed 
+in the file <filename>&lt;cyg/io/config_keys.h&gt;</filename>.    
+</PARA>   
+    
+<PARA>
+The following config keys are currently supported:
+</PARA>  
+    
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+CYG_IO_GET_CONFIG_CAN_INFO
+CYG_IO_GET_CONFIG_CAN_BUFFER_INFO
+CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO
+CYG_IO_GET_CONFIG_CAN_TIMEOUT
+CYG_IO_GET_CONFIG_CAN_HDI
+CYG_IO_GET_CONFIG_CAN_STATE
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-get-config -->
+  
+<SECTION>
+<TITLE>cyg_io_set_config</TITLE> 
+  
+<PROGRAMLISTING>
+cyg_io_set_config(handle, key, buf, len)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to manipulate or change the run-time configuration 
+of a device. The type of information is specified by the <parameter>key</parameter>. 
+The data will be obtained from the given buffer. The value of 
+<parameter>*len</parameter> should contain the amount of data provided, 
+which must match the size appropriate to the selected <parameter>key</parameter>. 
+The appropriate key values are all listed in the file 
+<filename>&lt;cyg/io/config_keys.h&gt;</filename>.  
+</PARA>   
+    
+<PARA>
+The following config keys are currently supported:
+</PARA>  
+    
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+CYG_IO_SET_CONFIG_CAN_INFO
+CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN
+CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH
+CYG_IO_SET_CONFIG_CAN_TIMEOUT
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+CYG_IO_SET_CONFIG_CAN_MODE
+CYG_IO_SET_CONFIG_CAN_ABORT
+CYG_IO_SET_CONFIG_CAN_CALLBACK
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+</SECTION><!-- io-can-api-details -->
+
+<SECTION id="io-can-runtime-cfg">  
+<TITLE>Runtime Configuration</TITLE>
+  
+<PARA>
+Runtime configuration is achieved by exchanging data structures with the 
+driver via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions.
+</PARA>
+
+<SECTION>
+<TITLE>Device configuration</TITLE>
+  
+<PROGRAMLISTING>
+typedef struct cyg_can_info_st {
+    cyg_can_baud_rate_t baud;
+} cyg_can_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Device configuration is achieved by by exchanging 
+<structname>cyg_can_info_t</structname> data structures with the driver 
+via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions using the config keys 
+<varname>CYG_IO_GET_CONFIG_CAN_INFO</varname> and 
+<varname>CYG_IO_SET_CONFIG_CAN_INFO</varname>. 
+The field <structfield>baud</structfield> contains a baud rate selection. 
+This must be one of the following values:  
+</PARA>
+  
+<PROGRAMLISTING>
+CYGNUM_CAN_KBAUD_10
+CYGNUM_CAN_KBAUD_20
+CYGNUM_CAN_KBAUD_50
+CYGNUM_CAN_KBAUD_100
+CYGNUM_CAN_KBAUD_125
+CYGNUM_CAN_KBAUD_250
+CYGNUM_CAN_KBAUD_500
+CYGNUM_CAN_KBAUD_800
+CYGNUM_CAN_KBAUD_1000
+</PROGRAMLISTING>
+</SECTION><!-- can-cyg-io-set-config -->
+  
+<SECTION>
+<TITLE>Timeout configuration</TITLE>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_timeout_info_st
+{
+    cyg_uint32 rx_timeout;
+    cyg_uint32 tx_timeout;
+} cyg_can_timeout_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+Timeout configuration is achieved by by exchanging 
+<structname>cyg_can_timeout_info_t</structname> data structures with the 
+driver via the <function>cyg_io_set_config()</function> and 
+<function>cyg_io_get_config()</function> functions using the config keys 
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname> and 
+<varname>CYG_IO_SET_CONFIG_CAN_TIMEOUT</varname>.   
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_timeout</varname></term>
+           <listitem><para>
+Timeout for <function>cyg_io_read</function> calls.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>tx_timeout</varname></term>
+           <listitem><para>
+Timeout for <function>cyg_io_write</function> calls.
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+
+<PARA>
+Timeout runtime configuration is supported if the configuration options 
+<varname>CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</varname> 
+and <varname>CYGOPT_IO_CAN_SUPPORT_TIMEOUTS</varname> are enabled. 
+</PARA>
+</SECTION><!-- can-timeout-config -->
+
+<SECTION>
+<TITLE>Reading buffer configuration</TITLE>
+    
+<PROGRAMLISTING>    
+typedef struct cyg_can_buf_info_st
+{
+    cyg_int32 rx_bufsize;
+    cyg_int32 rx_count;
+    cyg_int32 tx_bufsize;
+    cyg_int32 tx_count;
+} cyg_can_buf_info_t;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_BUFFER_INFO</varname> - This function 
+retrieves the current state of the software buffers in the CAN drivers. 
+For the transmit buffer it returns the the total number of 
+<type>cyg_can_message</type> objects in buffer and the current number of 
+<type>cyg_can_message</type> objects occupied in the buffer. 
+For the receive buffer it returns the total number of 
+<type>cyg_can_event</type> objects in receive buffer and the current 
+number of <type>cyg_can_event</type> objects occupied in the buffer. 
+It does not take into account any buffering such as FIFOs or holding 
+registers that the CAN hardware device itself may have.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_bufsize</varname></term>
+           <listitem><para>
+Total number of <type>cyg_can_event</type> buffers in receive queue.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rx_count</varname></term>
+           <listitem><para>
+Current number of <type>cyg_can_event</type> buffers occupied in receive queue.
+          </para></listitem>
+   </varlistentry>
+      <varlistentry>
+       <term><type>cyg_uint32</type> <varname>tx_bufsize</varname></term>
+           <listitem><para>
+Total number of <type>cyg_can_message</type> buffers in transmit queue.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint32</type> <varname>rtx_count</varname></term>
+           <listitem><para>
+Current number of <type>cyg_can_message</type> buffers occupied in transmit queue.
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+</SECTION>  <!-- can-read-buffer-config -->
+  
+  
+<SECTION>
+<TITLE>Reading hardware description information</TITLE>
+    
+<PROGRAMLISTING>    
+typedef struct cyg_can_hdi_st
+{
+    cyg_uint8 support_flags;
+    cyg_uint8 controller_type;
+} cyg_can_hdi;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_HDI</varname> - This function retrieves 
+information about the used hardware. The Hardware Description Interface 
+provides a method to gather information about the CAN hardware and the 
+functionality of the driver. For this purpose the structure 
+<structname>cyg_can_hdi</structname> is defined.  
+</PARA>
+     
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>support_flags</varname></term>
+           <listitem><para>
+Contains information about the capabilities of the used CAN hardware.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>controller_type</varname></term>
+           <listitem><para>
+A number that identifies the CAN controller type.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+The following flags are available in the field <structfield>support_flags</structfield>:  
+</PARA>
+     
+<PROGRAMLISTING>    
+|   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
++-------+-------+-------+-------+-------+-------+-------+-------+
+|  res  |  res  |  res  |timest.|SW-Filt|FullCAN|   Frametype   |
+</PROGRAMLISTING>
+
+<variablelist>
+  <varlistentry>
+    <term><parameter>Frametype</parameter></term>
+    <listitem><para>
+Bit 0 and Bit 1 of the structure describe the possibilities of the CAN
+controller. The following values are defined:
+    <PROGRAMLISTING>    
+CYGNUM_CAN_HDI_FRAMETYPE_STD          // receives only standard frame
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_PASSIVE  // can receive but not send extended frames
+CYGNUM_CAN_HDI_FRAMETYPE_EXT_ACTIVE   // can send and receive extended frames
+    </PROGRAMLISTING>
+    </para></listitem>
+  </varlistentry>
+    <varlistentry>
+    <term><parameter>FullCAN</parameter></term>
+    <listitem><para>
+If the Bit 2 - <varname>CYGNUM_CAN_HDI_FULLCAN </varname> - is set to one, 
+the CAN controller supports more than one message buffer.
+    </para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>SW-Filter</parameter></term>
+    <listitem><para>
+If Bit 3 - <varname>CYGNUM_CAN_HDI_FILT_SW</varname> - is set to one then 
+the CAN driver supports some kind of software message filtering.
+    </para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>Timestamp</parameter></term>
+    <listitem><para>
+If Bit 4 - <varname>CYGNUM_CAN_HDI_TIMESTAMP</varname> - is set to one then 
+the CAN hardware supports timestamps for CAN messages
+    </para></listitem>
+  </varlistentry>
+</variablelist>
+</SECTION>  <!-- can-read-buffer-config -->
+   
+<SECTION>
+<TITLE>Reading hardware message buffer configuration</TITLE>
+<PROGRAMLISTING>    
+typedef struct cyg_can_msgbox_info_st
+{
+    cyg_uint8 count; // number of message buffers available for this device
+    cyg_uint8 free;  // number of free message buffers
+} cyg_can_msgbuf_info;
+</PROGRAMLISTING>
+   
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_MSGBUF_INFO</varname> - If the CAN hardware supports 
+more than one message buffer for reception of CAN messages (flag 
+<varname>CYGNUM_CAN_HDI_FULLCAN</varname> is set while reading hardware description 
+interface with <varname>CYG_IO_GET_CONFIG_CAN_HDI</varname>) then this function 
+reads the number of message buffers the CAN hardware supports and the number of 
+free message buffers.   
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>count</varname></term>
+           <listitem><para>
+Counts the number of message buffers supported by the device.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint8</type> <varname>free</varname></term>
+           <listitem><para>
+Contains the number of free message buffers. The free message buffers are 
+available for setting up remote buffers (<varname>CYG_IO_SET_CONFIG_CAN_REMOTE_BUF</varname>) 
+and message filters (<varname>CYG_IO_SET_CONFIG_CAN_FILTER_MSG</varname>).
+          </para></listitem>
+   </varlistentry>
+</variablelist>   
+</SECTION> <!-- can-read-buffer-config -->
+   
+<SECTION>
+<TITLE>Reading state of CAN hardware</TITLE>
+
+<PROGRAMLISTING>    
+typedef enum
+{
+  CYGNUM_CAN_STATE_ACTIVE,      // CAN controller active, no errors
+  CYGNUM_CAN_STATE_STOPPED,     // CAN controller in stopped mode
+  CYGNUM_CAN_STATE_STANDBY,     // CAN controller in Sleep mode
+  CYGNUM_CAN_STATE_BUS_WARN,    // CAN controller active, warning level is reached
+  CYGNUM_CAN_STATE_ERR_PASSIVE, // CAN controller went into error passive mode
+  CYGNUM_CAN_STATE_BUS_OFF,     // CAN controller went into bus off mode
+  CYGNUM_CAN_STATE_PHY_FAULT,   // General failure of physical layer 
+  CYGNUM_CAN_STATE_PHY_H,       // Fault on CAN-H detected (Low Speed CAN)
+  CYGNUM_CAN_STATE_PHY_L,       // Fault on CAN-L detected (Low Speed CAN)
+} cyg_can_state;
+</PROGRAMLISTING>
+
+<PARA>
+<varname>CYG_IO_GET_CONFIG_CAN_STATE</varname> - This function retrieves the 
+present state of the CAN controller. Possible values are defined in the 
+<type>cyg_can_state</type> enumeration.
+</PARA>   
+</SECTION> <!-- can-read-hw-state -->
+
+
+<SECTION>
+<TITLE>Changing mode of CAN hardware</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_MODE</varname> - This function changes 
+the operating mode of the CAN controller. The identifiers for the different 
+operating modes are defined in the <type>cyg_can_mode</type> enumeration.
+</PARA>
+
+<PROGRAMLISTING> 
+typedef enum
+{
+  CYGNUM_CAN_MODE_STOP,   // set controller into stop mode
+  CYGNUM_CAN_MODE_START,  // set controller into operational mode
+  CYGNUM_CAN_MODE_STANDBY // set controller into standby / sleep mode
+} cyg_can_mode;
+</PROGRAMLISTING>
+ 
+<variablelist>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_STOP</type></term>
+           <listitem><para>
+Set controller into stop mode
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_START</type></term>
+           <listitem><para>
+Set controller into operational mode
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MODE_STANDBY</type></term>
+           <listitem><para>
+Set controller into standby / sleep mode.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Before the hardware configuration of the device is changed, that means
+if baud rate is changed or the message buffer and filter configuration
+is changed, the CAN hardware should be set into stop mode and if
+configuration is finished, then device should be set back into
+operational mode.  Before the device is set into standby mode, the
+output buffers should be flushed or drained because transmission of a
+CAN message may wake up the CAN hardware. If a received message wakes
+up the CAN hardware from standby mode then
+a <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> event will be
+inserted into receive message buffer or
+the <varname>CYGNUM_CAN_EVENT_LEAVING_STANDBY</varname> flag will be
+set for the message that caused wake up of CAN hardware.
+</PARA>
+</SECTION> <!-- can-mode-cfg -->
+   
+<SECTION>
+<TITLE>Flush or drain buffers</TITLE>
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_DRAIN</varname> - This function
+waits for any buffered output to complete. This function only
+completes when there is no more data remaining to be sent to the
+device.
+</PARA>
+   
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_OUTPUT_FLUSH</varname> - This function
+discards any buffered output for the device.
+</PARA> 
+
+<PARA>
+<varname>CYG_IO_SET_CONFIG_CAN_INPUT_FLUSH</varname> - This function
+discards any buffered input for the device.
+</PARA>
+</SECTION>
+   
+<SECTION>
+<TITLE>Configuring blocking/non-blocking calls</TITLE>
+<PARA>
+By default all calls to <function>cyg_io_read()</function>
+and <function>cyg_io_write()</function> are blocking calls. The config
+keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_READ_BLOCKING
+CYG_IO_SET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+
+<PARA>
+enable switching between blocking and nonblocking calls separatly for
+read and write calls.  If blocking calls are configured then the
+read/write functions return only if a message was stored into TX
+buffer or a event was received from RX buffer. If non-blocking calls
+are enabled and there is no space in TX buffer or RX buffer is empty
+then the function returns immediately
+with <varname>-EAGAIN</varname>.
+</PARA>
+   
+<PARA>
+If non-blocking calls are enabled and additionally timeouts are
+supported by driver, then the read/write functions wait until timeout
+value is expired and then return with <varname>-EINTR</varname>.  If
+the read/write operation succeeds during the timed wait then the
+functions return succesfully with
+<varname>ENOERR</varname>.
+</PARA>
+
+<PARA>
+To query if <function>cyg_io_read()</function>
+and <function>cyg_io_write()</function> are blocking or non-blocking
+you can use the config keys
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_GET_CONFIG_READ_BLOCKING
+CYG_IO_GET_CONFIG_WRITE_BLOCKING
+</PROGRAMLISTING>
+</SECTION> <!-- can-cfg-unblock -->
+   
+<SECTION>
+<TITLE>Message buffer management</TITLE>
+
+<PARA>
+Full CAN controllers often support more the one message buffer. These
+message buffers are often configurable for transmission or reception
+of certain CAN messages or as a remote buffers.  If a CAN hardware
+supports more than one message buffer then it is possible to configure
+the CAN hardware to receive only CAN messages with certain identifiers
+or to configure hardware support for remote buffers. If message
+filtering is done by hardware, the number of received CAN messages
+decreases and so also the time for processing received CAN messages
+and the memory required for buffering received messages
+decreases. This saves valuable memory and processing time.
+</PARA>
+
+<PARA>
+The eCos CAN driver supports a generic way of adding message filters
+or remote buffers. By default the CAN driver is configured for
+reception of any kind of CAN standard and extended
+frames. Configuration of message buffers is done by
+calling <function>cyg_io_set_config()</function> with the config key
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_MSGBUF
+</PROGRAMLISTING>
+
+<PARA>
+and by exchanging <type>cyg_can_msgbuf_cfg</type> data structures.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbox_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id; // configuration id
+    cyg_can_msgbuf_handle handle; // handle to message buffer
+    cyg_can_message msg;          // CAN message - for configuration of buffer
+} cyg_can_msgbuf_cfg;
+</PROGRAMLISTING>
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para> The <varname>cfg_id</varname> field
+contains the configuration ID that tells the driver what to do with a
+message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+Contains a reference to a certain message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+Required for configuration of message buffer parameters.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+The following configuration identifiers are supported:
+</PARA>
+
+<PROGRAMLISTING>
+CYGNUM_CAN_MSGBUF_RESET_ALL        // clears alle message buffers
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL    // cfg driver for reception of all can messages
+CYGNUM_CAN_MSGBUF_RX_FILTER_ADD    // add single message filter
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD   // add new remote response buffer
+CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE // stores data into existing remote buffer 
+</PROGRAMLISTING>
+
+<variablelist>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RESET_ALL</type></term>
+           <listitem><para>
+Clears alle message buffers - no message will be received and all remote buffers are deleted.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ALL</type></term>
+           <listitem><para>
+Configure driver for reception of all can messages
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_RX_FILTER_ADD</type></term>
+           <listitem><para>
+Add single message filter.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</type></term>
+           <listitem><para>
+Add new remote response buffer.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</type></term>
+           <listitem><para>
+Stores data into existing remote buffer (remote buffer handle required).
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for resetting all message buffers:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_msgbuf_cfg msgbox_cfg;
+
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;msgbox_cfg, &amp;len))
+{
+    // handle configuration error
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgbuf-cfg -->
+   
+   
+<SECTION>
+<TITLE>Remote frame response buffer configuration</TITLE>
+
+<PARA>
+The remote frame is a message frame which is transmitted to request a
+data frame. Some CAN hardware generates receive interrupts when a
+remote transmission request arrives. Other CAN hardware, i.e.  the
+Motorola FlexCAN module, does not generate any receive
+interrupt. These CAN hardware chips like the FlexCAN module can be
+configured to transmit a data frame automatically in response to a
+remote frame. In order to support any kind of CAN hardware the eCos CAN
+driver provides a generic handling of remote transmission requests.
+</PARA>
+
+<PARA>
+The transmission of the data frame in response to a remote frame is
+completely handled by the CAN driver.  If the hardware driver, like
+the driver for the FlexCAN module, supports hardware message buffers,
+then the response frame is automatically transmitted if a remote
+transmission request with a matching ID arrives.  If a CAN hardware
+does not provide hardware support for sending data frames in response
+to a remote frame, then this need to be implemented in software by the
+hardware device driver.
+</PARA>
+
+<PARA>
+It is always possible to add remote response buffers. It does not
+matter if the driver is configured for reception of all CAN messages
+or if message filtering is used. As long as there are free message
+buffers available, it is possible to add remote response buffers.
+</PARA>
+   
+<PARA>
+In order to respond to a remote frame, a remote frame response buffer
+need to be initialized before a data frame can be sent in response to
+a remote frame. This is achieved by by
+exchanging <type>cyg_can_remote_buf</type> data structures with the
+driver via the <function>cyg_io_set_config()</function> function using
+the config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once
+the buffer is initialized, the CAN data can be changed at any time by
+the application.
+</PARA>
+
+<PROGRAMLISTING>
+typedef struct cyg_can_msgbuf_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id; // configuration id 
+    cyg_can_msgbuf_handle handle; // handle to message buffer
+    cyg_can_message msg;          // CAN message - for configuration of buffer
+} cyg_can_remote_buf;
+</PROGRAMLISTING> 
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer (<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD</varname> or 
+<varname>CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE</varname>).
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+If there is no buffer initialized for this data, the value of the handle field need to be set to 
+<varname>CYGNUM_CAN_MSGBUF_INIT</varname>. After the call to <function>cyg_io_set_config()</function> 
+the handle field contains a valid remote buffer handle ( &gt;= 0) or the value 
+<varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+The CAN frame that should be transmitted in response to a remote frame.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Example code for setting up a remote response buffer:
+</PARA>
+
+<PROGRAMLISTING>
+cyg_can_remote_buf rtr_buf;
+
+// prepare the remote response buffer
+rtr_buf.cfg_id  = CYGNUM_CAN_MSGBUF_REMOTE_BUF_ADD;
+rtr_buf.handle  = CYGNUM_CAN_MSGBUF_INIT;
+rtr_buf.msg.id  = 0x7FF;
+rtr_buf.msg.ext = CYGNUM_CAN_ID_STD;
+rtr_buf.msg.rtr = CYGNUM_CAN_FRAME_DATA;
+rtr_buf.msg.dlc = 1;
+rtr_buf.msg.data[0] = 0xAB;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rtr_buf, &amp;len))
+{
+    // handle configuration error
+}
+
+if (rtr_buf.handle == CYGNUM_CAN_MSGBUF_NA)
+{
+    // no free message buffer available - handle this problem here
+}
+
+
+// change CAN data for a buffer that is already initialized
+rtr_buf.cfg_id = CYGNUM_CAN_MSGBUF_REMOTE_BUF_WRITE;
+rtr_buf.msg.data[0] = 0x11;
+
+len = sizeof(rtr_buf);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rtr_buf, &amp;len))
+{
+    // handle configuration error
+} 
+</PROGRAMLISTING> 
+</SECTION> <!-- can-rtrbuf-cfg -->
+    
+
+<SECTION>
+<TITLE>Message filter configuration</TITLE>
+
+<PARA>
+If message filtering is done by hardware the number of received CAN
+messages decreases and so also the time for processing received CAN
+messages and the memory required for buffering received messages
+decreases.  This saves valuable memory and processing time. The eCos
+CAN driver supports a generic way of adding message filters. By
+default the CAN driver is configured for reception of any kind of CAN
+standard and extended frames. As soon as a message filter is added,
+the CAN driver will only receive the CAN frames with the identifier of
+the CAN filter. By adding a number of message filters it is possible
+for the CAN hardware to receive an number of different CAN messages.
+</PARA>
+
+<PARA>
+Adding message filters is only possible if driver is not configured
+for reception of all available CAN messages. If the driver is
+configured for reception of all CAN messages then message buffers need
+to be reset before adding single message filters.
+</PARA>
+    
+<PARA>
+In order to add a message filter, a message buffer need to be
+initialized. This is achieved by
+exchanging <type>cyg_can_filter</type> data structures with the driver
+via the <function>cyg_io_set_config()</function> function using the
+config key <varname>CYG_IO_SET_CONFIG_CAN_MSGBUF</varname>. Once the
+buffer is initialized, the CAN hardware can receive messages with the
+identifier of the filter.
+</PARA>
+
+<PROGRAMLISTING> 
+typedef struct cyg_can_msgbox_cfg_st
+{
+    cyg_can_msgbuf_cfg_id cfg_id;
+    cyg_can_msgbuf_handle handle;
+    cyg_can_message       msg;
+} cyg_can_filter;
+</PROGRAMLISTING> 
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_msgbuf_cfg_id</type> <varname>cfg_id</varname></term>
+           <listitem><para>
+The <varname>cfg_id</varname> field contains the configuration ID that tells the driver what to do with 
+a message buffer.
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_msgbuf_handle</type> <varname>handle</varname></term>
+           <listitem><para>
+After the call to <function>cyg_io_set_config()</function> the handle field contains a valid value 
+( &gt;= 0) or the value <varname>CYGNUM_CAN_MSGBUF_NA</varname> ( &lt; 0) if no free buffer is available. 
+          </para></listitem>
+   </varlistentry>
+    <varlistentry>
+       <term><type>cyg_can_message</type> <varname>msg</varname></term>
+           <listitem><para>
+The fields <structfield>id</structfield> and <structfield>ext</structfield> of the <structfield>msg</structfield>
+configure the type of message to receive by a certain message filter.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+<PARA>
+Before adding message filters the device should be stopped and after
+configuration it should be set into operational mode again.
+</PARA>
+
+<PARA>
+Example code for setting up a message filter:   
+</PARA>
+
+<PROGRAMLISTING> 
+cyg_can_msgbuf_cfg msgbox_cfg;
+cyg_can_filter rx_filter;
+
+// reset all message buffers
+msgbox_cfg.cfg_id = CYGNUM_CAN_MSGBUF_RESET_ALL;
+len = sizeof(msgbox_cfg);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN, 
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;msgbox_cfg, &amp;len))
+{
+    // handle configuration error
+}
+
+// prepare the message filter
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ADD
+rx_filter.msg.id  = 0x800;
+rx_filter.msg.ext = CYGNUM_CAN_ID_EXT;
+
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rx_filter, &amp;len))
+{
+    // handle configuration error;
+}
+else if (CYGNUM_CAN_MSGBUF_NA == rx_filter.handle)
+{
+    // no free message buffer available - handle this problem here
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgfilt-cfg -->
+  
+  
+<SECTION id="can-msgfilt-deact">
+<TITLE>Message filter deactivation</TITLE>
+
+<PARA>
+After startup of your device the CAN driver is configured for
+reception of all available CAN messages.  If you change this
+configuration by adding single message filters then you can reset this
+default state with the configuration ID:
+</PARA> 
+
+<PROGRAMLISTING> 
+CYGNUM_CAN_MSGBUF_RX_FILTER_ALL
+</PROGRAMLISTING> 
+
+<PARA>
+This message buffer configuration id will clear all message filters
+and remote buffers and prepares the CAN hardware for reception of any
+kind of CAN standard and extended frames. It is not necessary to reset
+the message buffer configuration before this configuration step is
+executed because this should be done by device driver.
+</PARA> 
+   
+<PARA>
+Example code for deactivation of message filtering:
+</PARA>
+
+<PROGRAMLISTING> 
+cyg_can_filter rx_filter;
+
+// now setup a RX all configuration
+rx_filter.cfg_id = CYGNUM_CAN_MSGBUF_RX_FILTER_ALL;
+len = sizeof(rx_filter);
+if (ENOERR != cyg_io_set_config(hDrvFlexCAN,
+                                CYG_IO_SET_CONFIG_CAN_MSGBUF,
+                                &amp;rx_filter, &amp;len))
+{
+    CYG_TEST_FAIL_FINISH("Error writing config of /dev/can0");
+}
+</PROGRAMLISTING> 
+</SECTION> <!-- can-msgfilt-deact -->
+
+<SECTION id="can-event-callback">
+<TITLE>Configuring a callback on events</TITLE>
+
+<PARA>
+By default application cannot get information about an event arriving
+in the RX buffer until it calls
+the <function>cyg_io_read()</function>.  Usually this leads applications
+to use accessory threads to wait for new CAN events.
+</PARA>
+
+<PARA>
+The CDL option <varname>CYGOPT_IO_CAN_SUPPORT_CALLBACK</varname>
+allows application to use a callback on event arrival. It is
+configured by passing a <structname>cyg_can_callback_cfg</structname>
+data structure to the driver via
+the <function>cyg_io_set_config()</function> function using the config
+key
+<varname>CYG_IO_SET_CONFIG_CAN_CALLBACK</varname>.
+</PARA>
+
+<PROGRAMLISTING>
+CYG_IO_SET_CONFIG_CAN_CALLBACK
+</PROGRAMLISTING>
+
+<PROGRAMLISTING>
+typedef void (*cyg_can_event_cb_t)(cyg_uint16, CYG_ADDRWORD);
+
+typedef struct cyg_can_callback_cfg_st
+{
+    cyg_can_event_cb_t callback_func;   // callback function
+    cyg_uint16  flag_mask;              // flags mask
+    CYG_ADDRWORD data;                  // data passed to callback
+} cyg_can_callback_cfg;
+</PROGRAMLISTING>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cyg_can_event_cb_t</type> <varname>callback_func</varname></term>
+           <listitem><para> 
+Pointer to the callback function. The function will be called from DSR context so
+you should be careful to only call API functions that are safe in DSR
+context.  The First parameter is a combination of event flags for events that have 
+occurred. Second parameter is a user defined data pointer or value.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>CYG_ADDRWORD</type> <varname>data</varname></term>
+           <listitem><para>
+Additional user data that will be passed to callback function as a second parameter.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cyg_uint16</type> <varname>flag_mask</varname></term>
+           <listitem><para>
+Should be set with a combination
+of <varname>CYGNUM_CAN_EVENT_*</varname> flags.  If one of these
+events happens, the callback function will be called, with the
+actually event flags passed as a parameter.  To disable the callback
+function from being called set <varname>flag_mask</varname> to 0.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+
+</SECTION> <!-- can-event-callback -->
+
+</SECTION>  
+</CHAPTER>
+
+<CHAPTER id="io-can-configuration">
+<TITLE>Configuration</TITLE>
+
+<PARA>
+The CAN subsystem has a number of configuration options.
+</PARA>
+
+<variablelist>
+   <varlistentry>
+       <term><type>cdl_interface CYGINT_IO_CAN_TIMESTAMP</type></term>
+           <listitem><para>
+A hardware device driver that supports timestamps should implement this interface.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_TIMESTAMP</type></term>
+           <listitem><para>
+If the CAN hardware driver supports some kind of timestamps then this option enables 
+propagation of timestamps to higher layers. This may add some extra code to hardware 
+drivers.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_TX_EVENT_SUPPORT</type></term>
+           <listitem>
+<para> This option enables support for TX
+events. If a CAN message is transmitted successfully a TX event will
+be inserted into the receive event queue and propagated to higher
+layers.  If this option is enabled the RX event queue will be filled
+faster.
+</para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_NONBLOCKING</type></term>
+           <listitem>
+<para>
+This option enables extra code in the generic CAN driver which allows
+clients to switch read() and write() call semantics from blocking to
+non-blocking.
+</para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGOPT_IO_CAN_SUPPORT_CALLBACK</type></term>
+           <listitem>
+<para>
+This option enables extra code in the generic CAN driver which allows
+an application to register a callback for events. The callback function
+is called from DSR context so you should be careful to only call API
+functions that are safe in DSR context.
+</para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_READ</type></term>
+           <listitem><para>
+The initial timeout value in clock ticks for <FUNCTION>cyg_io_read()</FUNCTION> calls.
+          </para></listitem>
+   </varlistentry>
+   <varlistentry>
+       <term><type>cdl_option CYGNUM_IO_CAN_DEFAULT_TIMEOUT_WRITE</type></term>
+           <listitem><para> The initial timeout value in clock ticks
+for <FUNCTION>cyg_io_write()</FUNCTION> calls.
+          </para></listitem>
+   </varlistentry>
+</variablelist>
+</CHAPTER>
+
+
+<CHAPTER id="io-can-device-drivers">
+<TITLE>Writing a CAN hardware device driver</TITLE>
+
+<PARA>
+A CAN driver is nothing more than a named entity that supports the
+basic I/O functions - read, write, get config, and set config. The
+device driver 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.
+</PARA>
+
+<PARA>
+That said, the reason for using a device driver is to provide access
+to a CAN 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.
+</PARA>
+
+<PARA>
+Like other device drivers the CAN device driver is concerned with the
+movement of information - the CAN messages. 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 CAN device typically generates an
+interrupt after a CAN message has been sent or a CAN message has been
+received by a CAN hardware message buffer. 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 CAN message as soon as the current one is complete,
+without any active participation by the application code.
+</PARA>
+
+<PARA>
+The main building blocks for CAN device drivers are found in the
+include files
+<filename>&lt;cyg/io/devtab.h&gt;</filename> and <filename>&lt;cyg/io/can.h&gt;</filename>
+</PARA>
+
+<PARA>
+Like many other device drivers in eCos, CAN device drivers are described by a device 
+table entry, using the <type>cyg_devtab_entry_t</type> type. The entry should be created using 
+the <varname>DEVTAB_ENTRY()</varname> macro.
+</PARA>
+
+
+<SECTION id="io-can-how-to-write-interface-driver">
+<TITLE>How to Write a CAN Hardware Interface Driver</TITLE>
+
+<PARA>
+The standard CAN driver supplied with eCos is structured as a hardware
+independent portion and a hardware dependent interface module. To add
+support for a new CAN device, 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.
+</PARA>
+
+<PARA>
+The interfaces used by the CAN driver and CAN implementation modules
+are contained in the file <filename>&lt;cyg/io/can.h&gt;</filename>.
+</PARA>
+
+<SECTION>
+<title>DevTab Entry</TITLE>
+
+<PARA>
+The interface module contains the devtab entry (or entries if a single
+module supports more than one interface). This entry should have the
+form:
+</PARA>
+
+<PROGRAMLISTING> 
+DEVTAB_ENTRY(&lt;&lt;module_name&gt;&gt;, 
+             &lt;&lt;device_name&gt;&gt;,
+             0,
+             &amp;can_devio, 
+             &lt;&lt;module_init&gt;&gt;, 
+             &lt;&lt;module_lookup&gt;&gt;,
+             &amp;&lt;&lt;can_channel&gt;&gt;
+            );
+</PROGRAMLISTING> 
+
+<variablelist>
+<title>Arguments</title>
+  <varlistentry>
+    <term><parameter>module_name</parameter></term>
+    <listitem><para>The "C" label for this devtab entry</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>device_name</parameter></term>
+    <listitem><para>The "C" string for the
+    device. E.g. <filename>/dev/can0</filename>.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>can_devio</parameter></term>
+    <listitem><para>The table of I/O functions. This set is defined in
+    the hardware independent CAN driver and should be used.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>module_init</parameter></term>
+    <listitem><para>The hardware module initialization function.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>module_lookup</parameter></term>
+    <listitem><para>The device lookup function. This function
+    typically sets up the CAN device for actual use, turning on
+    interrupts, configuring the message buffers, etc.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>can_channel</parameter></term>
+    <listitem><para>This table (defined below) contains the interface
+    between the interface module and the CAN driver proper.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example devtab entry for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+DEVTAB_ENTRY(flexcan_devtab, 
+             CYGDAT_DEVS_CAN_MCF52xx_FLEXCAN0_NAME,
+             0,                     // Does not depend on a lower level interface
+             &amp;cyg_io_can_devio, 
+             flexcan_init, 
+             flexcan_lookup,        // CAN driver may need initializing
+             &amp;flexcan_can0_chan
+    );
+</PROGRAMLISTING>
+</SECTION>
+
+
+<SECTION>
+<title>CAN Channel Structure</TITLE>
+
+<PARA>
+Each CAN device must have a &ldquo;CAN channel&rdquo;.
+This is a set of data which describes all operations on the device.
+It also contains buffers, etc. The CAN channel is created by the macro: 
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,
+                             out_buf, out_buflen,
+                             in_buf,  in_buflen)
+</PROGRAMLISTING>
+
+<variablelist>
+  <title>Arguments</title>
+  <varlistentry>
+    <term><parameter>l</parameter></term>
+    <listitem><para>The "C" label for this structure.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>funs</parameter></term>
+    <listitem><para>The set of interface functions (see below).</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>dev_priv</structfield></term>
+    <listitem><para>A placeholder for any device specific data for
+    this channel.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>baud</structfield></term>
+    <listitem><para>The initial baud rate value
+    (<type>cyg_can_baud_rate_t</type>).</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>out_buf</structfield></term>
+    <listitem><para>Pointer to the output buffer</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>out_buflen</structfield></term>
+    <listitem><para>The length of the output buffer.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>in_buf</structfield></term>
+    <listitem><para>pointer to the input buffer.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>in_buflen</structfield></term>
+    <listitem><para>The length of the input buffer.</PARA></listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example CAN channel implementation for Motorola FlexCAN device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_CHANNEL_USING_INTERRUPTS(
+    flexcan_can0_chan,
+    flexcan_lowlevel_funs,
+    flexcan_can0_info,
+    CYG_CAN_BAUD_RATE(CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_KBAUD),
+    flexcan_can0_txbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_TX,
+    flexcan_can0_rxbuf, CYGNUM_DEVS_CAN_MCF52xx_FLEXCAN0_QUEUESIZE_RX
+);
+</PROGRAMLISTING>
+
+<PARA>
+The interface from the hardware independent driver into the hardware
+interface module is contained in the <structfield>funs</structfield>
+table.  This is defined by the macro:
+</PARA>
+</SECTION>
+
+<SECTION>
+<TITLE>CAN Lowlevel Functions Structure</TITLE>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(l, putmsg, getevent, get_config, set_config, start_xmit, stop_xmit)
+</PROGRAMLISTING>
+
+<variablelist>
+  <title>Arguments</title>
+  <varlistentry>
+    <term><structfield>l</structfield></term>
+    <listitem><para>The "C" label for this structure.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>putmsg</structfield></term>
+    <listitem>
+      <para><literal>
+      bool (*putmsg)(can_channel *priv, cyg_can_message *pmsg, void *pdata)
+      </literal></para>
+      <para>
+      This function sends one CAN message to the interface. It should
+      return <literal>true</literal> if the message is actually
+      consumed. It should return <literal>false</literal> if there is
+      no space in the interface
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>getevent</structfield></term>
+    <listitem>
+      <para><literal>
+      bool (*getevent)(can_channel *priv, cyg_can_event *pevent, void *pdata)
+      </literal></para>
+      <para>
+      This function fetches one event from the interface.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>get_config</structfield></term>
+    <listitem>
+      <para><literal> 
+      Cyg_ErrNo (*get_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+      </literal></para>
+      <para>
+        This function is used to query the configuration of a CAN channel.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><structfield>set_config</structfield></term>
+    <listitem>
+      <para><literal> 
+      Cyg_ErrNo (*set_config)(can_channel *priv, cyg_uint32 key, const void *xbuf, cyg_uint32 *len)
+      </literal></para>
+      <para>
+        This function is used to change configuration of a CAN channel.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>start_xmit</parameter></term>
+    <listitem><para><literal>void (*start_xmit)(can_channel *priv)</literal></para>
+      <para>
+        Enable the transmit channel and turn on transmit interrupts.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><parameter>stop_xmit</parameter></term>
+    <listitem>
+      <para><literal>void (*stop_xmit)(can_channel *priv)</literal></para>
+      <para>Disable the transmit channel and turn transmit interrupts off.</PARA>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<PARA>
+Example implementation of low level function structure for Motorola FlexCAN 
+device driver:
+</PARA>
+
+<PROGRAMLISTING>
+CAN_LOWLEVEL_FUNS(flexcan_lowlevel_funs,
+                  flexcan_putmsg,
+                  flexcan_getevent,
+                  flexcan_get_config,
+                  flexcan_set_config,
+                  flexcan_start_xmit,
+                  flexcan_stop_xmit
+     );
+</PROGRAMLISTING>
+</SECTION>
+
+<SECTION>
+<TITLE>Callbacks</TITLE>
+
+<PARA>
+The device interface module can execute functions in the
+hardware independent driver via <literal>chan-&gt;callbacks</literal>.
+These functions are available:
+</PARA>
+
+<PROGRAMLISTING>
+void (*can_init)(can_channel *chan)
+</PROGRAMLISTING>
+
+<PARA>This function is used to initialize the CAN channel.</PARA>
+
+<PROGRAMLISTING>
+void (*xmt_msg)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function would be called from an interrupt handler after a
+transmit interrupt indicating that additional messages may be
+sent. The upper driver will call the <function>putmsg</function>
+function as appropriate to send more data to the device.
+</PARA>
+
+<PROGRAMLISTING>
+void (*rcv_event)(can_channel *chan, void *pdata)
+</PROGRAMLISTING>
+
+<PARA>
+This function is used to tell the driver that a message has arrived
+at the interface or that an event has occurred. This function is typically 
+called from the interrupt handler. 
+</PARA>
+</SECTION><!-- Callbacks -->
+
+</SECTION><!-- id="io-can-how-to-write-interface-driver" -->
+</CHAPTER>
+
+</PART>
--- a/packages/io/can/current/include/canio.h
+++ b/packages/io/can/current/include/canio.h
@@ -331,7 +331,7 @@ typedef struct cyg_can_hdi_st
 // Callback configuration structure.
 //
 
-typedef void (*cyg_can_event_cb_t)(cyg_uint16, cyg_addrword_t);
+typedef void (*cyg_can_event_cb_t)(cyg_uint16, CYG_ADDRWORD);
 //
 // flag_mask should be set with a combination of CYGNUM_CAN_EVENT_* flags.
 // If one of these events happens, the callback function will be called,
@@ -341,7 +341,7 @@ typedef struct cyg_can_callback_cfg_st
 {
     cyg_can_event_cb_t callback_func;              // callback function
     cyg_uint16  flag_mask;                         // flags mask
-    cyg_addrword_t data;                           // data passed to callback
+    CYG_ADDRWORD data;                             // data passed to callback
 } cyg_can_callback_cfg;
 
 
--- a/packages/io/can/current/src/can.c
+++ b/packages/io/can/current/src/can.c
@@ -668,8 +668,8 @@ static Cyg_ErrNo can_set_config(cyg_io_h
 
 #ifdef CYGOPT_IO_CAN_SUPPORT_CALLBACK
         //
-        // Set waking calls configuration
-        // To disable waking calls set waking_mask = 0
+        // Set callback configuration
+        // To disable callback set flag_mask = 0
         //
         case CYG_IO_SET_CONFIG_CAN_CALLBACK:
              {