Linux下自动检测USB热插拔
来源:互联网 发布:奇迹暖暖每章套装知乎 编辑:程序博客网 时间:2024/06/07 12:28
做嵌入式开发,尤其在网关、路由器或者其他支持USB设备的终端上,为了提高用户体验,我们常常需要支持自动识别并挂载USB设备功能。某些应用程序,在使用USB设备的过程中,也希望能够侦测到USB断开事件,不至于某些工作因为USB已经不存在而白做。在Linux下,我们主要有两种办法检测USB热插拔。
第一种便是定时检查/proc/scsi/scsi文件,该文件内会按照标准格式保存着当前设备内挂载的存储介质基本信息,如果在PC端,除了硬盘(ATA)、光驱(CD-ROM)外,就是USB设备(Direct-Access)了,轮询该scsi文件,检查文件内是否新增或减少数据便可实现自动侦测USB热插拔的效果。但是这种方法对于热插拔(hotplug)设备,如U盘,效果就没那么理想了,因为我们不知道设备什么时候插上,又是什么时候被拔掉了,只能验证当前是否已经插上或者已经拔除的事实。于是便有了另一种办法,我们采用一种特殊类的的文件描述符(套结字)专门用于Linux内核跟用户空间之间的异步通信,这种技术通常被成为NETLINK。
由于NETLINK是Linux内置功能,所以使用起来很简单:创建一个AF_NETLINK协议族下NETLINK_KOBJECT_UEVENT类型的特殊文件描述符(套结字)CppLive,然后利用setsocketopt允许该文件描述符(套结字)复用其他端口,再利用band函数将自身进程绑定到特殊文件描述符(套结字)CppLive,最后利用select在while循环内监听CppLive是否可读,如果可读则调用recv接收Linux系统内核传递过来的数据并打印出来,这些输出便是USB热插拔信息。当然你也可以个性化地处理来自内核的热插拔信息,让程序变得更加智能以及人性化。
利用NETLINK检测USB热插拔的C语言实现代码如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/socket.h>
- #include <linux/netlink.h>
- #define UEVENT_BUFFER_SIZE 2048
- int main(void)
- {
- struct sockaddr_nl client;
- struct timeval tv;
- int CppLive, rcvlen, ret;
- fd_set fds;
- int buffersize = 1024;
- CppLive = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT);
- memset(&client, 0, sizeof(client));
- client.nl_family = AF_NETLINK;
- client.nl_pid = getpid();
- client.nl_groups = 1; /* receive broadcast message*/
- setsockopt(CppLive, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
- bind(CppLive, (struct sockaddr*)&client, sizeof(client));
- while (1) {
- char buf[UEVENT_BUFFER_SIZE] = { 0 };
- FD_ZERO(&fds);
- FD_SET(CppLive, &fds);
- tv.tv_sec = 0;
- tv.tv_usec = 100 * 1000;
- ret = select(CppLive + 1, &fds, NULL, NULL, &tv);
- if(ret < 0)
- continue;
- if(!(ret > 0 && FD_ISSET(CppLive, &fds)))
- continue;
- /* receive data */
- rcvlen = recv(CppLive, &buf, sizeof(buf), 0);
- if (rcvlen > 0) {
- printf("%s\n", buf);
- /*You can do something here to make the program more perfect!!!*/
- }
- }
- close(CppLive);
- return 0;
- }
运行程序,测试U盘插入/拔除,输出如下:
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0
- add@/module/usb_storage
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/scsi_host/host6
- add@/bus/usb/drivers/usb-storage
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/scsi_disk/6:0:0:0
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/scsi_device/6:0:0:0
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/scsi_generic/sg2
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/bsg/6:0:0:0
- change@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/block/sdb
- add@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/block/sdb/sdb4
- add@/devices/virtual/bdi/8:16
- add@/module/fat
- add@/kernel/slab/fat_cache
- add@/kernel/slab/fat_inode_cache
- add@/module/vfat
- add@/module/nls_cp437
- add@/module/nls_iso8859_1
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/bsg/6:0:0:0
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/scsi_generic/sg2
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/scsi_device/6:0:0:0
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/scsi_disk/6:0:0:0
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/block/sdb/sdb4
- remove@/devices/virtual/bdi/8:16
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0/block/sdb
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/target6:0:0/6:0:0:0
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6/scsi_host/host6
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0/host6
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1/2-1:1.0
- remove@/devices/pci0000:00/0000:00:1d.7/usb2/2-1
- remove@/host6/target6:0:0
转自http://www.cpplive.com/html/1355.html
- Linux下自动检测USB热插拔
- Linux下自动检测USB热插拔
- linux 2.6 usb自动检测
- linux 2.6 usb自动检测
- linux下自动检测mongodb 有问题就重启
- Linux下实现U盘自动检测
- 如何在LINUX下实现硬件的自动检测(下)
- USB 设备的自动检测 /proc/bus/usb
- linux下实现USB口的热插拔
- linux下USB设备热插拔如何检测
- Linux下实现USB口的热插拔
- 如何在LINUX下实现硬件的自动检测
- 如何在LINUX下实现硬件的自动检测(上)
- 如何在Linux下实现硬件的自动检测
- Linux下Tomcat自动检测和重启脚本
- linux下usb使用
- linux下USB驱动
- WINCE5.0上USB设备的自动检测
- vmstat命令的输出解释
- MySQL技术内幕InnoDB存储引擎学习笔记(第六章)
- CUDA编程_DEBUG_01
- 监听activeMQ的状态
- 二叉树前、中、后序遍历【非递归】【LintCode测试平台】
- Linux下自动检测USB热插拔
- 快速排序
- 简单写一个加入组播组接收到数据的代码
- Android studio真的很坑啊,智能还很远,麻烦倒是挺多
- APP直播源码、云豹直播破解版
- 顺序表应用3:元素位置互换之移位算法
- java内部类学习笔记
- 水经注下载的DAT文件用什么软件打开
- KVM源代码分析3:CPU虚拟化