0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

USB鼠标驱动程序上机实验

麦辣鸡腿堡 来源:嵌入式Linux系统开发 作者:韦东山老师驱动大 2023-07-17 17:35 次阅读

上机实验

韦老师的 USB 鼠标驱动,只实现了检测鼠标左键、右键、中键的【按下弹起】功能,没有实现复杂功能,可以做 demo 学习参考。使用完整 USB 鼠标功能请使用 Linux 内核自带的 driver,如文章开头目录。

/* 参考: drivershidusbhidusbmouse.c */
#include < linux/kernel.h >
#include < linux/slab.h >
#include < linux/module.h >
#include < linux/init.h >
#include < linux/usb.h >
#include < linux/input.h >
#include < linux/hid.h >

struct usb_mouse_as_key_desc {
    struct usb_device *dev;
    struct usb_interface *intf;
    const struct usb_device_id *id;
    int pipe, maxp;
    int bInterval;
    void *data_buffer;
    dma_addr_t data_dma;
    struct urb *urb;
};

/* 1. 构造 usb_driver 
 * 1.1 id_table : 能支持哪些设备
 * 1.2 probe : 记录某些信息, 分配/设置/注册 input_dev, 也许"分配/填充/提交 URB"
 */

static struct usb_device_id usb_mouse_as_key_id_table [] = {
 { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,
  USB_INTERFACE_PROTOCOL_MOUSE), .driver_info = (kernel_ulong_t)"it is a mouse", },
 { } /* Terminating entry */
};

static void usb_mouse_as_key_irq(struct urb *urb)
{
 struct input_dev *dev = urb- >context;
 struct usb_mouse_as_key_desc *desc = input_get_drvdata(dev);
 signed char *data = desc- >data_buffer;
 int status;

 //printk("%s %s %d, urb- >status = %dn", __FILE__, __FUNCTION__, __LINE__, urb- >status);
 switch (urb- >status) {
 case 0:   /* success */
  break;
 case -ECONNRESET: /* unlink */
 case -ENOENT:
 case -ESHUTDOWN:
  return;
 /* -EPIPE:  should clear the halt */
 default:  /* error */
  goto resubmit;
 }

 //printk("data[1] = 0x%xn", data[1]);
 input_report_key(dev, KEY_L, data[1] & 0x01);
 input_report_key(dev, KEY_S, data[1] & 0x02);
 input_report_key(dev, KEY_ENTER, data[1] & 0x04);

 input_sync(dev);
resubmit:
 status = usb_submit_urb (urb, GFP_ATOMIC);
  //printk("%s %s %d, status = %dn", __FILE__, __FUNCTION__, __LINE__, status);
}

static int usb_mouse_as_key_open(struct input_dev *dev)
{
    struct urb *urb;
    struct usb_mouse_as_key_desc *desc = input_get_drvdata(dev);
    int err;
    
    printk("%s %s %dn", __FILE__, __FUNCTION__, __LINE__);
    /* 分配/填充/提交 URB */
    urb = usb_alloc_urb(0, GFP_KERNEL);

    desc- >urb = urb;

    usb_fill_int_urb(urb,
         desc- >dev,
         desc- >pipe,
         desc- >data_buffer,
         (desc- >maxp > 8 ? 8 : desc- >maxp),
         usb_mouse_as_key_irq,
         dev,
         desc- >bInterval);
    
    urb- >transfer_dma = desc- >data_dma;
    urb- >transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

    err = usb_submit_urb (urb, GFP_ATOMIC);
    
    printk("%s %s %d, err = %dn", __FILE__, __FUNCTION__, __LINE__, err);
    return err;
}

static void usb_mouse_as_key_close(struct input_dev *dev)
{
    struct usb_mouse_as_key_desc *desc = input_get_drvdata(dev);
    
    /* 取消/释放 URB */
    usb_kill_urb(desc- >urb);
    usb_free_urb(desc- >urb);
}

static int usb_mouse_as_key_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
 struct usb_device *dev = interface_to_usbdev(intf);
 struct input_dev *input_dev;
 struct usb_mouse_as_key_desc *desc;
 int error;
 struct usb_host_interface *interface;
 struct usb_endpoint_descriptor *endpoint;
 int pipe, maxp;

 printk("%s %s %dn", __FILE__, __FUNCTION__, __LINE__);
 /* 1. 记录设备信息:  intf */
 interface = intf- >cur_altsetting;

 if (interface- >desc.bNumEndpoints != 1)
  return -ENODEV;

 endpoint = &interface- >endpoint[0].desc;
 if (!usb_endpoint_is_int_in(endpoint))
  return -ENODEV;

 pipe = usb_rcvintpipe(dev, endpoint- >bEndpointAddress);
 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

 desc = kmalloc(sizeof(struct usb_mouse_as_key_desc), GFP_KERNEL);
 desc- >dev  = dev;
 desc- >intf = intf;
 desc- >id   = id;
 desc- >pipe = pipe;
 desc- >maxp = maxp;
 desc- >bInterval = endpoint- >bInterval;
 desc- >data_buffer = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &desc- >data_dma);
 printk("%s %s %d, desc- >data_buffer = 0x%xn", __FILE__, __FUNCTION__, __LINE__, desc- >data_buffer);

 /* 2. 分配/设置/注册input_dev 
  * 2.1 能产生哪类事件
  * 2.2 能产生这类事件里哪些些事件: L/S/ENTER
  * 2.3 设置函数, 比如open
  * 2.4 在open函数里: 分配/填充/提交 URB
  * 2.5 URB的回调函数: 解析数据, 上报input_event
 */

 input_dev = devm_input_allocate_device(&intf- >dev);
    
 input_set_drvdata(input_dev, desc);

 /* set 1: which type event ? */ 
 __set_bit(EV_KEY, input_dev- >evbit);

 /* set 2: which event ? */ 
 __set_bit(KEY_L, input_dev- >keybit);
 __set_bit(KEY_S, input_dev- >keybit);
 __set_bit(KEY_ENTER, input_dev- >keybit);

 /* set 3: open */
 input_dev- >open  = usb_mouse_as_key_open;
 input_dev- >close = usb_mouse_as_key_close;

 error = input_register_device(input_dev);

 usb_set_intfdata(intf, input_dev);
    
 return 0;
}

static void usb_mouse_as_key_disconnect(struct usb_interface *intf)
{
 struct input_dev *input_dev = usb_get_intfdata (intf);
    struct usb_mouse_as_key_desc *desc = input_get_drvdata(input_dev);

    usb_free_coherent(desc- >dev, desc- >maxp, desc- >data_buffer, desc- >data_dma);
    kfree(desc);
        
    input_unregister_device(input_dev);
    usb_set_intfdata(intf, NULL);
}

static struct usb_driver usb_mouse_as_key_driver = {
 .name  = "usbmouse_as_key",
 .probe  = usb_mouse_as_key_probe,
 .disconnect = usb_mouse_as_key_disconnect,
 .id_table = usb_mouse_as_key_id_table,
};

/* 入口函数  / 出口函数 */
// module_usb_driver(usb_mouse_as_key_driver);
static int __init usb_mouse_as_key__init(void)
{
    printk("%s %s %dn", __FILE__, __FUNCTION__, __LINE__);
 return usb_register(&usb_mouse_as_key_driver);
}

static void __exit usb_mouse_as_key__init_exit(void)
{ 
 usb_deregister(&usb_mouse_as_key_driver);
}

module_init(usb_mouse_as_key__init);
module_exit(usb_mouse_as_key__init_exit);

MODULE_LICENSE("GPL");

测试:

# 把 USB 鼠标查到开发板上
# 先看看原来有哪些设备节点
ls /dev/input/event*

# 安装驱动程序
insmod usbmouse_as_key.ko

# 再看看新得到了哪个设备节点
ls /dev/input/event*

# 执行命令, 假设 event4 是新节点
hexdump /dev/input/event4

# 点击鼠标按键即可观察输出信息

# 第 2 种测试方法: 执行以下命令,按鼠标左键、右键,再按中键就有输出"ls"
cat /dev/tty0

# 第 3 种测试方法: 执行以下命令(注意"< "号前后没有空格),就可以使用鼠标按键在控制台输入字符
exec 0< /dev/tty0
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • usb
    usb
    +关注

    关注

    60

    文章

    7888

    浏览量

    263922
  • 驱动
    +关注

    关注

    12

    文章

    1824

    浏览量

    85168
  • 鼠标
    +关注

    关注

    6

    文章

    588

    浏览量

    39721
收藏 人收藏

    评论

    相关推荐

    Linux USB鼠标驱动程序详解

    驱动程序(u*** driver)是如何添加到驱动链表上去的?在每个 USB 驱动程序的被注册时,USB
    发表于 10-23 12:40

    usb网卡驱动程序下载(万能全集)

    usb网卡驱动程序:ADM8511 USB网卡驱动程序ADM8515 USB网卡驱动程序AS26
    发表于 09-28 15:40 4202次下载
    <b class='flag-5'>usb</b>网卡<b class='flag-5'>驱动程序</b>下载(万能全集)

    天语手机usb驱动程序

    天语手机usb驱动程序:天语手机usb驱动程序下载
    发表于 04-30 12:36 792次下载

    EZ USB 通用驱动程序说明

    EZ_USB 通用驱动程序(本文章中称为GPD或者是EZ_USB GPD)是用来和基于EZ_USB外设接口的通用设备驱动程序
    发表于 11-06 11:26 52次下载

    串口驱动程序实验

    串口驱动程序实验 一.实验目的本示例程序展示了如何在Small RTOS51
    发表于 09-26 17:47 2094次阅读
    串口<b class='flag-5'>驱动程序</b><b class='flag-5'>实验</b>

    PDIUSBD12 USB 驱动程序演示实验

    PDIUSBD12 USB 驱动程序演示实验 一.实验目的PDIUSBD12(简称D12) USB 芯片符合
    发表于 09-26 17:52 3464次阅读

    Windows USB 驱动程序接口及传输方式

    Windows USB 驱动程序接口系统中的USB驱动程序完成许多的工作。实际上对于一些HID的USB设 备,象键盘,
    发表于 05-06 16:04 2296次阅读

    USB接口驱动程序开发

    介绍USB的优点和发展情况,基于DDK的USB设备驱动程序结构,并结合开发的ARM 板驱动程序对关键程序进行介绍。
    发表于 03-19 15:21 121次下载
    <b class='flag-5'>USB</b>接口<b class='flag-5'>驱动程序</b>开发

    HC6800的USB驱动程序

    HC6800的USB驱动程序HC6800的USB驱动程序HC6800的USB驱动程序HC6800
    发表于 12-28 15:28 0次下载

    usb驱动程序

    CH340G的USB驱动程序,win7运行完全没有问题。
    发表于 05-13 10:17 69次下载

    CDM20600驱动程序,USB驱动程序和并口驱动应用程序(免费下载)

    本文档的主要内容是CDM20600驱动程序,USB驱动程序和并口驱动应用程序(免费下载)详细资料概述
    发表于 06-06 10:00 57次下载
    CDM20600<b class='flag-5'>驱动程序</b>,<b class='flag-5'>USB</b><b class='flag-5'>驱动程序</b>和并口<b class='flag-5'>驱动</b>应用<b class='flag-5'>程序</b>(免费下载)

    Linux USB鼠标驱动程序详解

    驱动程序usb driver)是如何添加到驱动链表上去的?在每个 USB 驱动程序的被注册时,USB
    发表于 04-02 14:35 750次阅读

    SDP USB驱动程序安装程序

    SDP USB驱动程序安装程序
    发表于 03-23 10:07 14次下载
    SDP <b class='flag-5'>USB</b><b class='flag-5'>驱动程序</b>安装<b class='flag-5'>程序</b>

    手指在应用程序上机器人

    电子发烧友网站提供《手指在应用程序上机器人.zip》资料免费下载
    发表于 11-16 10:04 0次下载
    手指在应用<b class='flag-5'>程序上机</b>器人

    USB驱动程序

    USB驱动程序
    发表于 08-17 11:47 54次下载