IMX257 USB鼠标驱动程序编写

发布时间:2024-08-14  

SB驱动程序包括为USB总线驱动程序以及USB设备驱动程序.

USB总线驱动程序的功能是:

    1.识别

    2.找到匹配的设备驱动程序

    3.提供USB读写函数(不知道数据的含义)

USB设备驱动程序功能是: 分析USB的数据,上报相应的事件

 

今天,我们来实现一个USB鼠标的设备驱动程序,让鼠标的左键模拟为键盘的L键,鼠标的右键模拟为键盘的S键,鼠标的中键模拟为键盘的ENTER键,接下来我们先来实现一个简单程序,让操作系统找到USB鼠标.

 

一.简单的USB鼠标设备驱动程序

1.分配/注册一个USB结构体usb_driver

如图所示,定义一个usb_driver结构体,里面分别有三个函数:

usb_mouse_key_probe usb鼠标探测函数

usb_mouse_key_disconnect  usb鼠标移出函数

usb_mouse_key_id_table    里面包含了usb鼠标的协议等信息

接下来分别实现上面的三个函数:

如图所示:我们现在先不做什么复杂的操作,知识简单的让它打印信息.

 

2.注册一个USB结构体usb_driver

3.调试:

make menuconfig去除自带的鼠标驱动程序:

1. make menuconfig 去掉原来鼠标的驱动程序

--> Device Drivers

--> HID Device

<>USB Human Interface Device(full HID) support

2. make uImage 使用新的内核启动

3. insmod usb_mouse_key.ko

4. 在开发板上接入和拔除USB设备

 

插入鼠标:打印出found usbmouse!

拔出鼠标:打印出disconnect usbmouse!

 

附上驱动程序1如下:


 1 /*drivers/hid/usbhid/usbmouse.c

 2  */

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9 

10 static struct usb_device_id usb_mouse_key_id_table [] = {

11     { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID      /*usb接口描述符的类为HID*/

12             , USB_INTERFACE_SUBCLASS_BOOT,            /*子类为BOOT*/

13         USB_INTERFACE_PROTOCOL_MOUSE) },             /*协议为MOUSE*/

14     /*{USB_DEVICE(vend,prod)} //若要自定义驱动支持某一款usb,在此处填充 */    

15     { }    /* Terminating entry */

16 };

17 

18 static int usb_mouse_key_probe(struct usb_interface *intf, const struct usb_device_id *id)

19 {

20     printk('<0>found usbmouse !n');

21 

22     return 0;

23 }

24 

25 static void usb_mouse_key_disconnect(struct usb_interface *intf)

26 {

27     printk('<0>disconnect usbmouse !n');

28 }

29 

30 

31 //1. 分配/设置/注册一个USB结构体usb_driver

32 static struct usb_driver usb_mouse_key_driver = {

33     .name        = 'usb_mouse_key',

34     .probe        = usb_mouse_key_probe,

35     .disconnect    = usb_mouse_key_disconnect,

36     .id_table    = usb_mouse_key_id_table,

37 };

38 

39 static int usb_mouse_key_init(void){

40 

41 

42     /*2.注册USB结构体*/

43     usb_register(&usb_mouse_key_driver);

44 

45     return 0;

46 }

47 

48 static void usb_mouse_key_exit(void){

49 

50     //卸载USB结构体

51     usb_deregister(&usb_mouse_key_driver);

52 }

53 

54 module_init(usb_mouse_key_init);

55 module_exit(usb_mouse_key_exit);

56 

57 MODULE_LICENSE('GPL');

58 

59 

60 /*

61 测试:

62 1. make menuconfig 去掉原来鼠标的驱动程序

63     --> Device Drivers

64         --> HID Device

65         <>USB Human Interface Device(full HID) support

66 2. make uImage 使用新的内核启动

67 3. insmod usb_mouse_key.ko

68 4. 在开发板上接入和拔除USB设备

69 

70 */


二.打印出USB鼠标的硬件信息.


1.usb_device 结构体


struct usb_device {

    int         devnum;

    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;

    struct     device dev;

    struct     usb_device_descriptor descriptor;   //硬件的信息

    struct     usb_host_config *config;

    struct     usb_host_config *actconfig;

    struct     usb_host_endpoint *ep_in[16];

    struct     usb_host_endpoint *ep_out[16];

    char      **rawdescriptors;

    unsigned short bus_mA;

    u8        portnum;

    u8        level;

    unsigned can_submit:1;

    unsigned discon_suspended:1;

    unsigned persist_enabled:1;

    unsigned have_langid:1;

    unsigned authorized:1;

    unsigned authenticated:1;

    unsigned wusb:1;

    int string_langid;


    /* static strings from the device */

    char *product;

    char *manufacturer;

    char *serial;

    struct list_head filelist;


#ifdef CONFIG_USB_DEVICE_CLASS

    struct device *usb_classdev;

#endif

#ifdef CONFIG_USB_DEVICEFS

    struct dentry *usbfs_dentry;

#endif

    int maxchild;

    struct usb_device *children[USB_MAXCHILDREN];

    int pm_usage_cnt;

    u32 quirks;

    atomic_t urbnum;

    unsigned long active_duration;


#ifdef CONFIG_PM

    struct delayed_work autosuspend;

    struct work_struct autoresume;

    struct mutex pm_mutex;

    unsigned long last_busy;

    int autosuspend_delay;

    unsigned long connect_time;

    unsigned auto_pm:1;

    unsigned do_remote_wakeup:1;

    unsigned reset_resume:1;

    unsigned autosuspend_disabled:1;

    unsigned autoresume_disabled:1;

    unsigned skip_sys_resume:1;

#endif


    struct wusb_dev *wusb_dev;

    int slot_id;

};   


2.struct usb_device_descriptor结构体


在这个结构体里面包含了鼠标的硬件信息.


 1 /* USB_DT_DEVICE: Device descriptor */

 2 struct usb_device_descriptor {

 3     __u8 bLength;

 4     __u8 bDescriptorType;

 5     __le16 bcdUSB;

 6     __u8 bDeviceClass;

 7     __u8 bDeviceSubClass;

 8     __u8 bDeviceProtocol;

 9     __u8 bMaxPacketSize0;

10     __le16 idVendor;

11     __le16 idProduct;

12     __le16 bcdDevice;

13     __u8 iManufacturer;

14     __u8 iProduct;

15     __u8 iSerialNumber;

16     __u8 bNumConfigurations;

17 } __attribute__ ((packed));


3.在上面程序的基础上,我们在probe函数中打印出上面结构体的信息,如下图所示:

4.测试

如下图所示,正常的打印出了鼠标的硬件ID号

附上驱动程序2如下:

 1 /*drivers/hid/usbhid/usbmouse.c

 2  */

 3 #include

 4 #include

 5 #include

 6 #include

 7 #include

 8 #include

 9 

10 static struct usb_device_id usb_mouse_key_id_table [] = {

11     { USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID      /*usb接口描述符的类为HID*/

12             , USB_INTERFACE_SUBCLASS_BOOT,            /*子类为BOOT*/

13         USB_INTERFACE_PROTOCOL_MOUSE) },             /*协议为MOUSE*/

14     /*{USB_DEVICE(vend,prod)} //若要自定义驱动支持某一款usb,在此处填充 */    

15     { }    /* Terminating entry */

16 };

17 

18 static int usb_mouse_key_probe(struct usb_interface *intf, const struct usb_device_id *id)

19 {

20     struct usb_device *dev = interface_to_usbdev(intf);    //获取USB的接口,设备描述符,在.usb_device_descriptor里面就包含的设备的ID号等信息。

21     printk('<0>found usbmouse !n');

22     

23     printk('<0>USB接口信息如下:n');

24     printk('bcdUSB = %xn',dev->descriptor.bcdUSB);

25     printk('VID = 0x%xn',dev->descriptor.idVendor);

26     printk('PID = 0x%xn',dev->descriptor.idProduct);

27 

28     return 0;

29 

30 }

31 

32 static void usb_mouse_key_disconnect(struct usb_interface *intf)

33 {

34     printk('<0>disconnect usbmouse !n');

35 }

36 

37 

38 //1. 分配/设置/注册一个USB结构体usb_driver

39 static struct usb_driver usb_mouse_key_driver = {

40     .name        = 'usb_mouse_key',

41     .probe        = usb_mouse_key_probe,

42     .disconnect    = usb_mouse_key_disconnect,

43     .id_table    = usb_mouse_key_id_table,

44 };

45 

46 static int usb_mouse_key_init(void){

47 

48 

49     /*2.注册USB结构体*/

50     usb_register(&usb_mouse_key_driver);

51 

52     return 0;

53 }

54 

55 static void usb_mouse_key_exit(void){

56 

57     //卸载USB结构体

58     usb_deregister(&usb_mouse_key_driver);

59 }

60 

61 module_init(usb_mouse_key_init);

62 module_exit(usb_mouse_key_exit);

63 

64 MODULE_LICENSE('GPL');

65 

66 

67 /*

68 测试:

69 1. make menuconfig 去掉原来鼠标的驱动程序

70     --> Device Drivers

71         --> HID Device

72         <>USB Human Interface Device(full HID) support

73 2. make uImage 使用新的内核启动

74 3. insmod usb_mouse_key.ko

75 4. 在开发板上接入和拔除USB设备

76 

77 */

三.获取鼠标的硬件信息

1.定义一个input_dev结构体,设置产生的事件类型,如图所示

2.定义urb(usb请求块usb request block)结构体,设置数据传输三要素,然后提交urb,如图所示

实现上面定义的usb_mouse_key_irq完成查询函数,当usb数据读取成功时,就会自动进入usb_mouse_key_irq函数中

如图所示,这个函数中,由于各个厂家的鼠标的数据定义可能不一样,所以,此处我们先打印测试,分别按下鼠标的左右中键,以及移动鼠标,测试鼠标数据的函数

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    就可正常工作,驱动软件可以在官方网站上下载。其基本原理是将USB控制器转化为虚拟的串口,可以在“我的电脑/属性,硬件,设备管理器”中看到对应的串口。该串口名字用于下载......
    并安装STM闪存加载程序软件,将下载的bin文件闪存到STM32中。单击此链接进入 ST 网站并滚动到底部并单击获取软件 步骤3:要下载软件,您必须输入您的电子邮件地址,下载......
    ,它连接了PC13针脚 那么我就选择这个文件下载 下载完成后,我们要烧录这个文件到STM32里,我们先下载所需要的软件,叫做FlyMcu,下载地址:https://www.lanzous.com......
    低功耗、手机应用软件“ST BLE Sensor” 实验1:STM32固件下载和演示测试 连接B-L475-IOT01A 用Micro USB线连接到B-L475-IOT01A 连接之后,驱动......
    列出了前面关键的步骤,希望大家能尽快入门。 1. 第1步:熟悉调试软件 对初学者来说,我们至少需要安装两个软件:J-Link驱动软件、MDK(就是原来的Keil)软件。 2. 第2步:GPIO编程 GPIO本身......
    USB虚拟串口涉及的文件有下面三类: 底层 中间层 应用层 实际使用的时候只需要关心应用层即可。 在编译下载之前,我们需要在电脑安装STM32提供的虚拟串口驱动,这在他们的官网可以下载......
    接口,常见的可使用串口方式来下载(如SPI、UART等),在下载软件的配合下,可很轻松的把目标文件下到单片机中。 NXP公司专门为其生产的芯片开发了一款下载工具软件......
    它不检查您是否错过了小费或连接是否正常。再次运行该软件,使其重置。 一旦识别出COM端口,则可以单击“下一步3次”,然后会出现一个窗口,可以在其中选择“下载到设备”。 。.选择它,并在其上显示“从文件下载”,单击......
    资料的链接:https://bbs.21ic.com/icview-3055190-1-2.html 一、安装软件包 官网可以下载到IAR和MDK对应pack文件,我使用的是MDK,下载对应的文件。 二......
    要去自己编译烧写,可以直接用STM32的USB DFU通过USB下载固件,我会在附件资料提供相应的软件和文档说明,并提供编译好的几个固件。 canable还提供了一个web的烧写页面: https......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>