当前位置:   article > 正文

arduino usb串口驱动_linux的usb转串口热插拔检测、驱动的自动安装

linux系统如何识别arduino端口

目前linux的发行版本都支持usb设备的热插拔。usb转串口设备从硬件上来说也是一个即插即用的usb设备。插入或拔出的时候,都是通过usb的hub集线器检测。那么是如何检测并自动安装对应接口的驱动的呢?---------------目前网络上找到的资料都是零散的,关键是没有找到跟本文linux5.4.0内核相对应的(很多参考资料都是针对2.6内核,如参考书LDD3)。

下文就基于linux5.4.0内核,将接口事件检测到自动安装驱动的环节一步步写下来,如有不妥之处,欢迎大家指正。(我自己被怎么自动安装驱动部分困扰了很久!)

一、热插拔事件的触发

1、当usb设备插入集线器hub时,插入的设备将拉高D+或D-,此时端口变化发生了变化,从而进入hub_irq中断。

2、hub_irq中断触发hub的event_list,从而进入hub_thread线程;

3、hub_thread调用hub_events()。

4、由于端口的变化,hub_events()函数进入hub_port_connect_change()。

1)分配一个usb设备配并初始化udev:

udev = usb_alloc_dev(hdev, hdev_bus, port1);//           struct usb_device *udev

2)初始化设备配置usb_new_device(udev);

(1)usb_configure_device(udev)->usb_get_configuration(udev);

得到设备的描述符(包括设备描述符、配置描述符、接口描述符等),并分析和提取配置、接口等信息赋值给udev结构相应字段。

(2)device_add(&udev->dev);------------将usb设备注册到设备模型中

  1. int device_add(struct device *dev)
  2. {
  3. ................................
  4. kobject_uevent(&dev->kobj, KOBJ_ADD); //产生uevent事件,是linux设备模型中热插拔机制, 源码位于/usr/src/linux-5.4/lib/kobject_uevent.c
  5. ...............................
  6. };

这里的kobject_uevent()是实现自动加载驱动的关键。

二、根据检测的接口信息、自动安装对应驱动

这里不得不提到Linux uevent机制。它是内核与用户空间的一种通信机制。当有新的设备加入的时候,将设备的信息发送消息到用户态。如设备驱动模型的usb热插拔uevent,发出kobject_uevent()事件获取相关的环境变量,并通知到用户空间。而用户态有一个Udev的守护进程监听这个信息,并执行一些操作,比如可以加载驱动程序。

Udev 守护进程直接从内核接收设备的插入、拔出、改变状态等事件,并到规则库中进行匹配,以实现设备的触发事件。

Udev同时为连接在系统上面的设备节点提供一个动态设备目录。设备插入或移出系统的时候,Udev就在 /dev目录下面创建或者删除设备节点文件。如插入本文的激光雷达,就在 /dev下面生成serial文件夹,serial中包含两个文件夹/dev/serial/by-id和/dev/serial/by-path。

f1db0fc9aff8ae906d99ced1baea024c.png
图一 serial文件夹

Udev使用modalias方法来加载设备驱动程序,而位于/lib/modules/5.4.0/modules.alias 的modalias文件用于协助Udev加载设备驱动。

1、modules.alias 文件

那么modules.alias 是如何产生的呢?这与宏定义MODULE_DEVICE_TABLE()有关。

在linux的设备模型中, 每一个设备都有VENDOR ID, _PRODUCT ID等信息。而每一个设备驱动程序,也需要表明自己能为哪些VENDOR ID, _PRODUCT ID的设备提供服务。以下以PL2303为例,在pl2303.c中,有如下定义:

  1. static const struct usb_device_id id_table[] = {
  2. { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID),
  3. .driver_info = PL2303_QUIRK_ENDPOINT_HACK },
  4. { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
  5. ......
  6. }
  7. MODULE_DEVICE_TABLE(usb, id_table);

在安装模块的时候,depmod程序根据id_table信息,把相关的模块信息添加到/lib/modules/uname-r/modules.alias文件中。

  1. alias usb:v067Bp2303d*dc*dsc*dp*ic*isc*ip*in* pl2303
  2. ......

其中v代表Vendor ID,p代表PRODUCT ID,后面的*表示随意匹配。另外在/lib/modules/uname-r/modules.dep文件中还保存了模块之间的依赖关系(表示模块pl2303.ko依赖于模块usbserial.ko )。

  kernel/drivers/usb/serial/pl2303.ko: kernel/drivers/usb/serial/usbserial.ko                                                                                                                                                                                      

2、udev的自动加载机制

udev 规则是定义在一个以 .rules 为扩展名的文件中,这些文件主要放在两个位置:

(1)/lib/udev/rules.d,这个目录用于存放系统安装的规则;

(2)/etc/udev/rules.d/, 这个目录存放本机规则,如激光雷达的自定义规则就放于此;

本文提到的serial驱动udev规则位于/lib/udev/rules.d/80-drivers.rules中。

如上所述kobject_uevent()把添加新设备的事件、以及相关信息(如设备的VendorID, ProductID等信息)通过netlink发送到用户态。在用户态的Udev进程得到信息后,根据/lib/udev/rules.d/80-drivers.rules的规则:

ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load $env{MODALIAS}"

当有环境变量MODALIAS(就是modules.alias的信息格式)时,自动加载驱动程序。此时根据modules.alias和modules.dep文件,得知设备驱动模块为pl2303.ko,并且此模块依赖于 /usbserial.ko。如果此时usbserial.ko没有加载,就先加载usbserial.ko,接着再加载 pl2303.ko。

3、udevadm

udevadm是一个udev管理工具,可以获取内核发送的事件。输入命令:udevadm monitor --env。

  1. valian@valian-TM1703:~$ udevadm monitor --env
  2. monitor will print the received events for:
  3. UDEV - the event which udev sends out after rule processing
  4. KERNEL - the kernel uevent

插入我的激光雷达后,可以获得以下uevent信息。这里可以看到MODALIAS信息,这里的MODALIAS就是modules.alias文件匹配的格式。

  1. KERNEL[34996.845989] add /devices/pci0000:00/0000:00:14.0/usb1/1-4 (usb)
  2. ACTION=add
  3. BUSNUM=001
  4. DEVNAME=/dev/bus/usb/001/011
  5. DEVNUM=011
  6. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4
  7. DEVTYPE=usb_device
  8. MAJOR=189
  9. MINOR=10
  10. PRODUCT=67b/2303/300
  11. SEQNUM=4188
  12. SUBSYSTEM=usb
  13. TYPE=0/0/0
  14. KERNEL[34996.847771] add /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0 (usb)
  15. ACTION=add
  16. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0
  17. DEVTYPE=usb_interface
  18. INTERFACE=255/0/0
  19. MODALIAS=usb:v067Bp2303d0300dc00dsc00dp00icFFisc00ip00in00
  20. PRODUCT=67b/2303/300
  21. SEQNUM=4189
  22. SUBSYSTEM=usb
  23. TYPE=0/0/0
  24. KERNEL[34996.848910] add /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0 (usb-serial)
  25. ACTION=add
  26. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0
  27. SEQNUM=4190
  28. SUBSYSTEM=usb-serial
  29. KERNEL[34996.849138] add /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0/tty/ttyUSB0 (tty)
  30. ACTION=add
  31. DEVNAME=/dev/ttyUSB0
  32. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0/tty/ttyUSB0
  33. MAJOR=188
  34. MINOR=0
  35. SEQNUM=4191
  36. SUBSYSTEM=tty
  37. UDEV [34996.860612] add /devices/pci0000:00/0000:00:14.0/usb1/1-4 (usb)
  38. ACTION=add
  39. BUSNUM=001
  40. DEVNAME=/dev/bus/usb/001/011
  41. DEVNUM=011
  42. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4
  43. DEVTYPE=usb_device
  44. DRIVER=usb
  45. ID_BUS=usb
  46. ID_MM_DEVICE_MANUAL_SCAN_ONLY=1
  47. ID_MODEL=USB-Serial_Controller
  48. ID_MODEL_ENC=USB-Serialx20Controller
  49. ID_MODEL_FROM_DATABASE=PL2303 Serial Port
  50. ID_MODEL_ID=2303
  51. ID_REVISION=0300
  52. ID_SERIAL=Prolific_Technology_Inc._USB-Serial_Controller
  53. ID_USB_INTERFACES=:ff0000:
  54. ID_VENDOR=Prolific_Technology_Inc.
  55. ID_VENDOR_ENC=Prolificx20Technologyx20Inc.
  56. ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
  57. ID_VENDOR_ID=067b
  58. MAJOR=189
  59. MINOR=10
  60. PRODUCT=67b/2303/300
  61. SEQNUM=4188
  62. SUBSYSTEM=usb
  63. TYPE=0/0/0
  64. USEC_INITIALIZED=34996860449
  65. UDEV [34997.866782] add /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0 (usb)
  66. .MM_USBIFNUM=00
  67. ACTION=add
  68. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0
  69. DEVTYPE=usb_interface
  70. DRIVER=pl2303
  71. ID_MODEL_FROM_DATABASE=PL2303 Serial Port
  72. ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
  73. INTERFACE=255/0/0
  74. MODALIAS=usb:v067Bp2303d0300dc00dsc00dp00icFFisc00ip00in00
  75. PRODUCT=67b/2303/300
  76. SEQNUM=4189
  77. SUBSYSTEM=usb
  78. TYPE=0/0/0
  79. USEC_INITIALIZED=34996862068
  80. UDEV [34997.869061] add /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0 (usb-serial)
  81. .MM_USBIFNUM=00
  82. ACTION=add
  83. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0
  84. DRIVER=pl2303
  85. SEQNUM=4190
  86. SUBSYSTEM=usb-serial
  87. USEC_INITIALIZED=34997868911
  88. UDEV [34997.873758] add /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0/tty/ttyUSB0 (tty)
  89. .ID_PORT=0
  90. .MM_USBIFNUM=00
  91. ACTION=add
  92. DEVLINKS=/dev/serial/by-id/usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0 /dev/rplidar /dev/serial/by-path/pci-0000:00:14.0-usb-0:4:1.0-port0
  93. DEVNAME=/dev/ttyUSB0
  94. DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4:1.0/ttyUSB0/tty/ttyUSB0
  95. ID_BUS=usb
  96. ID_MM_CANDIDATE=1
  97. ID_MODEL=USB-Serial_Controller
  98. ID_MODEL_ENC=USB-Serialx20Controller
  99. ID_MODEL_FROM_DATABASE=PL2303 Serial Port
  100. ID_MODEL_ID=2303
  101. ID_PATH=pci-0000:00:14.0-usb-0:4:1.0
  102. ID_PATH_TAG=pci-0000_00_14_0-usb-0_4_1_0
  103. ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
  104. ID_PCI_INTERFACE_FROM_DATABASE=XHCI
  105. ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
  106. ID_REVISION=0300
  107. ID_SERIAL=Prolific_Technology_Inc._USB-Serial_Controller
  108. ID_TYPE=generic
  109. ID_USB_DRIVER=pl2303
  110. ID_USB_INTERFACES=:ff0000:
  111. ID_USB_INTERFACE_NUM=00
  112. ID_VENDOR=Prolific_Technology_Inc.
  113. ID_VENDOR_ENC=Prolificx20Technologyx20Inc.
  114. ID_VENDOR_FROM_DATABASE=Prolific Technology, Inc.
  115. ID_VENDOR_ID=067b
  116. MAJOR=188
  117. MINOR=0
  118. SEQNUM=4191
  119. SUBSYSTEM=tty
  120. TAGS=:systemd:
  121. USEC_INITIALIZED=34997873660
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/59696
推荐阅读
相关标签
  

闽ICP备14008679号