urb介绍
usb requedt block 简称urb
usb总线就像一条高速公路,货物、人流之类的可以看成是系统与设备交互的数据,而urb就可以看成是汽车。
USB的endpoint有四种不同类型,也就是说能在这条高速公路上流动的数据有四种,但是对汽车没有要求,所以可以用urb运载这四种数据
不过首先要告诉运什么,目的地什么
1. 运货首先有车 第一步创建一个urb
struct urb *usb_alloc_urb(int isoc_packets, int mem_flags);
2.要承载数据,还要告诉司机目的信息跟要运的货物,对于不同的数据,系统提供不同的函数
对于中断urb,使用
void usb_fill_int_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,void *transfer_buffer, int buffer_length,
usb_complete_t complete, void *context, int interval);
transfer_buffer是一个要送/收的数据的缓冲,buffer_length是它的长度,complete是urb完成回调函数的入口,
context由用户定义,可能会在回调函数中使用的数据,interval就是urb被调度的间隔。
对于批量urb和控制urb
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
void *transfer_buffer, int buffer_length, usb_complete_t complete,void *context);
void usb_fill_bulk_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
unsigned char* setup_packet,void *transfer_buffer, int buffer_length, usb_complete_t complete,void *context);
参数分析:urb要被初始化的urb指针 dev目标设备,被发送到哪个USB设备 pipe这个urb要被发送到USB设备的特定端点
transfer_buffer是一个要送/收的数据的缓冲 buffer_length是它的长度 complete是urb完成回调函数的入口
context由用户定义,可能会在回调函数中使用的数剧 interval就是urb被调度的间隔
3. 有了汽车,有了司机,下一步就是开始运货,使用下面函数来提交urb
int usb_submit_urb(struct urb *urb, int mem_flags);
mem_flags有几种:GFP_ATOMIC、GFP_NOIO、GFP_KERNEL,通常在中断上下文环境我们会用GFP_ATOMIC。
4. 会掉函数
这里skel_write_bulk_callback就是一个完成回调函数,而他做的主要事情就是检查数据传输状态和释放urb: