/Documentation/usb/URB.txt

2024-06-22 07:32
文章标签 documentation usb urb txt

本文主要是介绍/Documentation/usb/URB.txt,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如果想评论或更新本文的内容,请直接联系原文档的维护者。

如果你使用英文交流有困难的话,也可以向中文版维护者求助。

如果本翻译更新不及时或者翻译存在问题,请联系中文版维护者。

中文版维护者: 姚家珺AriosYao   ks666dejia@163.com

中文版翻译者: 姚家珺AriosYao   ks666dejia@163.com

中文版校译者: 姚家珺AriosYao   ks666dejia@163.com

 

Revised: 2000-Dec-05.
Again:   2002-Jul-06
Again:   2005-Sep-19

    NOTE/小记:

    The USB subsystem now has a substantial section in "The Linux Kernel API"
    guide (in Documentation/DocBook), generated from the current source
    code.  This particular documentation file isn't particularly current or
    complete; don't rely on it except for a quick overview.

 USB子系统现在有一个主要部分“Linux内核API”
    指南(在 Documentation/DocBook),从当前源
    代码产生。这种特定的文档文件并不是完全正确或者完整的;除非是为了快速了解,尽量不要依赖它。

1.1. Basic concept or 'What is an URB?'/基本概念,什么是URB?

The basic idea of the new driver is message passing, the message itself is
called USB Request Block, or URB for short.

新的驱动程序的基本思路是消息传递,消息本身是
称为USB请求块,或URB。

- An URB consists of all relevant information to execute any USB transaction
  and deliver the data and status back.
 
  一个URB包括执行任何USB事务和提供的数据和状态回所有相关信息。

- Execution of an URB is inherently an asynchronous operation, i.e. the
  usb_submit_urb(urb) call returns immediately after it has successfully
  queued the requested action.
 
  URB本质上是执行一个异步操作,即usb_submit_urb(URB)调用后立即返回它已经成功地排队请求的操作。

- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time.

  一个URB转发可以在任何时候用usb_unlink_urb(URB)取消。

- Each URB has a completion handler, which is called after the action
  has been successfully completed or canceled. The URB also contains a
  context-pointer for passing information to the completion handler.
 
  每个URB有一个完成处理操作,这就是所谓的行动后,已成功完成或取消。
  URB还包含一个上下文指针传递信息用以完成处理。

- Each endpoint for a device logically supports a queue of requests.
  You can fill that queue, so that the USB hardware can still transfer
  data to an endpoint while your driver handles completion of another.
  This maximizes use of USB bandwidth, and supports seamless streaming
  of data to (or from) devices when using periodic transfer modes.
 
  每个端点设备在逻辑上支持的请求队列。
  您可以填写该队列,使USB硬件仍然可以在您的驱动程序处理完成另一个操作的同时传输数据到端点。
  这最大限度地利用了USB带宽,并在使用定期传输模式时支持无缝输入(输出)设备的数据流。


1.2. The URB structure/URB结构

Some of the fields in an URB are:/URB的部分结构:

struct urb
{
// (IN) device and pipe specify the endpoint queue
 struct usb_device *dev;         // pointer to associated USB device
 unsigned int pipe;              // endpoint information

 unsigned int transfer_flags;    // ISO_ASAP, SHORT_NOT_OK, etc.

// (IN) all urbs need completion routines
 void *context;                  // context for completion routine
 void (*complete)(struct urb *); // pointer to completion routine

// (OUT) status after each completion
 int status;                     // returned status

// (IN) buffer used for data transfers
 void *transfer_buffer;          // associated data buffer
 int transfer_buffer_length;     // data buffer length
 int number_of_packets;          // size of iso_frame_desc

// (OUT) sometimes only part of CTRL/BULK/INTR transfer_buffer is used
 int actual_length;              // actual data buffer length

// (IN) setup stage for CTRL (pass a struct usb_ctrlrequest)
 unsigned char* setup_packet;    // setup packet (control only)

// Only for PERIODIC transfers (ISO, INTERRUPT)
    // (IN/OUT) start_frame is set unless ISO_ASAP isn't set
 int start_frame;                // start frame
 int interval;                   // polling interval

    // ISO only: packets are only "best effort"; each can have errors
 int error_count;                // number of errors
 struct usb_iso_packet_descriptor iso_frame_desc[0];
};

Your driver must create the "pipe" value using values from the appropriate
endpoint descriptor in an interface that it's claimed.

您的驱动程序必须创建一个接口“管”,它声称适当的端点描述符中的值。


1.3. How to get an URB?/如何使用URB:

URBs are allocated with the following call
URB通过下面的调用启动

 struct urb *usb_alloc_urb(int isoframes, int mem_flags)

Return value is a pointer to the allocated URB, 0 if allocation failed.
The parameter isoframes specifies the number of isochronous transfer frames
you want to schedule. For CTRL/BULK/INT, use 0.  The mem_flags parameter
holds standard memory allocation flags, letting you control (among other
things) whether the underlying code may block or not.

如果分配失败,返回值是一个指针分配URB,0。
参数isoframes指定你要安排的同步传输帧的数量。对于CTRL/BULK/INT, use 0。
参数mem_flags保存了标准内存分配标志,让您控制底层代码(其中包括)是否可能被阻止。

To free an URB, use/释放URB

 void usb_free_urb(struct urb *urb)

You may free an urb that you've submitted, but which hasn't yet been
returned to you in a completion callback.  It will automatically be
deallocated when it is no longer in use.

您可能会释放一个你已经提交的URB,但在一个完整的回调中尚未返回。此时它会自动被解除分配,不再使用。


1.4. What has to be filled in?/需要填写的信息

Depending on the type of transaction, there are some inline functions
defined in <linux/usb.h> to simplify the initialization, such as
fill_control_urb() and fill_bulk_urb().  In general, they need the usb
device pointer, the pipe (usual format from usb.h), the transfer buffer,
the desired transfer length, the completion  handler, and its context.
Take a look at the some existing drivers to see how they're used.

根据不同的事务,也有一些内联函数中定义<linux/usb.h>简化初始化,如fill_control_urb()和fill_bulk_urb()。
在一般情况下,他们需要USB设备的指针,管道(usb.h中常用的格式),传输缓冲区,需要的传输长度,完成处理程序,它的上下文。
了解一些一些现有的驱动程序,看看他们是如何使用。

Flags:/标志
For ISO there are two startup behaviors: Specified start_frame or ASAP.
For ASAP set URB_ISO_ASAP in transfer_flags.

对于ISO有两个启动行为:指定start_frame的或ASAP。
对于ASAP,在transfer_flags设置URB_ISO_ASAP。

If short packets should NOT be tolerated, set URB_SHORT_NOT_OK in
transfer_flags.

如果短数据包无法使用,在transfer_flags设置URB_SHORT_NOT_OK。

1.5. How to submit an URB?/如何注册一个URB

Just call/直接调用

 int usb_submit_urb(struct urb *urb, int mem_flags)

The mem_flags parameter, such as SLAB_ATOMIC, controls memory allocation,
such as whether the lower levels may block when memory is tight.

参数mem_flags,如SLAB_ATOMIC,控制内存分配,比如在较低水平时,是否可能会阻止内存资源紧张。

It immediately returns, either with status 0 (request queued) or some
error code, usually caused by the following:

如果它立即返回,无论是与状态0(请求排队)或一些错误代码,通常由以下原因引起的:

- Out of memory (-ENOMEM)/内存不足
- Unplugged device (-ENODEV)/设备没有加电
- Stalled endpoint (-EPIPE)/停滞的端点
- Too many queued ISO transfers (-EAGAIN)/ISO传输队列过长
- Too many requested ISO frames (-EFBIG)/ISO帧请求太多
- Invalid INT interval (-EINVAL)/无效的INT间隔
- More than one packet for INT (-EINVAL)/多个INT数据包

After submission, urb->status is -EINPROGRESS; however, you should never
look at that value except in your completion callback.

提交后,URB->状态是EINPROGRESS,但是,完成回调之前该值无意义。

For isochronous endpoints, your completion handlers should (re)submit
URBs to the same endpoint with the ISO_ASAP flag, using multi-buffering,
to get seamless ISO streaming.

对于同步端点,完成处理程序应该(重新)提交URB的相同的端点与ISO_ASAP标志,使用多缓冲,获得无缝ISO流。


1.6. How to cancel an already running URB?/如何取消一个已经运行的URB?

There are two ways to cancel an URB you've submitted but which hasn't
been returned to your driver yet.  For an asynchronous cancel, call

有两种取消已经运行的URB的方法,但是并没有返回给你的驱动。
对于异步取消,调用

 int usb_unlink_urb(struct urb *urb)

It removes the urb from the internal list and frees all allocated
HW descriptors. The status is changed to reflect unlinking.  Note
that the URB will not normally have finished when usb_unlink_urb()
returns; you must still wait for the completion handler to be called.

它消除了URB从内部列表,并释放所有分配的硬件描述。
状态更改为断开链接。
注意URB的不正常结束时的usb_unlink_urb()返回,您仍然必须等待被调用的程序完成处理。

To cancel an URB synchronously, call/取消同步URB,调用

 void usb_kill_urb(struct urb *urb)

It does everything usb_unlink_urb does, and in addition it waits
until after the URB has been returned and the completion handler
has finished.  It also marks the URB as temporarily unusable, so
that if the completion handler or anyone else tries to resubmit it
they will get a -EPERM error.  Thus you can be sure that when
usb_kill_urb() returns, the URB is totally idle.


它跟usb_unlink_urb的功能差不多,除了等待,直到URB后已返回并完成处理程序已完成。
这也标志着URB暂时无法使用,所以,如果完成处理或其他任何人试图重新提交,他们会得到一个EPERM错误。
因此,可以肯定,当usb_kill_urb()返回时,URB是完全闲置的。

There is a lifetime issue to consider.  An URB may complete at any
time, and the completion handler may free the URB.  If this happens
while usb_unlink_urb or usb_kill_urb is running, it will cause a
memory-access violation.  The driver is responsible for avoiding this,
which often means some sort of lock will be needed to prevent the URB
from being deallocated while it is still in use.

有其是一个很严重的问题。一个URB可能在任何时间完成,并完成处理可能释放URB。
如果发生这种情况,而usb_unlink_urb或usb_kill_urb正在运行,它会导致一个内存访问冲突。
为避免这种驱动程序负责,这往往意味着某种类型的锁,用来防止URB被释放时它仍然在使用。

On the other hand, since usb_unlink_urb may end up calling the
completion handler, the handler must not take any lock that is held
when usb_unlink_urb is invoked.  The general solution to this problem
is to increment the URB's reference count while holding the lock, then
drop the lock and call usb_unlink_urb or usb_kill_urb, and then
decrement the URB's reference count.  You increment the reference
count by calling

另一方面,由于usb_unlink_urb可能最终会调用完成处理程序,处理程序在调用usb_unlink_urb时不能使用任何锁。
解决这个问题使用了URB的引用计数递增,同时持有锁,然后放下锁调用usb_unlink_urb或usb_kill_urb,然后递减的URB的引用计数。
调用递增引用计数:

 struct urb *usb_get_urb(struct urb *urb)

(ignore the return value; it is the same as the argument) and
decrement the reference count by calling usb_free_urb.  Of course,
none of this is necessary if there's no danger of the URB being freed
by the completion handler.

(忽略返回值,它跟参数相同)通过调用usb_free_urb递减引用计数。
当然,如果没有危险的URB被释放完成处理程序,这是没有必要的。


1.7. What about the completion handler?/关于完成处理程序

The handler is of the following type:/处理程序的类

 typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)

I.e., it gets the URB that caused the completion call, plus the
register values at the time of the corresponding interrupt (if any).
In the completion handler, you should have a look at urb->status to
detect any USB errors. Since the context parameter is included in the URB,
you can pass information to the completion handler.

即,它得到产生完成调用操作的URB,在相应的中断时间(如有的话)附加寄存器的值。
在完成处理程序中,你应该查看URB->状态检测是否有任何USB错误。
由于上下文参数包含在URB,你可以传递信息至完成处理程序。

Note that even when an error (or unlink) is reported, data may have been
transferred.  That's because USB transfers are packetized; it might take
sixteen packets to transfer your 1KByte buffer, and ten of them might
have transferred successfully before the completion was called.

请注意,即使在出现错误(或解除链接)报告,数据可能已经被转移。
这是因为USB传输打包的时候,可能需要16个数据包传输1K字节的缓冲区,
其中十个数据包可能在完成调用发生之前就转移完毕了。


NOTE:  ***** WARNING *****/警告
NEVER SLEEP IN A COMPLETION HANDLER.  These are normally called
during hardware interrupt processing.  If you can, defer substantial
work to a tasklet (bottom half) to keep system latencies low.  You'll
probably need to use spinlocks to protect data structures you manipulate
in completion handlers.

不要在完成处理程序使用睡眠模式。
这些通常被称为硬件中断处理过程中。如果可以的话,大量的工作推迟到一个tasklet(的下半部),以保持较低的系统延迟。
您可能会需要使用自旋锁保护你操纵的完成处理程序的数据结构,。


1.8. How to do isochronous (ISO) transfers?/如何做到同步(ISO)传输?

For ISO transfers you have to fill a usb_iso_packet_descriptor structure,
allocated at the end of the URB by usb_alloc_urb(n,mem_flags), for each
packet you want to schedule.   You also have to set urb->interval to say
how often to make transfers; it's often one per frame (which is once
every microframe for highspeed devices).  The actual interval used will
be a power of two that's no bigger than what you specify.

对于ISO传输,你必须填补usb_iso_packet_descriptor的结构,通过usb_alloc_urb(N,mem_flags)分配结束时的URB,要排定每个数据包。
你还必须设置URB->设置间隔多久时间进行转移, 这个时间往往是一个帧(这是一次微帧的高速设备)。
将使用实际的间隔会变成2的幂次方,但是不会大于你所限定的数值。

The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value.  If
ISO_ASAP scheduling is used, urb->start_frame is also updated.

usb_submit_urb()调用修改urb的时间间隔实施的时间间隔值,该值是小于或等于所需的时间间隔值。
如果使用ISO_ASAP调度,URB-> start_frame中也被更新。

For each entry you have to specify the data offset for this frame (base is
transfer_buffer), and the length you want to write/expect to read.
After completion, actual_length contains the actual transferred length and
status contains the resulting status for the ISO transfer for this frame.
It is allowed to specify a varying length from frame to frame (e.g. for
audio synchronisation/adaptive transfer rates). You can also use the length
0 to omit one or more frames (striping).

对于每个条目,你必须指定这个框架(基本是transfer_buffer),你想要写的长度/期望读的数据偏移。
项目建成后,actual_length包含实际传输长度,status包含ISO传输这个框架包含的结果状态。
它被允许指定一个不同的帧与帧之间的长度(例如,音频同步/自适应传输速率)。您还可以使用长度为0的缺省一个或多个帧(分段)。

For scheduling you can choose your own start frame or ISO_ASAP. As explained
earlier, if you always keep at least one URB queued and your completion
keeps (re)submitting a later URB, you'll get smooth ISO streaming (if usb
bandwidth utilization allows).


调度方面,您可以选择您的自己的起始帧或ISO_ASAP。
如前所述,如果你始终保持至少一个URB排队,并完成保持(重新)提交以后URB,你就会得到一个顺畅的ISO流(如果USB带宽利用率允许)。

If you specify your own start frame, make sure it's several frames in advance
of the current frame.  You might want this model if you're synchronizing
ISO data with some other event stream.

如果您指定自己的起始帧,确保它在当前帧的前几帧。如果你与其他一些事件流同步ISO数据,你可能会需要这个模式。


1.9. How to start interrupt (INT) transfers?/如何启动中断的(INT)转移?

Interrupt transfers, like isochronous transfers, are periodic, and happen
in intervals that are powers of two (1, 2, 4 etc) units.  Units are frames
for full and low speed devices, and microframes for high speed ones.
The usb_submit_urb() call modifies urb->interval to the implemented interval
value that is less than or equal to the requested interval value.

像同步传输,中断传输,是周期性的,而发生的时间间隔是2的幂次方(1,2,4等)的单位。
单位是全速和低速设备和高速的微帧的帧。usb_submit_urb()调用修改urb->interval所实现的的时间间隔值,该值小于或等于所需的时间间隔值。

In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically
restarted when they complete.  They end when the completion handler is
called, just like other URBs.  If you want an interrupt URB to be restarted,
your completion handler must resubmit it.

与以前的版本不同的是,在Linux 2.6中,中断URB的都不会自动重新启动,当他们完成。
他们最终完成处理程序被调用时,就像其他URB的。如果你想重新启动中断URB,你的完成处理程序必须重新提交。

 

这篇关于/Documentation/usb/URB.txt的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083667

相关文章

oracle数据导出txt及导入txt

oracle数据导出txt及导入txt ORACLE数据导出TXT及从TXT导入: 导出到TXT文件: 1、用PL/SQL DEV打开CMD窗口。 2、spool d:/output.txt; 3、set heading off; --去掉表头 4、select * from usergroup; 5、spool off; www.2ct

USB - USB在消费领域的应用

Switching in USB Consumer Applications 通用串行总线(USB)已成为满足终端设备之间日益增长的快速数据传输需求的主流接口--例如,在个人电脑和便携式设备(如手机、数码相机和个人媒体播放器)之间下载和上传数据。 The universal serial bus (USB) has become a dominant

离线linux通过USB连接并使用手机网络

离线linux通过USB连接并使用手机网络 引场景 引 离线环境要安装一些软件特别麻烦,要自己去官网下载对应的包,然后上传到服务器上,再解压,编译,执行,配置变量等等,错一步都可能安装失败。有网络的话使用yum或者是docker镜像来安装就非常方便。这里记录一下之前在centos上通过USB连接手机并使用手机网络来做这些基础工作时所遇到的网络问题。 场景 首先手机连上服务器主

AG32 MCU是否支持DFU下载实现USB升级

1、AG32 MCU是否支持DFU下载实现USB升级呢? 先说答案是NO. STM32 可以通过内置DFU实现USB升级,AG32 MCU目前不支持。但用户可以自己写一个DFU, 作为二次boot. 2、AG32 MCU可支持的下载方式有哪些呢? 我们AG32裸机下载只支持uart和jtag. 用户可以通过UART实现ISP升级。所以虽然不支持DFU,但是用户仍然可以通过UART实现升级。 3

c++写txt文件

// Txt_Write.cpp : 定义控制台应用程序的入口点。#include "stdafx.h"#include<iostream>#include<fstream>using namespace std;//将int _tmain(int argc, _TCHAR* argv[]){ofstream in;in.open("shuchu.txt",ios::trunc);/

c++ 读取txt文件

1,按行读取 // TEST_Read.cpp : 定义控制台应用程序的入口点。#include "stdafx.h"#include<iostream>#include<string>#include<fstream>//读取文件所需的文件头//以下为读取文件的一种方法:将文件每行内容存储到字符串中,再输出字符串using namespace std;int _tmain(int

ChatTTS增强版V3【已开源】,长文本修复,中英混读,导入音色,批量SRT、TXT

ChatTTS增强版V3来啦!本次更新增加支持导入SRT、导入音色等功能。结合上次大家反馈的问题,修复了长文本、中英混读等问题。 项目已开源(https://github.com/CCmahua/ChatTTS-Enhanced) 项目介绍 V3 ChatTTS增强版V3,长文本修复,中英混读,导入音色,批量SRT、TXT,代码开源_哔哩哔哩_bilibili V2 ChatTTS

计算机基础:公司usb被禁用了该怎么恢复使用

主要有两个方法: (1):win+r键,弹出cmd命令框后,在输入gpedit.msc------》计算机配置或者用户配置---------------------》管理模板---------》系统------》可移动存储访问,然后查看可移动磁盘的配置权限,如果状态不是未配置,就双击修改为未配置 (2):win+r键,弹出cmd命令框后,在输入regedit,然后找到如下位置:HKEY_LOC

关于ROS包中CMakeList.txt中几个常用的命令的作用 ——————(二)

目录 (5)catkin_package() (6)add_library()    (7)add_dependencies( []...) 接(一)关于ROS包中CMakeList.txt中几个常用的命令的作用 ——————(一)_u012057432的博客-CSDN博客,以下是其他相关的配置命令,有些不是必要的,但是却十分常用,但是也是十分重要的。 (5)catkin_packa

关于ROS包中CMakeList.txt中几个常用的命令的作用 ——————(一)

目录 (1)find_package(catkin REQUIRED  COMPONENTS  ...) (2)include_directories()  (3)add_executable(  src1 src2 ...)   (简易写法) (4)target_link_libraries( lib1  lib2 ...) (简易写法,lib是依赖库的路径) 重点的命令总结: