精华内容
下载资源
问答
  • usb驱动程序

    2013-01-17 08:43:08
    usb驱动程序
  • USB驱动程序

    2015-02-26 14:54:33
    USB驱动程序,用于USB插件的驱动程序。
  • USb驱动程序

    2013-08-04 22:15:57
    USB驱动程序,代码,关于USB驱动文档及完整代码 相互学习
  • USB驱动程序 USB驱动程序 USB驱动程序 USB驱动程序
  • USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序USB驱动程序
  • USB 驱动程序

    2014-02-18 17:32:22
    Linux设备驱动程序学习(16)-USB 驱动程序(一) http://linux.chinaunix.net/techdoc/install/2009/08/05/1128373.shtml Linux设备驱动程序学习(17)-USB 驱动程序(二) ...

    Linux设备驱动程序学习(16)-USB 驱动程序(一)

    http://linux.chinaunix.net/techdoc/install/2009/08/05/1128373.shtml

    Linux设备驱动程序学习(17)-USB 驱动程序(二)

    http://linux.chinaunix.net/techdoc/install/2009/08/05/1128374.shtml

    Linux设备驱动程序学习(18)-USB 驱动程序(三)

    http://linux.chinaunix.net/techdoc/install/2009/08/05/1128376.shtml

    Linux设备驱动程序学习(19)-USB 驱动程序(四)

    http://linux.chinaunix.net/techdoc/install/2009/08/05/1128379.shtml

    展开全文
  • 宇泰485USB驱动程序

    2018-07-10 10:58:25
    宇泰485USB驱动程序宇泰485USB驱动程序宇泰485USB驱动程序宇泰485USB驱动程序
  • MTP USB驱动程序

    2018-06-21 17:51:09
    MTP USB驱动程序 手机连接驱动程序WINDOWS XP驱动 .
  • 文章目录USB驱动程序简介USB驱动程序描述USB设备列表注册驱动Linux USB 描述符设备描述设备描述**配置描述:**接口描述接口设置接口描述符端点描述USB URBURB定义URB处理流程创建URB初始化URB提交URB处理URBUSB鼠标...

    USB驱动程序简介

    USB设备驱动程序(层次划分)
    在这里插入图片描述
    USB设备驱动程序位于不同的内核子系统和USB主控制器之间,USB核心为USB驱动程序提供一个用于访问和控制USB硬件的软件接口,使得USB设备驱动程序不必考虑USB硬件控制器。

    USB设备层次:
    在这里插入图片描述
    从上图可以看出,USB设备逻辑层次可以分为:设备、配置、接口、端点

    划重点:

    • USB设备驱动程序对应的是接口层次,也就是说每一个接口都要对应一个USB设备驱动程序

    USB驱动程序描述

    在Linux内核中,使用 struct usb_driver 结构描述一个 USB驱动。

    	struct usb_driver
    	{
    		const char *name; //驱动程序名
    	
    		/*当USB核心发现了该驱动能够处理USB接口时,调用次函数*/
    		int (*probe)(struct usb_interface *intf,const struct usb_device_id *id);
    	
    		/*当相应的USB接口被移除时,调用此函数*/
    		void (*disconnect)(struct usb_interface *intf);
    		
    		/*USB驱动能够处理的设备列表*/
    		const struct usb_device_id *id_table;
    	}; 
    

    USB设备列表

    一种设备:
    Linux内核提供了宏USB_DEVICE来定义一种USB设备的
    USB_DEVICE(vend,prod)

    参数

    • vend:USB Vendor ID
    • prod:USB Product ID

    例(USB OV511摄像头):
    USB_DEVICE(VEND_OMNIVISION,PROD_OV511)
    #define VEND_OMNIVISION 0x05A9
    #define PROD_OV511 0x0511

    struct usb_device_id
    在这里插入图片描述

    一类设备:

    Linux内核提供了宏USB_INTERFACE_INFO来协助定义一类USB设备
    USB_INTERFACE_INFO(cl,sc,pr)

    参数:

    • cl:bInterfaceClass value
    • sc:bInterfaceSubClass value
    • pr:bInterfaceProtocol value

    例(USB鼠标)

    	USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE)
    

    注册驱动

    Linux内核提供了函数usb_register来注册USB驱动程序。

    	static inline int usb_register(struct usb_driver *driver)
    

    Linux USB 描述符

    设备描述

    linux内核使用 struct usb_device 来描述一个USB 设备

    	struct usb_device
    	{
    		int devnum;  //USB设备号
    		char devpath[16];  //设备ID字符串
    		enum usb_device_state state;  //设备状态:未连接,已配置
    		enum usb_device_speed speed;  //高速;全速;低速
    	
    		struct usb_device_descriptor descriptor; //USB设备描述符
    		struct usb_host_config *config;
    		
    		char *product; //产品号
    		char *manufacturer;  //厂商名
    		char *serial;  //设备串号
    	};
    

    设备描述

    上面结构体中包含的结构体:usb_device_descriptor 来对应USB描述符中的 设备描述符

    	struct usb_device_descriptor
    	{
    		__u8 bLength;
    		__u8 bDescriptorTypr;
    		__le16 bcdUSB;
    		__u8 bDeviceClass;
    		__u8 bDeviceSubClass;
    		__u8 bDeviceProtocol;
    		__u8 bMaxPacketSize0;
    		__le16 idVendor;
    		__le16 idProduct;
    		__le16 bcdDevice;
    		__u8 iManufacturer;
    		__u8 iProduct;
    		__u8 iSerialNumber;
    		__u8 bNumConfigurations;
    	} __attribute__((packed));  //按字节对齐
    

    严格按照USB协议的USB设备描述符保持一致;

    配置描述:

    上面结构体 struct usb_device 中包含的结构体:usb_device_host_config描述USB配置

    	struct usb_host_config
    	{
    		struct usb_config_descriptor desc;  //配置描述符
    		char *string;  //配置的字符串(如果存在)
    		//接口链表
    		struct usb_interface *interface[USB_MAXINTERFACES];
    	};
    

    上述结构体中的 struct usb_config_descriptor
    在这里插入图片描述

    接口描述

    linux内核使用 struct usb_interface 来描述USB接口。

    	struct usb_interface
    	{
    		struct usb_host_interface *altsetting;  //接口设置数组
    		struct usb_host_interface *cur_altsetting; //当前设置
    		unsigned num_altsetting;  //设置数
    	};
    

    配置 VS 设置

    • 一个配置包含一个或多个接口
    • 一个接口包含一个或多个设置

    举例
    在这里插入图片描述

    接口设置

    linux内核使用 struct usb_host_interface 来描述USB接口设置

    	struct usb_host_interface
    	{
    		struct usb_interface_descriptor desc;//接口描述符
    		struct usb_host_endpoint *endpoint;  //接口包含的端点
    	};
    

    接口描述符

    linux内核使用 struct usb_interface_descriptor 来对应USB描述符中的接口描述符

    在这里插入图片描述

    端点描述

    linux内核使用 struct usb_host_endpoint 来描述USB端点

    	struct usb_host_endpoint
    	{
    		struct usb_endpoint_descriptor desc;  //端点描述符
    		struct list_head  usb_list;  //urb
    		
    		.........
    		.........
    	};
    

    在这里插入图片描述

    USB URB

    URB定义

    USB请求块(USB request block,urb)是USB设备驱动中用来描述与USB设备通信所用的基本载体和核心数据结构,非常类似于网络设备驱动中的 sk_buff 结构体,是USB主机与设备通信的“”电波“”。

    URB处理流程

    1. USB设备驱动程序创建并初始化一个访问特定USB设备特定端点的urb,并提交USB core;
    2. USB core提交该urb到USB主控制器驱动程序
    3. USB主控制器驱动程序根据该urb描述的信息,来访问USB设备;
    4. 当设备访问结束后,USB主控制器驱动程序通知USB设备驱动程序。

    创建URB

    创建URB函数为:

    	struct *usb_alloc_urb(int iso_packets,gtp_t mem_flags) 
    

    参数

    • iso_packets:urb所包含的等时数据包个数
    • mem_flags:内存分配标识(如GFP_KERNEL),参考kmalloc

    初始化URB

    • 对于中断urb,使用 usb_fill_int_urb 函数来初始化:
    	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:要初始化的urb指针;

    • dev:urb所要访问的设备;

    • pipe:要访问的端点所对应的管道,使用usb_sndintpipe()或usb_rcvintpipe()创建

    • transfer_buffer:要传输的数据缓冲区

    • buffer_length:transfer_buffer所指缓冲区长度

    • complete_fn:当完成urb所请求的操作时,要调用的回调函数;

    • context:complet_fn 函数所需的上下文,通常取值为dev;

    • interval:urb被调度的时间间隔

    • 对于批量urb,使用usb_fill_bulk_urb 函数来初始化

    • 对于控制urb,使用usb_fill_control_urb 函数来初始化

    • 等时urb没有像中断、控制和批量urb那样的初始化函数,我们只能手动地初始化urb

    提交URB

    在完成urb的创建和初始化后,urb便可以通过usb_submit_urb函数来提交后USB核心

    	int usb_submit_urb(struct urb *urb,gfp_t mem_flags)
    

    参数:

    • urb:执行urb的指针
    • mem_flags:内存分配标识,它用于告知USB核心如何分配内存缓冲区

    处理URB

    URB被提交后,USB核心指定主控制器驱动程序来处理该urb,在3种情况下,urb会被认为为处理完成

    1. urb 被成功发送给设备,并且设备返回正确的确认。如果 urb->status 为0,意味着对于一个输出urb,数据被成功发送;对于一个输入的urb,请求的数据被成功收到。
    2. 如果发送数据到设备或从设备接受数据时出现错误,urb->status将记录该错误值。
    3. urb 被“”取消“”,这发生在驱动通过 usb_unlink_urb()或usb_kill_urb()函数取消urb,或urb虽已提交,而USB设备被拔出的情况下。

    当urb处理完成后,urb完成函数将被调用。

    USB鼠标驱动程序分析设计

    代码部分 mouse.c

    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/kernel.h>
    #include <linux/usb/input.h>
    #include <linux/hid.h>
    #include <linux/slab.h>
    
    #define DRIVER_DESC "USB HID Boot Protocol mouse driver"
    #define DRIVER_LICENSE "GPL"
    
    MODULE_AUTHOR("silence");
    MODULE_DESCRIPTION(DRIVER_DESC);
    MODULE_LICENSE(DRIVER_LICENSE);
    
    struct usb_mouse
    {
            char name[128];
            char phys[64];
            struct usb_device *usbdev;
            struct input_dev *dev;
            struct urb *irq;
    
            signed char *data;
            dma_addr_t data_dma;
    };
    
    static void usb_mouse_irq(struct urb *urb)
    {
            struct usb_mouse *mouse = urb->context;
            signed char *data = mouse->data;
            struct input_dev *dev = mouse->dev;
            int status;
    
            //检测urb传输是否成功
            switch(urb->status)
            {
            case 0:         //success
                    break;
    
            case -ECONNRESET:     //unlink
            case -ENOENT:
            case -ESHUTDOWN:
                    return;
    
            //-EPIPE:should clear the halt
            default:         //error
                    goto resubmit;
            }
    
            //报告按键状态
            input_report_key(dev,BTN_LEFT,data[0] & 0x01);
            input_report_key(dev,BTN_RIGHT,data[0] & 0x02);
            input_report_key(dev,BTN_MIDDLE,data[0] & 0x04);
            input_report_key(dev,BTN_SIDE,data[0] & 0x08);
            input_report_key(dev,BTN_EXTRA,data[0] & 0x10);
    
            input_report_rel(dev,REL_X,data[1]);
            input_report_rel(dev,REL_Y,data[2]);
            input_report_rel(dev,REL_WHEEL,data[3]);
    		input_sync(dev);
    		
    resubmit:
            //提交下次传输
            status = usb_submit_urb(urb,GFP_ATOMIC);
            if(status)
                    err("can't resubmit intr,%s-%s/input0,status %d",mouse->usbdev->bus->bus_name,mouse->usbdev->devpath,status);
    }
    
    static int usb_mouse_open(struct input_dev *dev)
    {
            struct usb_mouse *mouse = input_get_drvdata(dev);
    
            mouse->irq->dev = mouse->usbdev;
            if(usb_submit_urb(mouse->irq,GFP_KERNEL))
                    return -EIO;
    
            return 0;
    }
    
    static void usb_mouse_close(struct input_dev *dev)
    {
            struct usb_mouse *mouse = input_get_drvdata(dev);
    
            usb_kill_urb(mouse->irq);
    }
    
    static int usb_mouse_probe(struct usb_interface *intf,const struct usb_device_id *id)
    {
            //设备描述usb_device
            //接口描述usb_interface
            struct usb_device *dev = interface_to_usbdev(intf);
    
            //接口设置描述
            struct usb_host_interface *interface;
    
            //端点描述符
            struct usb_endpoint_descriptor *endpoint;
    
            struct usb_mouse *mouse;
            struct input_dev *input_dev;
            int pipe,maxp;
            int error = -ENOMEM;
    		//获取当前接口设置
            interface = intf->cur_altsetting;
    
            //根据HID规范,鼠标只有一个端点(不包含0号控制端点)
            if(interface->desc.bNumEndpoints != 1)
                    return -ENODEV;
    
            //获取端点0描述符
            endpoint = &interface->endpoint[0].desc;
    
            //根据HID规范,鼠标唯一的端点应为中断端点
            if(!usb_endpoint_is_int_in(endpoint))
                    return -ENODEV;
    
            //生成中断管道
            pipe = usb_rcvintpipe(dev,endpoint->bEndpointAddress);
    
            //返回该端点能够传输的最大包长度,鼠标的返回最大数据包为4个字节
            maxp = usb_maxpacket(dev,pipe,usb_pipeout(pipe));
    
            //创建input设备
            mouse = kzalloc(sizeof(struct usb_mouse),GFP_KERNEL);
            input_dev = input_allocate_device();
            if(!mouse || !input_dev)
                    goto fail1;
    
            //申请内存空间用于数据传输,data为指向该空间地址
            mouse->data = usb_alloc_coherent(dev,8,GFP_ATOMIC,&mouse->data_dma);
            if(!mouse->data)
                    goto fail1;
    
            //分配URB
            mouse->irq = usb_alloc_urb(0,GFP_KERNEL);
            if(!mouse->irq)
                    goto fail2;
    		
     mouse->usbdev = dev;
            mouse->dev = input_dev;
    
            if(dev->manufacturer)
                    strlcpy(mouse->name,dev->manufacturer,sizeof(mouse->name));
    
            if(dev->product)
            {
                    if(dev->manufacturer)
                            strlcat(mouse->name," ",sizeof(mouse->name));
    
                    strlcat(mouse->name,dev->product,sizeof(mouse->name));
            }
    
            if(!strlen(mouse->name))
                    snprintf(mouse->name,sizeof(mouse->name),"USB HIDBP Mouse %04x:%04x",le16_to_cpu(dev->descriptor.idVendor),le16_to_cpu(dev->descriptor.idProduct));
    
            //usb_make_path 用来获取 USB 设备在 Sysfs 中的路径
            usb_make_path(dev,mouse->phys,sizeof(mouse->phys));
    
            strlcat(mouse->phys,"/input0",sizeof(mouse->phys));
    
            //字符设备初始化
            input_dev->name = mouse->name;
            input_dev->phys = mouse->phys;
            usb_to_input_id(dev,&input_dev->id);
            input_dev->dev.parent = &intf->dev;
    
            input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
            input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
    		input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
            input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
            input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
    
            input_set_drvdata(input_dev,mouse);
    
            input_dev->open = usb_mouse_open;
            input_dev->close = usb_mouse_close;
    
            //初始化中断URB
            usb_fill_int_urb(mouse->irq,dev,pipe,mouse->data,(maxp > 8 ? 8 : maxp),usb_mouse_irq,mouse,endpoint->bInterval);
    
            mouse->irq->transfer_dma = mouse->data_dma;
            mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
    
            error = input_register_device(mouse->dev);
            if(error)
                    goto fail3;
    
            //将mouse指针保存在intf的dev成员中
            usb_set_intfdata(intf,mouse);
            return 0;
    
    fail3:
            usb_free_urb(mouse->irq);
    fail2:
            usb_free_coherent(dev,8,mouse->data,mouse->data_dma);
    fail1:
            input_free_device(input_dev);
            kfree(mouse);
            return error;
    }
    
    	static void usb_mouse_disconnect(struct usb_interface *intf)
    {
            struct usb_mouse *mouse = usb_get_intfdata(intf);
    
            usb_set_intfdata(intf,NULL);
            if(mouse)
            {
                    usb_kill_urb(mouse->irq);
                    input_unregister_device(mouse->dev);
                    usb_free_urb(mouse->irq);
                    usb_free_coherent(interface_to_usbdev(intf),8,mouse->data,mouse->data_dma);
                    kfree(mouse);
            }
    }
    
    static struct usb_device_id usb_mouse_id_table [] =
    {
            { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID,USB_INTERFACE_SUBCLASS_BOOT,USB_INTERFACE_PROTOCOL_MOUSE) },
            { }  //Terminating entry
    };
    
    MODULE_DEVICE_TABLE(usb,usb_mouse_id_table);
    
    static struct usb_driver usb_mouse_driver =
    {
            .name = "usbmouse",  //驱动名
            .probe = usb_mouse_probe,  //捕获函数
            .disconnect = usb_mouse_disconnect,  //卸载函数
            .id_table = usb_mouse_id_table,  //设备列表
    };
                                         
    static int __init usb_mouse_init(void)
    {
            //注册鼠标驱动程序
            int retval = usb_register(&usb_mouse_driver);
            if(retval == 0)
                    //printk(KERN_INFO KBUILD_MODNAME ":" DRIVER_VERSION ":" DRIVER_DESC "\n");
                    printk("register success\n");
            return retval;
    }
    
    static void __exit usb_mouse_exit(void)
    {
            usb_deregister(&usb_mouse_driver);
    }
    
    module_init(usb_mouse_init);
    module_exit(usb_mouse_exit);
    
    
    展开全文
  • CH341 USB驱动程序

    2018-07-22 20:30:25
    CH341 USB驱动程序
  • USBasp驱动_avr_fighter_USB驱动程序 使用方法:桌面=》我的电脑=》右键=》硬件=>设备管理器=》人体学输入设备=》USB人体学输入设备(注意:要多所有的都是一下,才可以更新)=》右键=》更新驱动=》选择《从列表...
  • 顺舟科技USB驱动程序zip,顺舟科技USB驱动程序

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,867
精华内容 4,346
关键字:

usb驱动程序