can.sgml

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

SGML
1,739
字号

<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 h

⌨️ 快捷键说明

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