can.sgml

来自「开放源码实时操作系统源码.」· SGML 代码 · 共 1,739 行 · 第 1/5 页

SGML
1,739
字号
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> 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?