⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbs-control.html

📁 ecos 文档
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
<!-- 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 is obtained from the copyright holder.               -->
<HTML
><HEAD
><TITLE
>Control Endpoints</TITLE
><meta name="MSSmartTagsPreventParsing" content="TRUE">
<META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE="eCos Reference Manual"
HREF="ecos-ref.html"><LINK
REL="UP"
TITLE="eCos USB Slave Support"
HREF="io-usb-slave.html"><LINK
REL="PREVIOUS"
TITLE="Halted Endpoints"
HREF="usbs-halt.html"><LINK
REL="NEXT"
TITLE="Data Endpoints"
HREF="usbs-data.html"></HEAD
><BODY
CLASS="REFENTRY"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>eCos Reference Manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="usbs-halt.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="usbs-data.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><H1
><A
NAME="USBS-CONTROL">Control Endpoints</H1
><DIV
CLASS="REFNAMEDIV"
><A
NAME="AEN16530"
></A
><H2
>Name</H2
>Control Endpoints&nbsp;--&nbsp;Control endpoint data structure</DIV
><DIV
CLASS="REFSYNOPSISDIV"
><A
NAME="AEN16533"><H2
>Synopsis</H2
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="SYNOPSIS"
>#include &lt;cyg/io/usb/usbs.h&gt;

typedef struct usbs_control_endpoint {
    *hellip;
} usbs_control_endpoint;</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="REFSECT1"
><A
NAME="AEN16535"
></A
><H2
><TT
CLASS="LITERAL"
>usbs_control_endpoint</TT
> Data Structure</H2
><P
>The device driver for a USB slave device should supply one
<SPAN
CLASS="STRUCTNAME"
>usbs_control_endpoint</SPAN
> data structure per USB
device. This corresponds to endpoint 0 which will be used for all
control message interaction between the host and that device. The data
structure is also used for internal management purposes, for example
to keep track of the current state. In a typical USB peripheral there
will only be one such data structure in the entire system, but if
there are multiple USB slave ports, allowing the peripheral to be
connected to multiple hosts, then there will be a separate data
structure for each one. The name or names of the data structures are
determined by the device drivers. For example, the SA11x0 USB device
driver package provides <TT
CLASS="LITERAL"
>usbs_sa11x0_ep0</TT
>.</P
><P
>The operations on a control endpoint do not fit cleanly into a
conventional open/read/write I/O model. For example, when the host
sends a control message to the USB peripheral this may be one of four
types: standard, class, vendor and reserved. Some or all of the
standard control messages will be handled automatically by the common
USB slave package or by the device driver itself. Other standard
control messages and the other types of control messages may be
handled by a class-specific package or by application code. Although
it would be possible to have devtab entries such as
<TT
CLASS="LITERAL"
>/dev/usbs_ep0/standard</TT
> and
<TT
CLASS="LITERAL"
>/dev/usbs_ep0/class</TT
>, and then support read and
write operations on these devtab entries, this would add significant
overhead and code complexity. Instead, all of the fields in the
control endpoint data structure are public and can be manipulated
directly by higher level code if and when required. </P
><P
>Control endpoints involve a number of callback functions, with
higher-level code installing suitable function pointers in the control
endpoint data structure. For example, if the peripheral involves
vendor-specific control messages then a suitable handler for these
messages should be installed. Although the exact details depend on the
device driver, typically these callback functions will be invoked at
DSR level rather than thread level. Therefore, only certain eCos
functions can be invoked; specifically, those functions that are
guaranteed not to block. If a potentially blocking function such as a
semaphore wait or a mutex lock operation is invoked from inside the
callback then the resulting behaviour is undefined, and the system as
a whole may fail. In addition, if one of the callback functions
involves significant processing effort then this may adversely affect
the system's real time characteristics. The eCos kernel documentation
should be consulted for more details of DSR handling.</P
><DIV
CLASS="REFSECT2"
><A
NAME="AEN16545"
></A
><H3
>Initialization</H3
><P
>The <SPAN
CLASS="STRUCTNAME"
>usbs_control_endpoint</SPAN
> data structure
contains the following fields related to initialization.</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>typedef struct usbs_control_endpoint {
    &#8230;
    const usbs_enumeration_data* enumeration_data;
    void                         (*start_fn)(usbs_control_endpoint*);
    &#8230;
};</PRE
></TD
></TR
></TABLE
><P
>It is the responsibility of higher-level code, usually the
application, to define the USB enumeration data. This needs to be
installed in the control endpoint data structure early on during
system startup, before the USB device is actually started and any
interaction with the host is possible. Details of the enumeration data
are supplied in the section <A
HREF="usbs-enum.html"
>USB Enumeration
Data</A
>. Typically, the enumeration data is constant for a given
peripheral, although it can be constructed dynamically if necessary.
However, the enumeration data cannot change while the peripheral is
connected to a host: the peripheral cannot easily claim to be a
keyboard one second and a printer the next.</P
><P
>The <TT
CLASS="STRUCTFIELD"
><I
>start_fn</I
></TT
> member is normally accessed
via the utility <A
HREF="usbs-start.html"
><TT
CLASS="FUNCTION"
>usbs_start</TT
></A
> rather
than directly. It is provided by the device driver and should be
invoked once the system is fully initialized and interaction with the
host is possible. A typical implementation would change the USB data
pins from tristated to active. If the peripheral is already plugged
into a host then the latter should detect this change and start
interacting with the peripheral, including requesting the enumeration
data.</P
></DIV
><DIV
CLASS="REFSECT2"
><A
NAME="AEN16556"
></A
><H3
>State</H3
><P
>There are three <SPAN
CLASS="STRUCTNAME"
>usbs_control_endpoint</SPAN
> fields
related to the current state of a USB slave device, plus some state
constants and an enumeration of the possible state changes:</P
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>typedef struct usbs_control_endpoint {
    &#8230;
    int     state;
    void    (*state_change_fn)(struct usbs_control_endpoint*, void*,
                               usbs_state_change, int);
    void*   state_change_data;
    &#8230;
};

#define USBS_STATE_DETACHED             0x01
#define USBS_STATE_ATTACHED             0x02
#define USBS_STATE_POWERED              0x03
#define USBS_STATE_DEFAULT              0x04
#define USBS_STATE_ADDRESSED            0x05
#define USBS_STATE_CONFIGURED           0x06
#define USBS_STATE_MASK                 0x7F
#define USBS_STATE_SUSPENDED            (1 &lt;&lt; 7)

typedef enum {
    USBS_STATE_CHANGE_DETACHED          = 1,
    USBS_STATE_CHANGE_ATTACHED          = 2,
    USBS_STATE_CHANGE_POWERED           = 3,
    USBS_STATE_CHANGE_RESET             = 4,    
    USBS_STATE_CHANGE_ADDRESSED         = 5,
    USBS_STATE_CHANGE_CONFIGURED        = 6,
    USBS_STATE_CHANGE_DECONFIGURED      = 7,    
    USBS_STATE_CHANGE_SUSPENDED         = 8,
    USBS_STATE_CHANGE_RESUMED           = 9
} usbs_state_change;</PRE
></TD
></TR
></TABLE
><P
>The USB standard defines a number of states for a given USB
peripheral. The initial state is <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>detached</I
></SPAN
>, where
the peripheral is either not connected to a host at all or, from the
host's perspective, the peripheral has not started up yet because the
relevant pins are tristated. The peripheral then moves via
intermediate <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>attached</I
></SPAN
> and
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>powered</I
></SPAN
> states to its default or
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>reset</I
></SPAN
> state, at which point the host and
peripheral can actually start exchanging data. The first message is
from host to peripheral and provides a unique 7-bit address within the
local USB network, resulting in a state change to
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>addressed</I
></SPAN
>. The host then requests enumeration
data and performs other initialization. If everything succeeds the
host sends a standard set-configuration control message, after which
the peripheral is <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>configured</I
></SPAN
> and expected to be
up and running. Note that some USB device drivers may be unable to
distinguish between the <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>detached</I
></SPAN
>,
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>attached</I
></SPAN
> and <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>powered</I
></SPAN
> states
but generally this is not important to higher-level code.</P
><P
>A USB host should generate at least one token every millisecond. If a
peripheral fails to detect any USB traffic for a period of time then
typically this indicates that the host has entered a power-saving
mode, and the peripheral should do the same if possible. This
corresponds to the <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>suspended</I
></SPAN
> bit. The actual
state is a combination of <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>suspended</I
></SPAN
> and the
previous state, for example <SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>configured</I
></SPAN
> and
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>suspended</I
></SPAN
> rather than just
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>suspended</I
></SPAN
>. When the peripheral subsequently
detects USB traffic it would switch back to the
<SPAN
CLASS="emphasis"
><I
CLASS="EMPHASIS"
>configured</I
></SPAN
> state.</P
><P
>The USB device driver and the common USB slave package will maintain
the current state in the control endpoint's
<TT
CLASS="STRUCTFIELD"
><I
>state</I
></TT
> field. There should be no need for
any other code to change this field, but it can be examined whenever
appropriate. In addition whenever a state change occurs the generic
code can invoke a state change callback function. By default, no such
callback function will be installed. Some class-specific packages such
as the USB-ethernet package will install a suitable function to keep
track of whether or not the host-peripheral connection is up, that is
whether or not ethernet packets can be exchanged. Application code can
also update this field. If multiple parties want to be informed of
state changes, for example both a class-specific package and
application code, then typically the application code will install its
state change handler after the class-specific package and is
responsible for chaining into the package's handler.</P
><P
>The state change callback function is invoked with four arguments. The
first identifies the control endpoint. The second is an arbitrary
pointer: higher-level code can fill in the
<TT
CLASS="STRUCTFIELD"
><I
>state_change_data</I
></TT
> field to set this. The
third argument specifies the state change that has occurred, and the
last argument supplies the previous state (the new state is readily
available from the control endpoint structure).</P
><P
>eCos does not provide any utility functions for updating or examining
the <TT
CLASS="STRUCTFIELD"
><I
>state_change_fn</I
></TT
> or
<TT
CLASS="STRUCTFIELD"
><I
>state_change_data</I
></TT
> fields. Instead, it is
expected that the fields in the
<SPAN
CLASS="STRUCTNAME"
>usbs_control_endpoint</SPAN
> data structure will be
manipulated directly. Any utility functions would do just this, but
at the cost of increased code and cpu overheads.</P
></DIV
><DIV
CLASS="REFSECT2"
><A
NAME="AEN16586"
></A
><H3
>Standard Control Messages</H3
><TABLE
BORDER="5"
BGCOLOR="#E0E0F0"
WIDTH="70%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>typedef struct usbs_control_endpoint {
    &#8230;
    unsigned char       control_buffer[8];
    usbs_control_return (*standard_control_fn)(struct usbs_control_endpoint*, void*);
    void*               standard_control_data;
    &#8230;
} usbs_control_endpoint;

typedef enum {
    USBS_CONTROL_RETURN_HANDLED = 0,
    USBS_CONTROL_RETURN_UNKNOWN = 1,
    USBS_CONTROL_RETURN_STALL   = 2
} usbs_control_return;

extern usbs_control_return usbs_handle_standard_control(struct usbs_control_endpoint*);</PRE

⌨️ 快捷键说明

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