linux ------ USB设备驱动

     USB是通用串行接口,具有USB接口的设备很多,比如U盘,MP3,PC CAMERA等。USB分主机端与设备端,在LINUX系统里面,在USB主机端集成了一个根HUB和主控制器,系统启动的时候会对根HUB与主控制器进行牧举并加载驱动,然后会启动一个守护进程专门监视控制器总线上的变化,如果有新的设备接入,该守护进程就会被调用并对设备进行枚举,然后会产生一个热插拔的事件。LINUX内核已经写好USB HUB与主控制器的代码,不需驱动程序员进行修改,驱动程序员只需理解设备端的程序与架构,写USB设备驱动程序。

    一. USB设备架构简单描述

         在USB传输过程中,总线上流动的数据是按照包来解释的,各种包又由协议所定义的基本域构成,不同的包构成传输事务,一个或多个事务可以完成用户所需要的传输。

         USB协议定义的一些基本单位包括:域,包,事务,数据传输类型,USB中描述符,USB数据流模型等。

         域:USB协议定义了一系列有统一解释的二进制序列,这些序列称为域。分为:同步域、标识域、地址域、端点域、帧号域、数据域、校验域。

         包:包是USB的基本数据单元,由一系列的域组成。USB中的包类型有:令牌包、数据包、握手包、特殊包。

         事务:事务是某种传输类型的一次实例,多次事务完成用户指定的传输。USB的事务有:IN事务、OUT事务、SETUP事务。

         数据传输类型:USB协议寇义了四种数据传输类型,即控制传输、中断传输、批量传输和同步传输。

        描述符:USB作为一种总线本身只是一种传输通道,并不能完成特殊的功能,它需要集成到设备上。而USB设备的接入不需要人工来于预,所以必须事先规定若干描述
符来标识设备的功能和配置,这样在主机端枚举并配置完设备后才能匹配适当的主机端驱动程序。USB的描述符号有:设备描述符、配置描述符、接口描述符、端点描述符号、字符串描述符。

        数据流模型:USB的数据流模型摘述了USB总线上的数据包是如何在主机和设备之间传递的。数据流模型涉及两个概念:端口和管道。

        在PC上设备驱动程序通过调用USBD,发出输入输出请求包URB,USB驱动程序接到请求后,调用主控制驱动程序接口HCD,将URB转换为USB的传输。根据数据量的大小,一个URB可以包含一个或多个USB传输,然后主控制器驱动程序将USBB传输分解为总线事务,主控制器以包的形式把数据传给设备。

        讲了这个USB相关的基本元素,有点抽象,可以简单概括一下,USB系统架构实际就是包括USB主控制器,USB HUB总线,USB 设备3部分,而域、包、事务、传输类型、描述符与数据流模型把它们联系组成一个整体,保证它们之间的正常运作。可以把USB通信系统比喻为一个物流系统,USB控制器就是需要快递服务的买家,USB HUB总线是物流的高速公路,USB设备就是快递派送的目的地。域、包是物流快递的具体物体,包好比就是一个包裹,域是包裹上的标签信息,比如收件人名字、地址等。事务就是一次快递的执行,比如发快递,收快递,或快递打包。传输类型可以比喻为快递派送中的具体派送方式,控制、中断传输就好比是用电动车或面包车短途内把包裹送过去,批量、同步传输就是用大卡车或火车把大量的包裹运到目的地。描述符可以比喻为物流快递过程中某个环节的描述,设备描述符可以比喻为“快递公司顺丰需要把顾客A的物品N送到目的地D"等。数据流模型URB可以为快递员+快递工具,比如快递员A与他的电动车,或大卡车与派送司机。

    二. 相关数据结构

        1. USB端点描述符usb_endpoint_descriptor

             struct usb_endpoint_descriptor{
                      __u8  bLength;                                    //描述符长度
                      __u8  bDescriptorType;                     //描述符类型
                      __u8  bEndpointAddress;                 //端点地址,包含端点方向的信息
                      __u8  bmAttributes;                           //端点类型,中断、控制、批量或同步中的一种
                      __le16 wMaxPacketSize;//端点一次处理的最大字节数。发送的BULK 包能大于这个数值,但会被分割传送。
                      __u8  bInterval;      //如果端点是中断类型,该值是端点的间隔设置,以毫秒为单位。
                      /* NOTE:  these two are _only_ in audio endpoints. */
                      /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
                      __u8  bRefresh;
                      __u8  bSynchAddress;
               } __attribute__ ((packed));     //这行表示取消字节对齐的优化,用该结构实际的字节数。

        2. USB接口描述符usb_interface

             struct usb_interface{
                     struct usb_host_interface *altsetting;             //接口设置数组指针,一个接口有多个设置
                     struct usb_host_interface *cur_altsetting; /* the currently active alternate setting */ //当前活动的设置
                     unsigned num_altsetting; /* number of alternate settings *///接口设置总数
                     struct usb_interface_assoc_descriptor *intf_assoc; 
                     int minor;   /* minor number this interface is bound to */     //次设备号
                     enum usb_interface_condition condition;  /* state of binding */
                     unsigned sysfs_files_created:1; /* the sysfs attributes exist */
                     unsigned ep_devs_created:1; /* endpoint "devices" exist */
                     unsigned unregistering:1; /* unregistration is in progress */
                     unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
                     unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */
                     unsigned needs_binding:1; /* needs delayed unbind/rebind */
                     unsigned reset_running:1;
                     unsigned resetting_device:1; /* true: bandwidth alloc after reset */
                     struct device dev;  /* interface specific device info */   //接口相关的设备信息
                     struct device *usb_dev;     //相关的USB设备
                     atomic_t pm_usage_cnt;  /* usage counter for autosuspend */
                     struct work_struct reset_ws; /* for resets in atomic context */
             };

        3. USB设备描述符usb_device

            struct usb_device {
                   int  devnum;               //USB设备在总线上的编号
                   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;  //端点0
                   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];  //最多支持15个端点
                   struct usb_host_endpoint *ep_out[16];
                   char **rawdescriptors;
                   unsigned short bus_mA;
                   u8 portnum;
                   u8 le

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值