"USB 接口"是逻辑上的 USB 设备 ,编写的 usb_driver 驱动程序,支持的是"USB 接口":
在 USB 设备驱动程序中,能使用的 USB 函数都在这个头文件里:includelinuxusb.h
。
使用这些接口函数的主要目的是传输数据,传输数据的对象是 USB 设备里的某个 endpoint,这被称为 pipe:
/* Create various pipes... */
#define usb_sndctrlpipe(dev, endpoint)
((PIPE_CONTROL < < 30) | __create_pipe(dev, endpoint))
#define usb_rcvctrlpipe(dev, endpoint)
((PIPE_CONTROL < < 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)
#define usb_sndisocpipe(dev, endpoint)
((PIPE_ISOCHRONOUS < < 30) | __create_pipe(dev, endpoint))
#define usb_rcvisocpipe(dev, endpoint)
((PIPE_ISOCHRONOUS < < 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)
#define usb_sndbulkpipe(dev, endpoint)
((PIPE_BULK < < 30) | __create_pipe(dev, endpoint))
#define usb_rcvbulkpipe(dev, endpoint)
((PIPE_BULK < < 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)
#define usb_sndintpipe(dev, endpoint)
((PIPE_INTERRUPT < < 30) | __create_pipe(dev, endpoint))
#define usb_rcvintpipe(dev, endpoint)
((PIPE_INTERRUPT < < 30) | __create_pipe(dev, endpoint) | USB_DIR_IN)
对于控制传输、批量传输、中断传输,有 3 个同步函数可以用来直接发起传输。这些函数内部会创建、填充、提交一个 URB("usb request block"),并等待它完成或超时。
函数原型如下:
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);
int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout);
int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout);
使用 URB 进行传输时,它是异步方式:需要先分配、构造、提交一个 URB("usb request block"),当传输完成后,它的回调函数被调用。
关键就在于需要填充 URB:
函数原型如下:
struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags);
void usb_free_urb(struct urb *urb);
发起 USB 传输时,数据保存在 buffer 里。这个 buffer 可以是一般的 buffer,也可以是 DMA Buffer。
对于一般的 buffer,在提交 URB 时会临时分配一个 DMA Buffer:
我们可以直接使用 DMA Buffer,函数原型如下:
void *usb_alloc_coherent(struct usb_device *dev, size_t size, gfp_t mem_flags,dma_addr_t *dma);
void usb_free_coherent(struct usb_device *dev, size_t size, void *addr,dma_addr_t dma);
对于控制传输、批量传输、中断传输,分别有如下函数:
static inline void usb_fill_control_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_fn,
void *context);
static inline 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_fn,
void *context);
static inline 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_fn,
void *context,
int interval);
如果 URB 使用 DMA Buffer,那么还需要设置一个 flag 表明这点:
urb- >transfer_dma = DMA address of buffer; // usb_alloc_coherent的输出参数
urb- >transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
构造好 URB 后,需要提交到 USB 系统里,才能启动传输。
int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
已经提交的 URB,可以取消它,有 2 个函数:
void usb_kill_urb(struct urb *urb);
int usb_unlink_urb(struct urb *urb);
全部0条评论
快来发表一下你的评论吧 !