首页 > 代码库 > 学习Linux下s3c2440的USB鼠标驱动笔记

学习Linux下s3c2440的USB鼠标驱动笔记

USB驱动学习笔记:
  2 1、ARM-Linux下USB驱动程序开发
  3 1.1.1、linux下USB配置:
  4 *********(MassStorage:存储设备)************************************
  5         -> Device Drivers                                                                
  6           -> SCSI device support(通用设备) 
  7           -> SCSI disk support  (磁盘支持)           
  8           -> SCSI device support(设备支持) 
  9         
 10         -> Device Drivers                                                            
 11           -> USB support               (USB设备)
 12           -> USB device filesystem   (USB设备文件系统)
 13           -> OHCI HCD support        (主要是非PC上的USB芯片)
 14           -> USB Mass Storage support(USB大容量设备)        
 15           -> USB Monitor               (USB 主设备)  
 16           
 17         -> File systems                                                                   
 18            -> DOS/FAT/NT Filesystems   
 19               -> MSDOS fs support                                                    
 20               -> VFAT (Windows-95) fs support
 21               
 22         -> Partition Types           (分区类型)                      
 23            -> PC BIOS (MSDOS partition tables) support  
 24            
 25         -> Native Language Suppor    (本地语言设置)
 26            -> Simplified Chinese charset (CP936, GB2312) 
 27            -> NLS UTF-8                     
 28            
 29        make uImage  (生成uImage)
 30        测试 mount /dev/sda1 /mnt/  
 31           
 32 *********(HID:人机接口(鼠标、键盘))********************************
 33         -> Device Drivers                                                               
 34             HID Devices  --->   
 35                  -> USB Human Interface Device (full HID) support      
 36             USB support  --->              
 37                  -> Support for Host-side USB    
 38          make uImage  (生成uImage)
 39          测试 cat /dev/mouse1
 40     
 41 *********(RNDIS:网卡)********************************
 42         
 43                -> Device Drivers                                                                                                                                                                  x  
 44                      -> USB support                                                                                                                                                                   x  
 45                      -> USB Gadget Support  
 46                         <M> Support for USB Gadgets    
 47                         <M>   Ethernet Gadget (with CDC Et hernet support)                                                                            x x  
 48                          [*]     RNDIS support (EXPERIMENTAL) (NEW)                                         
 49             编译内核模块
 50             
 51             cp drivers/usb/gadget/_ether.ko  /work/nfs_root/first_fs/
 52             cp /arch/arm/boot/uImage /work/nfs_root/new_uImage
 53         
 54 *********(CDC-ACM:USB虚拟串口)********************************
 55             (未能识别USB driver)可能是没有配置USB设备
 56 
 57             
 58 
 59             
 60 1.2.1、驱动程序编写
 61         struct usb_driver {
 62             const char *name;    /*USB驱动名字*/
 63             int (*probe) (struct usb_interface *intf,const struct usb_device_id *id);/*USB core发现该驱动程序能够处理USB接口时,调用*/
 64             void (*disconnect) (struct usb_interface *intf);/*USB移除的时候调用*/
 65             const struct usb_device_id *id_table;            /*该驱动程序支持哪些设备 idVendor(制造商ID) idProduct(产品id)*/
 66         };
 67 1.2.2、linux提供宏来定义 一种 设备 :
 68         USB_DEVICE(vend,prod)
 69         vend:USB Vendor  ID   制造商ID
 70         prod:USB Product ID   设备ID
 71     
 72 1.2.3、linux提供宏来定义 一类 设备 :
 73         USB_INTERFACE_INFO(cl,sc,pr)
 74         cl:类     blnterfaceClass Value
 75         sc:子类    blnterfaceSubClass value 
 76         pr:协议    blnterfaceProtocil Value
 77         
 78 1.2.4、USB注册:传入一个参数usb_driver
 79         static inline int usb_register(struct usb_driver *driver)
 80     
 81 1.2.5、usb_device结构
 82     int            devnum;                                /* Address on USB bus */
 83     char        devpath [16];                        /* Use in messages: /port/port/... */
 84     enum usb_device_state    state;                    /* configured, not attached, etc */
 85     enum usb_device_speed    speed;                    /* high/full/low (or error) */
 86     struct usb_device_descriptor descriptor;        /* Descriptor 设备描述符号*/
 87     struct usb_host_config         *config;            /* All of the configs */
 88         struct usb_config_descriptor    desc;        /*usb配置描述符*/
 89         struct usb_interface *interface[USB_MAXINTERFACES];     
 90         ruct usb_host_interface *cur_altsetting;    /* the currently
 91             /*USB 接口描述符 一个[配置]包含一个或者多个接口,一个接口包含一个或者多个[设置] */
 92             struct usb_interface_descriptor    desc; 
 93             struct usb_host_endpoint *endpoint;     /*USB端点*/
 94                 struct usb_endpoint_descriptor    desc;/*USB 端点描述符 */
 95     
 96 1.3.1、URB(usb request block)请求块 ,承载USB之间的数据传输 
 97 
 98     ①URB处理流程:
 99         1、USB设备驱动程序创建并初始化一个访问特点USB设备指定的端点的URB,并提交给USB Core
100         2、USB core提交该URB到USB主控制驱动程序
101         3、USB主控制器驱动程序根据该URB的描述信息,来访问USB设备
102         4、当访问设备结束后,USB主控制器驱动程序通知USB设备驱动(device)程序
103     
104     ②创建urb的函数为:
105         struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
106         参数1:iso_packets:urb所含的等时数据包个数
107         参数2:mem_flags:内存分配标示
108     
109     ③初始化urb函数为:interrupt
110         static inline void usb_fill_int_urb (
111                      struct urb *urb,            //要初始化urb指针
112                      struct usb_device *dev,    //usb_device设备
113                      unsigned int pipe,            //要访问的端点所对应的管道,使用usb_sndintpipe()/usb_rcvintpipe()
114                      void *transfer_buffer,        //要传输数据的缓冲区
115                      int buffer_length,               //要传输数据的长度
116                  usb_complete_t complete_fn,    //当完成urb所请求的操作时候调用的回调函数
117                      void *context,                //通常取值为DEV
118                      int interval                //URB被调度的时间间隔
119                      );
120     问:何为管道?
121     答:管道:驱动程序的数据缓冲区与一个端点的连接,代表一个在两者之间要移动数据的能力。
122     
123     批量urb:使用usb_fill_bulk_urb()
124     控制urb: 使用usb_control_urb()
125     等时urb没有像中断、控制、批量传输那样有URB初始化函数,我们只有手动初始化urb.
126     
127     ④提交URB
128         在完成urb的创建和初始化后,URB就可以通过usb_smbmit_urb函数来提交给usb core 
129         int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
130         urb:指向URB的指针
131         mem_flags:内存分配标示,用于告知USB core如何分配内存换成区。
132         
133         
134     ⑤URB处理 以下三种情况被认为URB处理完成,调用complete_fn函数
135         1、URB成功发送给设备,并且设备返回正确,URB->status = 0
136         2、如果接收和发送发生错误时候 urb->status = error
137         3、urb被取消,就发生在驱动程序通过,usb_unlink_urb() / usb_kill_urb()
138 
鼠标驱动程序:

技术分享
  1 #include <linux/kernel.h>
  2 #include <linux/errno.h>
  3 #include <linux/init.h>
  4 #include <linux/slab.h>
  5 #include <linux/module.h>
  6 #include <linux/kref.h>
  7 #include <asm/uaccess.h>
  8 #include <linux/usb.h>
  9 #include <linux/mutex.h>
 10 #include <linux/hid.h>
 11 #include <linux/input.h>
 12 
 13 
 14 /*创建输入设备*/
 15 static struct input_dev *uk_dev;
 16 static int len;
 17 static char *usb_buf;
 18 static dma_addr_t usb_data_dma;
 19 static struct urb *uk_urb;
 20 
 21 
 22 
 23 
 24 //usb支持的设备列表
 25 static struct usb_device_id usbmouse_key_table [] = {
 26     { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
 27         USB_INTERFACE_PROTOCOL_MOUSE) },
 28     //{USB_DEVICE(0x1234,0x5678)},
 29     { }    /* Terminating entry */
 30 };
 31 
 32 static void usb_mouse_irq(struct urb *urb)
 33 {
 34     static unsigned char pre_val;
 35 #if 0    
 36     int i;
 37     char b[100];
 38     static int cnt = 0;
 39     printk("data cnt %d: ", ++cnt);
 40     for (i = 0; i < len; i++)
 41     {
 42         printk("%02x   ", usb_buf[i]);
 43     }
 44     printk("\n");
 45 
 46 
 47 
 48     /* USB鼠标数据含义
 49      * data[1]: bit0-左键, 1-按下, 0-松开
 50      *          bit1-右键, 1-按下, 0-松开
 51      *          bit2-中键, 1-按下, 0-松开 
 52      *
 53      */
 54     // if ((pre_val & (1<<0)) != (usb_buf[1] & (1<<0)))
 55     // {
 56     //     /* 左键发生了变化 */
 57     //     input_event(uk_dev, EV_KEY, KEY_L, (usb_buf[1] & (1<<0)) ? 1 : 0);
 58     //     input_sync(uk_dev);
 59     // }
 60 
 61     // if ((pre_val & (1<<1)) != (usb_buf[1] & (1<<1)))
 62     // {
 63     //     /* 右键发生了变化 */
 64     //     input_event(uk_dev, EV_KEY, KEY_S, (usb_buf[1] & (1<<1)) ? 1 : 0);
 65     //     input_sync(uk_dev);
 66     // }
 67 
 68     // if ((pre_val & (1<<2)) != (usb_buf[1] & (1<<2)))
 69     // {
 70     //     /* 中键发生了变化 */
 71     //     input_event(uk_dev, EV_KEY, KEY_ENTER, (usb_buf[1] & (1<<2)) ? 1 : 0);
 72     //     input_sync(uk_dev);
 73     // }    
 74     
 75     // pre_val = usb_buf[1];
 76     /* 重新提交urb */
 77     usb_submit_urb(uk_urb, GFP_KERNEL);
 78 
 79 #else
 80 
 81     switch (urb->status) {
 82     case 0:            /* success */
 83         break;
 84     case -ECONNRESET:    /* unlink */
 85     case -ENOENT:
 86     case -ESHUTDOWN:
 87         return;
 88     /* -EPIPE:  should clear the halt */
 89     default:        /* error */
 90         goto resubmit;
 91     }
 92 
 93     input_report_key(uk_dev, BTN_LEFT,   usb_buf[1] & 0x01);
 94     input_report_key(uk_dev, BTN_RIGHT,  usb_buf[1] & 0x02);
 95     input_report_key(uk_dev, BTN_MIDDLE, usb_buf[1] & 0x04);
 96     input_report_key(uk_dev, BTN_SIDE,   usb_buf[1] & 0x08);
 97     input_report_key(uk_dev, BTN_EXTRA,  usb_buf[1] & 0x10);
 98 
 99     input_report_rel(uk_dev, REL_X,     usb_buf[3]);
100     input_report_rel(uk_dev, REL_Y,     usb_buf[4]);
101     input_report_rel(uk_dev, REL_WHEEL, usb_buf[5]);
102 
103     input_sync(uk_dev);
104 resubmit:
105      usb_submit_urb (urb, GFP_ATOMIC);
106 #endif
107 
108 
109 
110 
111 }
112 
113 static int usbmouse_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
114 {
115     struct usb_device *dev = interface_to_usbdev(intf);
116     struct usb_host_interface *interface;
117     struct usb_endpoint_descriptor *endpoint;
118     int pipe;
119     /*获取当前usb接口的设置*/
120     interface = intf->cur_altsetting;
121     endpoint  = &interface->endpoint[0].desc;
122 
123     /* a. 分配一个input_dev */
124     uk_dev = input_allocate_device();
125     /* b. 设置 */
126     /* b.1 能产生哪类事件 */
127      set_bit(EV_KEY, uk_dev->evbit);
128      set_bit(EV_REL, uk_dev->evbit);
129     
130     // /* b.2 能产生这类操作里的哪些事件: L,S,ENTER,LEFTSHIT */
131     // set_bit(BTN_LEFT, uk_dev->keybit);
132     // set_bit(BTN_RIGHT, uk_dev->keybit);
133     // set_bit(BTN_MIDDLE, uk_dev->keybit); 
134 
135     // set_bit(REL_X,uk_dev->keybit);
136     // set_bit(REL_Y,uk_dev->keybit);
137     // set_bit(REL_WHEEL,uk_dev->keybit);
138     
139      uk_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
140      uk_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
141      uk_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
142      uk_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
143      uk_dev->relbit[0] |= BIT(REL_WHEEL);
144 
145     /* c. 注册 */
146     input_register_device(uk_dev);
147     
148     /* d. 硬件相关操作 */
149     /* 数据传输3要素: 源,目的,长度 */
150     /* 源: USB设备的某个端点 */
151     pipe = usb_rcvintpipe(dev,endpoint->bEndpointAddress);
152     /* 长度: */
153     len =  endpoint->wMaxPacketSize;
154     /* 目的: */
155     usb_buf = usb_buffer_alloc(dev,len,GFP_ATOMIC,&usb_data_dma);
156     /* 使用"3要素" */
157     /* 分配usb request block */
158     uk_urb = usb_alloc_urb(0, GFP_KERNEL);
159 
160     /* 使用"3要素设置urb" */
161     usb_fill_int_urb(uk_urb, dev, pipe,usb_buf,len,usb_mouse_irq, NULL, endpoint->bInterval);
162     uk_urb->transfer_dma = usb_data_dma;
163     uk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
164 
165     /* 使用URB */
166     usb_submit_urb(uk_urb, GFP_KERNEL);
167 
168 
169     printk("found usbmouse!\n");
170 
171     printk("bcdUSB = %x\n", dev->descriptor.bcdUSB);
172     printk("VID    = 0x%x\n", dev->descriptor.idVendor);
173     printk("PID    = 0x%x\n", dev->descriptor.idProduct);
174 
175     return 0;
176 }
177 
178 static void usbmouse_key_disconnect(struct usb_interface *interface)
179 {
180     struct usb_device *dev = interface_to_usbdev(interface);
181 
182     printk("usbmouse_key_disconnect\n");
183     input_unregister_device(uk_dev);
184     input_free_device(uk_dev);    
185     usb_buffer_free(dev,len,usb_buf,usb_data_dma);
186     usb_kill_urb(uk_urb);
187     usb_free_urb(uk_urb);
188 
189 }
190 
191 MODULE_DEVICE_TABLE (usb, usbmouse_key_table);
192 
193  /*usbmouse_key_probe  usbmouse_key_disconnect  函数指针
194   *当设备与在id_table 中变量信息匹配时,此函数被调用
195   */
196 static struct usb_driver usbmouse_key_driver = {
197     .name =        "usbmouse_key",
198     .probe =    usbmouse_key_probe,             
199     .disconnect =    usbmouse_key_disconnect,
200     .id_table =    usbmouse_key_table,
201 
202 };
203 
204 /*
205  *USB骨架  最基本的usb驱动模板
206  */
207 static int __init usb_usbmouse_key_init(void)
208 {
209     int result;
210 
211     printk("usb_usbmouse_key_init\n");
212 
213     /* register this driver with the USB subsystem */
214     result = usb_register(&usbmouse_key_driver);
215     if (result)
216         err("usb_register failed. Error number %d", result);
217 
218     return result;
219 }
220 
221 static void __exit usb_usbmouse_key_exit(void)
222 {
223     printk("usb_usbmouse_key_exit\n");
224     /* deregister this driver with the USB subsystem */
225     usb_deregister(&usbmouse_key_driver);
226 }
227 
228 module_init(usb_usbmouse_key_init);
229 module_exit(usb_usbmouse_key_exit);
230 MODULE_LICENSE("GPL");
View Code

 





学习Linux下s3c2440的USB鼠标驱动笔记