linux设备驱动程序的编写--将usb鼠标当做按键

来源:互联网 发布:邮箱群发软件 编辑:程序博客网 时间:2024/06/03 13:43
USB设备驱动程序的编写:
1分配一个struct usb_driver;

    static struct usb_driver usbmouse_as_key_driver = {
        .name        = "usbmouse_as_key",
        .probe        = usbmouse_as_key_probe,
        .disconnect    = usbmouse_as_key_disconnect,
        .id_table    = usbmouse_as_key_id_table,
    };

1.1分配成员id_table
    static struct usb_device_id usbmouse_as_key_id_table [] = {
    {    USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
        USB_INTERFACE_PROTOCOL_MOUSE) },
        { }    /* Terminating entry */
    };
    usb_device_id结构体包含了设备驱动程序支持的设备。

2:注册:
    入口函数里面注册:
    usb_register(&usbmouse_as_key_driver);
    在出口函数里面取消注册:
    usb_deregister(&usbmouse_as_key_driver);    

3具体函数的设置和实现:

    几个usb设备概念:
    端口:USB 通讯的最基本形式是通过某些称为 端点 的. 一个 USB 端点只能在一个方
         向承载数据, 或者从主机到设备(称为输出端点)或者从设备到主机(称为输入端
          点). 端点可看作一个单向的管道.
         struct usb_endpoint_descriptor *endpoint;
    接口:
         USB 端点被绑在接口中. USB 接口只处理一类 USB 逻辑连接, 例如一个鼠标,
         一个键盘, 或者一个音频流. 一些 USB 设备有多个接口, 例如一个 USB 扬声
        器可能有 2 个接口: 一个 USB 键盘给按钮和一个 USB 音频流。
    USBurb:
        linux内核中的USB代码通过urb(usb请求块)和所有的usb设备通信。这个块使用struct urb来描述。


       static int usbmouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
    {

        static dma_addr_t *buf_phys;

        struct usb_host_interface *interface;   //定义接口变量
        struct usb_endpoint_descriptor *endpoint; //定义端点变量
    
        struct usb_device *dev = interface_to_usbdev(intf);//根据接口信息分配一个usb_dev结构体。
        interface = intf->cur_altsetting;            //
        endpoint = &interface->endpoint[0].desc;//接口和端口的信息填充
        
        /*创建urb结构体*/
        urb_uk = usb_alloc_urb(0, GFP_KERNEL);
        
        /*创建一个DMA缓冲区来以最高效的方式发送数据*/

        buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &buf_phys);
        
        /*把指定的USB设备端点号设置成一个控制IN型端口*/
        pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
        
        /*端口一次可以处理的最大字节数 /
        len = endpoint->wMaxPacketSize;

        /*初始化即将被发送到usb设备的中断端点的urb*/
        usb_fill_int_urb(urb_uk, dev, pipe, buf,len,usb_mouse_as_key_irq, NULL, endpoint->bInterval);
        urb_uk->transfer_dma = buf_phys; //以DMA方式传输数据到USB设备的缓冲区
        urb_uk->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

        /*urb被创建和初始化之后, 提交到usb核心以发送到usb设备*/
        usb_submit_urb(urb_uk,GFP_KERNEL);

        /*urb被成功的传输到usb设备之后,urb里面的回调函数(usb_mouse_as_key_irq)将被usb核心调用*/
    



    
    }

    static void usb_mouse_as_key_irq(struct urb *urb)
    {
        /*将usb鼠标用作按键使用, 用到输入子系统*/
        
        int pipe;
        /*1:分配一个input_dev结构体*/
        input_mk = input_allocate_device();

        /*2:设置*/

        set_bit(EV_KEY,input_mk->evbit);
        set_bit(EV_REP,input_mk->evbit);

        set_bit(KEY_L,input_mk->keybit);
        set_bit(KEY_S,input_mk->keybit);
        set_bit(KEY_ENTER,input_mk->keybit);
        
        
        /*3:注册*/

        input_register_device(input_mk);
        
        /* USB鼠标数据含义
         * data[0]: bit0-左键, 1-按下, 0-松开
         *          bit1-右键, 1-按下, 0-松开
         *          bit2-中键, 1-按下, 0-松开
         *
             */
        static unsigned char pre_val;

        if ((pre_val & (1<<0)) != (buf[0] & (1 << 0)))
        {
            input_event(input_mk, EV_KEY, KEY_L,(buf[0] & (1 << 0) ? 1 : 0));
            input_sync(input_mk);
        }
        else if ((pre_val & (1<<1)) != (buf[0] & (1 << 1)))
        {
            input_event(input_mk, EV_KEY, KEY_S,(buf[0] & (1 << 1) ? 1 : 0));
            input_sync(input_mk);
        }
        else if ((pre_val & (1<<2)) != (buf[0] & (1 << 2)))
        {
            input_event(input_mk, EV_KEY, KEY_ENTER,(buf[0] & (1 << 2) ? 1 : 0));
            input_sync(input_mk);
        }

        pre_val = buf[0];

        /*再次提交*/
        usb_submit_urb(urb_uk,GFP_KERNEL);
    }
       static void usbmouse_as_key_disconnect(struct usb_interface *intf)
    {    
        struct usb_device *dev = interface_to_usbdev(intf);
        
        usb_free_urb(buf);
        usb_kill_urb(buf);
        usb_buffer_free(dev,len, buf, buf_phys);

        
        input_unregister_device(input_mk);
        input_free_device(input_mk);
        
    }


原创粉丝点击