本文共 3490 字,大约阅读时间需要 11 分钟。
以后记录东西要场景化,现在有些想不起来URB这个点是怎么引入的了,引以为戒。
参考链接:
https://www.cnblogs.com/alan666/p/8311874.html
USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结构体。
创建urb 结构体的函数为:
struct urb *usb_alloc_urb(int iso_packets, int mem_flags); iso_packets 是这个urb 应当包含的等时数据包的数目,若为0 表示不创建等时数据包。 mem_flags 参数是分配内存的标志,和kmalloc()函数的分配标志参数含义相同。如果分配成功,该函数返回一个urb 结构体指针,否则返回0。 urb 结构体在驱动中不能静态创建,因为这可能破坏USB 核心给urb 使用的引用计数方法。 usb_alloc_urb()的“反函数”为: void usb_free_urb(struct urb *urb); 该函数用于释放由usb_alloc_urb()分配的urb 结构体。drivers/usb/core/message.c
/** * usb_control_msg - Builds a control urb, sends it off and waits for completion * @dev: pointer to the usb device to send the message to * @pipe: endpoint "pipe" to send the message to * @request: USB message request value * @requesttype: USB message request type value * @value: USB message value * @index: USB message index value * @data: pointer to the data to send * @size: length in bytes of the data to send * @timeout: time in msecs to wait for the message to complete before timing * out (if 0 the wait is forever) * * Context: !in_interrupt () * * This function sends a simple control message to a specified endpoint and * waits for the message to complete, or timeout. * * If successful, it returns the number of bytes transferred, otherwise a * negative error number. * * Don't use this function from within an interrupt context, like a bottom half * handler. If you need an asynchronous message, or need to send a message * from within interrupt context, use usb_submit_urb(). * If a thread in your driver uses this call, make sure your disconnect() * method can wait for it to complete. Since you don't have a handle on the * URB used, you can't cancel the request. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout){ struct usb_ctrlrequest *dr; int ret; dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); if (!dr) return -ENOMEM; dr->bRequestType = requesttype; dr->bRequest = request; dr->wValue = cpu_to_le16(value); dr->wIndex = cpu_to_le16(index); dr->wLength = cpu_to_le16(size); /* dbg("usb_control_msg"); */ ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout); kfree(dr); return ret;}EXPORT_SYMBOL_GPL(usb_control_msg);
该函数建立一个控件urb,将其发送出去并等待完成
首先该函数也可以创建urb,并且具备后续的处理能力static inline void usb_set_intfdata(struct usb_interface *intf, void *data){ dev_set_drvdata(&intf->dev, data);} * @probe: Called to see if the driver is willing to manage a particular * interface on a device. If it is, probe returns zero and uses * usb_set_intfdata() to associate driver-specific data with the * interface. It may also use usb_set_interface() to specify the * appropriate altsetting. If unwilling to manage the interface, * return -ENODEV, if genuine IO errors occurred, an appropriate * negative errno value.@probe:调用以查看驱动程序是否愿意管理设备上的特定接口。 如果是,则探测返回零,并使用usb_set_intfdata()将特定于 驱动程序的数据与接口相关联。 它还可以使用usb_set_interface() 指定适当的altsetting。 如果不愿意管理该接口,则返回-ENODEV, 如果发生真正的IO错误,则为适当的负errno值。
在做openni处理深度摄像头数据的时候,运行demo,随着时间的推移,数据上来的速度越来越慢,怀疑与usb的频宽相关。