文章的主要目的是为了记录,其次希望自己做的东西越来越多以后,可以把这些东西整合、重塑,让自己的知识体系更加的立体、完整
以后记录东西要场景化,现在有些想不起来URB这个点是怎么引入的了,引以为戒。
URB请求块
参考链接:
https://www.cnblogs.com/alan666/p/8311874.html
1.urb 结构体
USB 请求块(USB request block,urb)是USB 设备驱动中用来描述与USB 设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的sk_buff 结构体。
2.urb 处理流程
创建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 结构体。
usb_control_msg函数
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,并且具备后续的处理能力
usb_set_intfdata函数
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值。
USB的频宽
在做openni处理深度摄像头数据的时候,运行demo,随着时间的推移,数据上来的速度越来越慢,怀疑与usb的频宽相关。