📄 can.sgml
字号:
<!-- {{{ 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><cyg/io/config_keys.h></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><cyg/io/config_keys.h></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><cyg/io/canio.h></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()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -