USB驱动程序(五)————USB驱动函数总结

更新时间:2023-06-26 15:32:42 阅读: 评论:0

USB 驱动程序(五)————USB 驱动函数总结
pipe 管道
  管道是USB 设备通信的通道,内核中提供了创建管道的宏,从宏中我们可以分析出,管道是⼀个 int 型的变量,由设备号、端点地址、端点类型组合⽽成。URB
分配URB 填充URB
控制传输
usb_[snd|rcv][ctrl|int|bulk|isoc]pipe(dev, endpoint)例:struct usb_device *dev = interface_to_usbdev(intf);struct usb_endpoint_descriptor *endpoint;int pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);1
2
3
4
5
#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)1
2
3
4
5
6
7
8
9
10
11排球训练计划
12
13
正宗粉蒸肉14
15
16
static  inline  unsigned  int  __create_pipe(struct  usb_device *dev,        unsigned  int  endpoint){    return  (dev->devnum << 8) | (endpoint << 15);}
1
2
3
4
5 usb_alloc_urb(int  iso_packets, gfp_t mem_flags)
1
中断传输批量传输等时传输
鬼谷子技能static  inline  void  usb_fill_control_urb(struct  urb *urb,                    struct  usb_device *dev,                    unsigned  int  pipe,                    unsigned  char  *tup_packet,                    void  *transfer_buffer,                    int  buffer_length,                    usb_complete_t complete_fn,                    void  *context){   
urb->dev  = dev;    urb->pipe = pipe;    urb->tup_packet = tup_packet;    urb->transfer_buffer = transfer_buffer;    urb->transfer_buffer_length = buffer_length;    urb->complete = complete_fn;    urb->context  = context;}
1
传奇是什么意思
2
3
玩具猫4
5
6
7
8
9
10
11
12
13
14
15
16
17static 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 ->dev  = dev;    urb ->pipe = pipe;    urb ->transfer_buffer = transfer_buffer;    urb ->transfer_buffer_length = buffer_length;    urb ->complete = complete_fn;    urb ->context = context;    if  (dev ->speed == USB_SPEED_HIGH)  // 相⽐批量传输和控制传输,实时传输和中断传输多这个参数,表⽰周期        urb ->interval = 1 << (interval - 1);    el        urb ->interval = interval;    urb ->start_frame = -1;}
1
2
3
4
5
6
7
8
9
10
11小孩爬山
12
13
14
15
16
17土鸡炖香菇
18
19
20
21static  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){    urb->dev = dev;    urb->pipe = pipe;    ur
b->transfer_buffer = transfer_buffer;    urb->transfer_buffer_length = buffer_length;    urb->complete = complete_fn;    urb->context = context;}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  不幸的是,等时urb 没有和中断、控制、批量urb 类似的初始化函数,因此它们在提交到USB 核⼼之前,需要在驱动程序中⼿动的初始化。例如:同步提交URB
  有时候 USB 驱动程序只是要发送或者接收⼀些简单的 USB 数据,⽽不是想创建⼀个 struct urb ,初始化它,然后等待该 urb 接收函数运⾏这些⿇烦事都⾛⼀遍。内核提供了同步提交 urb 的接⼝。
控制传输  如果函数调⽤成功,返回值为 0 ,如果返回⼀个负数,表⽰发⽣⼀个错误。如果成功 actual_lenth 参数包含从该消息发送或者接收的字节数。
举例:  控制传输,通过 pipe 可以看出传输⽅向是设备到主机,和默认端点0通信,请求类型是请求描述符,具体的类型和索引。传输完成时,描述符就被存放在 buf 所指向的缓冲区中了。
usb_ctrl_msg 分析
urb->dev = dev;urb->context = uvd;urb->pipe = usb_rcvisocpipe(dev,uvd->video_endp-1);urb->interval = 1;urb->transfer_flags = URB_IOS_ASAP ;urb->transfer_buffer = can->sts_buf[i];urb_complete = konicawc_isoc_irq;urb->number_of_packets = FRAMES_PRE_DESC ;urb->transfer_buffer_lenth = FRAMES_PRE_DESC ;for (j=0; j < FRAMES_PRE_DESC ; j++){    urb->ios_frame_desc[j].offt  = j;    urb->ios_frame_desc[j].length  = 1;}
1
2
3
4
5
6
7
8
9
10
qq音乐听歌识曲11
12
13int  usb_control_msg(struct  usb_device *dev,                    unsigned int  pipe,                    __u8 request,                    __u8 requesttype,                    __u16 value ,                    __u16 index,                    void  *data,                    __u16 size,                    int  timeout  // 超时时间,以jiffies 为单位                    )
1
2
3
4
5
6
7
8
9
10/* usb_get_descriptor */    result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),            USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,            (type  << 8) + index, 0, buf, size,            USB_CTRL_GET_TIMEOUT);
1
2
3
4
5
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;    // 填充 tup packet    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;}123456789101112131415161718192021222324252627282930static int  usb_internal_control_msg(struct usb_device *usb_dev ,                                    unsigned int  pipe ,                                    struct usb_ctrlrequest *cmd ,                                    void *data ,                                    int  len,                                    int  timeout){    struct urb *urb ;    int  retv;    int  length ;    urb = usb_alloc_urb(0, GFP_NOIO);    if  (!urb)        return  -ENOMEM;    usb_fill_control_urb(urb, usb_dev, pipe , (unsigned char *)cmd, data,                len, usb_api_blocking_completion, NULL);    retv = usb_start_wait_urb(urb, timeout, &length );    if  (retv < 0)        return  retv;    el        return  le
ngth ;}123456789101112131415161718192021222324
static  inline  void  usb_fill_control_urb(struct  urb *urb,                    struct  usb_device *dev,                    unsigned  int  pipe,                    unsigned  char  *tup_packet,                    void  *transfer_buffer,                    int  buffer_length,                    usb_complete_t complete_fn,                    void  *context){    urb->dev  = dev;    urb->pipe = pipe;    urb->tup_packet = tup_packet;    urb->transfer_buffer = transfer_buffer;    urb->transfer_buffer_length = buffer_length;    urb->complete = complete_fn;    urb->context  = context;}1234567891011121314151617struct  api_context {    struct  completion  done;    int          status;};static  int  usb_start_wait_urb(struct  urb *urb, int  timeout, int  *actual_length){    struct  api_context ctx;    unsigned long  expire;    int  retval;    // 完成量    init_completion(&ctx.done);    urb->context = &ctx;    urb->actual_length = 0;    retval = usb_submit_urb(urb, GFP_NOIO);    if  (unlikely(retval))        goto  out ;    expire = timeout ? mcs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;    // 等待完成,返回值为0表⽰超时    if  (!wait_for_completion_timeout(&ctx.done, expire)) {        usb_kill_urb(urb);        retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status);        dev_dbg(&urb->dev->dev,            "%s timed out on ep%d%s len=%u/%u\n",            current->comm,            usb_endpoint_num(&urb->ep->desc),            usb_urb_dir_in(urb) ? "in" : "out",            urb->actual_length,            urb->transfer_buffer_length);    }
el        retval = ctx.status;out :    if  (actual_length)        *actual_length = urb->actual_length;    usb_free_urb(urb);    return  retval;}123456789101112131415161718192021222324252627282930313233343536373839

本文发布于:2023-06-26 15:32:42,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1055912.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:传输   端点   发送   类型
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图