Linux UVC 摄像头知识整理之USB概述

                         Linux UVC摄像头驱动流程
  最近在学习USB摄像头,所谓好记性不如烂笔头,现在将自己所学的东西整理一下。
  学习USB摄像头之前,先整理下USB有关概念。
1.  USB 有关知识            
   USB通信采用主从结构,实现主机控制器和外围设备的通信。
   USB主机控制器有UHCI(通用主机控制器接口),OHCI(开放主机控制器接口),EHCI(增强主机控制器接口),USB OTG控制器接口等。
   主机控制器内嵌一个根集线器硬件,根集线器是逻辑集线器,多个USB接口共用,端口可以和内部或外部集线器相连,扩展更多,级联下来,可以构成树状。
   USB设备传输数据模式有4种:
   A:控制传输,用来传输外设和主机之间的控制、状态、配置等信息。
   B:批量传输,传输大量时延要求不高的数据。
   C:中断传输,传输数据量小,对传输时延敏感,要求立即响应。
   D:等时传输,传输实时数据,传输速率预先可知。
   USB设备每个可寻址单元称为端点,为每个端点分配的地址称为端点地址,每个端点都有与之相关的传输模式;地址为0的端点专门用来配置设备,控制管道和它相连,完成设备枚举过程。
       端点可以沿上行方向发送数据,也可以沿下行方向接收数据,前者称为IN传输,后者称为OUT传输,两者地址空间分开的,所以可以一个IN端点和一个OUT端点可以有相同地址。![USB子系统](https://img-blog.csdn.net/20171009144242409?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzM0MzIxODk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  编写USB驱动程序所用到的数据结构,有如下重要的几个。

usb_device 属于USB子系统,该结构体在内核中代表所驱动的设备。

   struct usb_device {
    int     devnum;
    char        devpath[16];
    u32     route;
    enum usb_device_state   state;
    enum usb_device_speed   speed;

    struct usb_tt   *tt;
    int     ttport;

    unsigned int toggle[2];

    struct usb_device *parent;
    struct usb_bus *bus;
    struct usb_host_endpoint ep0;

    struct device dev;

    struct usb_device_descriptor descriptor;
    struct usb_host_bos *bos;
    struct usb_host_config *config;

    struct usb_host_config *actconfig;
    struct usb_host_endpoint *ep_in[16];
    struct usb_host_endpoint *ep_out[16];

    char **rawdescriptors;

    unsigned short bus_mA;
    u8 portnum;
    u8 level;

    unsigned can_submit:1;
    unsigned persist_enabled:1;
    unsigned have_langid:1;
    unsigned authorized:1;
    unsigned authenticated:1;
    unsigned wusb:1;
    unsigned lpm_capable:1;
    unsigned usb2_hw_lpm_capable:1;
    unsigned usb2_hw_lpm_besl_capable:1;
    unsigned usb2_hw_lpm_enabled:1;
    unsigned usb2_hw_lpm_allowed:1;
    unsigned usb3_lpm_u1_enabled:1;
    unsigned usb3_lpm_u2_enabled:1;
    int string_langid;

    /* static strings from the device */
    char *product;
    char *manufacturer;
    char *serial;

    struct list_head filelist;

    int maxchild;

    u32 quirks;
    atomic_t urbnum;

    unsigned long active_duration;

#ifdef CONFIG_PM
    unsigned long connect_time;

    unsigned do_remote_wakeup:1;
    unsigned reset_resume:1;
    unsigned port_is_suspended:1;
#endif
    struct wusb_dev *wusb_dev;
    int slot_id;
    enum usb_device_removable removable;
    struct usb2_lpm_parameters l1_params;
    struct usb3_lpm_parameters u1_params;
    struct usb3_lpm_parameters u2_params;
    unsigned lpm_disable_count;
}; 

URB(USB Request Block,USB请求块),USB传输数据机制的核心数据结构,供USB协议栈使用。

struct urb {
    /* private: usb core and host controller only fields in the urb */
    struct kref kref;       /* reference count of the URB */
    void *hcpriv;           /* private data for host controller */
    atomic_t use_count;     /* concurrent submissions counter */
    atomic_t reject;        /* submissions will fail */
    int unlinked;           /* unlink error code */

    /* public: documented fields in the urb that can be used by drivers */
    struct list_head urb_list;  /* list head for use by the urb's
                     * current owner */
    struct list_head anchor_list;   /* the URB may be anchored */
    struct usb_anchor *anchor;
    struct usb_device *dev;     /* (in) pointer to associated device */
    struct usb_host_endpoint *ep;   /* (internal) pointer to endpoint */
    unsigned int pipe;      /* (in) pipe information */
    unsigned int stream_id;     /* (in) stream ID */
    int status;         /* (return) non-ISO status */
    unsigned int transfer_flags;    /* (in) URB_SHORT_NOT_OK | ...*/
    void *transfer_buffer;      /* (in) associated data buffer */
    dma_addr_t transfer_dma;    /* (in) dma addr for transfer_buffer */
    struct scatterlist *sg;     /* (in) scatter gather buffer list */
    int num_mapped_sgs;     /* (internal) mapped sg entries */
    int num_sgs;            /* (in) number of entries in the sg list */
    u32 transfer_buffer_length; /* (in) data buffer length */
    u32 actual_length;      /* (return) actual transfer length */
    unsigned char *setup_packet;    /* (in) setup packet (control only) */
    dma_addr_t setup_dma;       /* (in) dma addr for setup_packet */
    int start_frame;        /* (modify) start frame (ISO) */
    int number_of_packets;      /* (in) number of ISO packets */
    int interval;           /* (modify) transfer interval
                     * (INT/ISO) */
    int error_count;        /* (return) number of ISO errors */
    void *context;          /* (in) context for completion */
    usb_complete_t complete;    /* (in) completion routine */
    struct usb_iso_packet_descriptor iso_frame_desc[0];
                    /* (in) ISO ONLY */
};

URB使用分三个步骤:分配内存,初始化,提交。

和URB相关的管道有关概念:
管道包括:端点地址,传输方向,数据传输模式。
管道是URB重要成员,为USB传输提供地址信息,USB核心提供现成的宏来创建管道。

USB标准定义一系列描述符数据结构来保存设备信息:
设备描述符存放设备普通信息,比如产品ID和设备ID;
配置描述符存放设备配置模式,如设备是总线供电还是自己供电;
接口描述符使得USB能够支持更多功能;
端点描述符存放设备最终的端点信息;

下面贴上一个例子,是书里讲的一个遥控卡的例子。

/* Define these values to match your devices */
#define USB_SKEL_VENDOR_ID  0xABCD
#define USB_SKEL_PRODUCT_ID 0xCDEF

/* table of devices that work with this driver */
static const struct usb_device_id tele_table[] = {
    { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
    { }                 /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, tele_table);
...
static struct usb_driver tele_driver = {
    .name =     "tele",
    .probe =    tele_probe,
    .disconnect =   tele_disconnect,
    .id_table = tele_table,
};
static int __init tele_init(void){
/*Register with the USB core*/
result = usb_register(&tele_driver);

    /*...*/
    return 0;
}

static void __exit tele_exit(void){
/*Unregister from the USB core*/
   usb_deregister(&tele_driver);
   return ;
}
module_init(tele_init);
module_exit(tele_exit);

USB_DEVICE()宏利用提供的厂商ID和产品ID创建usb_divce_id结构体。
MODULE_DEVICE_TABLE()宏把tele_ids记录在模块映像中,一旦有设备插入,驱动就能被加载到内核运行。

暂时整理到这里,以后整理read等其他函数分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值