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

📄 usbs.sgml

📁 eCos操作系统源码
💻 SGML
📖 第 1 页 / 共 5 页
字号:
is allowed as well.</para><para>For USB peripherals involving multiple configurations, the array of<structname>usb_interface_descriptor</structname> structures shouldfirst contain all the interfaces for the first configuration, then allthe interfaces for the second configuration, and so on.</para></refsect2><refsect2><title id="usbs-enum-endpoint"><structname>usb_endpoint_descriptor</structname></title><para>The host also needs information about which endpoint should be usedfor what. This involves an array of endpoint descriptors:</para><programlisting width=72>const usb_endpoint_descriptor usb_endpoints[] = {    {        length:         USB_ENDPOINT_DESCRIPTOR_LENGTH,        type:           USB_ENDPOINT_DESCRIPTOR_TYPE,        endpoint:       USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT | 1,        attributes:     USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,        max_packet_lo:  64,        max_packet_hi:  0,        interval:       0    },    {        length:         USB_ENDPOINT_DESCRIPTOR_LENGTH,        type:           USB_ENDPOINT_DESCRIPTOR_TYPE,        endpoint:       USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN | 2,        attributes:     USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,        max_packet_lo:  64,        max_packet_hi:  0,        interval:       0    }};const usbs_enumeration_data usb_enum_data = {    &hellip;    total_number_endpoints:     2,    endpoints:                  usb_endpoints,    &hellip;};</programlisting><para>As usual the values for the <structfield>length</structfield> and<structfield>type</structfield> fields are specified by the standard.The <structfield>endpoint</structfield> field gives both the endpointnumber and the direction, so in the above example endpoint 1 is usedfor OUT (host to peripheral) transfers and endpoint 2 is used for IN(peripheral to host) transfers. The<structfield>attributes</structfield> field indicates the USB protocolthat should be used on this endpoint: <literal>CONTROL</literal>,<literal>ISOCHRONOUS</literal>, <literal>BULK</literal> or<literal>INTERRUPT</literal>. The<structfield>max_packet</structfield> field specifies the maximum sizeof a single USB packet. For bulk transfers this will typically be 64bytes. For isochronous transfers this can be up to 1023 bytes. Forinterrupt transfers it can be up to 64 bytes, although usually asmaller value will be used. The <structfield>interval</structfield>field is ignored for control and bulk transfers. For isochronoustransfers it should be set to 1. For interrupt transfers it can be avalue between 1 and 255, and indicates the number of millisecondsbetween successive polling operations.</para><para>For USB peripherals involving multiple configurations or interfacesthe array of endpoint descriptors should be organized sequentially:first the endpoints corresponding to the first interface of the firstconfiguration, then the second interface in that configuration, and soon; then all the endpoints for all the interfaces in the secondconfiguration; etc.</para></refsect2><refsect2><title id="usbs-enum-strings">Strings</title><para>The enumeration data can contain a number of strings with additionalinformation. Unicode encoding is used for the strings, and it ispossible for a peripheral to supply a given string in multiplelanguages using the appropriate characters. The first two bytes ofeach string give a length and type field. The first string is special;after the two bytes header it consists of an array of 2-byte languageid codes, indicating the supported languages. The language code0x0409 corresponds to English (United States). </para><programlisting width=72>const unsigned char* usb_strings[] = {    "\004\003\011\004",    "\020\003R\000e\000d\000 \000H\000a\000t\000"};const usbs_enumeration_data usb_enum_data = {    &hellip;    total_number_strings:       2,    strings:                    usb_strings,    &hellip;};</programlisting><para>The default handler for standard control messages assumes that theperipheral only uses a single language. If this is not the case thenhigher-level code will have to handle the standard get-descriptorcontrol messages when a string descriptor is requested.</para></refsect2><refsect2><title><structname>usbs_enumeration_data</structname></title><para>The <structname>usbs_enumeration_data</structname> data structurecollects together all the various descriptors that make up theenumeration data. It is the responsibility of application code tosupply a suitable data structure and install it in the controlendpoints's <structfield>enumeration_data</structfield> field beforethe USB device is started.</para></refsect2></refsect1></refentry><!-- }}} --><!-- {{{ usbs_start()                   --><refentry id="usbs-start"><refmeta><refentrytitle>Starting up a USB Device</refentrytitle></refmeta><refnamediv><refname><function>usbs_start</function></refname><refpurpose>Starting up a USB Device</refpurpose></refnamediv><refsynopsisdiv><funcsynopsis><funcsynopsisinfo>#include &lt;cyg/io/usb/usbs.h&gt;</funcsynopsisinfo><funcprototype><funcdef>void <function>usbs_start</function></funcdef><paramdef>usbs_control_endpoint* <parameter>ep0</parameter></paramdef></funcprototype></funcsynopsis></refsynopsisdiv><refsect1><title>Description</title><para>Initializing a USB device requires some support from higher-levelcode, typically the application, in the form of enumeration data.Hence it is not possible for the low-level USB driver to activate aUSB device itself. Instead the higher-level code has to take care ofthis by invoking <function>usbs_start</function>. This function takesa pointer to a USB control endpoint data structure. USB device driversshould provide exactly one such data structure for every USB device,so the pointer uniquely identifies the device.</para><programlisting width=72>const usbs_enumeration_data usb_enum_data = {    &hellip;};intmain(int argc, char** argv){    usbs_sa11x0_ep0.enumeration_data = &amp;usb_enum_data;    &hellip;    usbs_start(&amp;usbs_sa11x0_ep0);    &hellip;}</programlisting><para>The exact behaviour of <function>usbs_start</function> depends on theUSB hardware and the device driver. A typical implementation wouldchange the USB data pins from tristated to active. If the peripheralis already plugged into a host then the latter should detect thischange and start interacting with the peripheral, including requestingthe enumeration data. Some of this may happen before<function>usbs_start</function> returns, but given that multipleinteractions between USB host and peripheral are required it is likelythat the function will return before the peripheral is fullyconfigured. Control endpoints provide a <linklinkend="usbs-control-state">mechanism</link> for informinghigher-level code of USB state changes.<function>usbs_start</function> will return even if the peripheral isnot currently connected to a host: it will not block until theconnection is established.</para><para><function>usbs_start</function> should only be called once for a givenUSB device. There are no defined error conditions. Note that thefunction affects the entire USB device and not just the controlendpoint: there is no need to start any data endpoints as well.</para></refsect1></refentry><!-- }}} --><!-- {{{ Devtab Entries                 --><refentry id="usbs-devtab"><refmeta><refentrytitle>Devtab Entries</refentrytitle></refmeta><refnamediv><refname>Devtab Entries</refname><refpurpose>Data endpoint data structure</refpurpose></refnamediv><refsynopsisdiv><synopsis>/dev/usb0c/dev/usb1r/dev/usb2w</synopsis></refsynopsisdiv><refsect1><title>Devtab Entries</title><para>USB device drivers provide two ways of transferring data between hostand peripheral. The first involves USB-specific functionality such as<linklinkend="usbs-start-rx"><function>usbs_start_rx_buffer</function></link>.This provides non-blocking I/O: a transfer is started, and some timelater the device driver will call a supplied completion function. Thesecond uses the conventional I/O model: there are entries in thedevice table corresponding to the various endpoints. Standard callssuch as <function>open</function> can then be used to get a suitablehandle. Actual I/O happens via blocking <function>read</function> and<function>write</function> calls. In practice the blocking operationsare simply implemented using the underlying non-blockingfunctionality.</para><para>Each endpoint will have its own devtab entry. The exact names arecontrolled by the device driver package, but typically the root willbe <literal>/dev/usb</literal>. This is followed by one or moredecimal digits giving the endpoint number, followed by<literal>c</literal> for a control endpoint, <literal>r</literal> fora receive endpoint (host to peripheral), and <literal>w</literal> fora transmit endpoint (peripheral to host). If the target hardwareinvolves more than one USB device then different roots should be used,for example <literal>/dev/usb0c</literal> and<literal>/dev/usb1_0c</literal>. This may require explicitmanipulation of device driver configuration options by the applicationdeveloper.</para><para>At present the devtab entry for a control endpoint does not supportany I/O operations. </para><refsect2><title><function>write</function> operations</title><para><function>cyg_io_write</function> and similar functions inhigher-level packages can be used to perform a transfer fromperipheral to host. Successive write operations will not be coalesced.For example, when doing a 1000 byte write to an endpoint that uses thebulk transfer protocol this will involve 15 full-size 64-byte packetsand a terminating 40-byte packet. USB device drivers are not expectedto do any locking, and if higher-level code performs multipleconcurrent write operations on a single endpoint then the resultingbehaviour is undefined.</para><para>A USB <function>write</function> operation will never transfer lessdata than specified. It is the responsibility of higher-level code toensure that the amount of data being transferred is acceptable to thehost-side code. Usually this will be defined by a higher-levelprotocol. If an attempt is made to transfer more data than the hostexpects then the resulting behaviour is undefined.</para><para>There are two likely error conditions. <literal>EPIPE</literal>indicates that the connection between host and target has been broken.<literal>EAGAIN</literal> indicates that the endpoint has beenstalled, either at the request of the host or by other activityinside the peripheral.</para></refsect2><refsect2><title><function>read</function> operations</title><para><function>cyg_io_read</function> and similar functions in higher-levelpackages can be used to perform a transfer from host to peripheral.This should be a complete transfer: higher-level protocols shoulddefine an upper bound on the amount of data being transferred, and the<function>read</function> operation should involve at least thisamount of data. The return value will indicate the actual transfersize, which may be less than requested.</para><para>Some device drivers may support partial reads, but USB device driversare not expected to perform any buffering because that involves bothmemory and code overheads. One technique that may work for bulktransfers is to exploit the fact that such transfers happen in 64-bytepackets. It is possible to <function>read</function> an initial 64bytes, corresponding to the first packet in the transfer. These 64bytes can then be examined to determine the total transfer size, andthe remaining data can be transferred in another<function>read</function> operation. This technique is not guaranteedto work with all USB hardware. Also, if the delay between acceptingthe first packet and the remainder of the transfer is excessive thenthis could cause timeout problems for the host-side software. Forthese reasons the use of partial reads should be avoided.

⌨️ 快捷键说明

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