linux下USB设备热插拔如何检测

时间:2022-07-07 15:18:53
现在做的项目中想实现USB设备插上以后自动挂载到/mnt/hd目录下。请问大侠们怎么实现。
如果拔出USB设备怎么检测到错误?假如我现在正在写U盘。突然U盘被拔出。我该怎么检测U盘被拔出的消息。我是在嵌入式linux下做的项目。请大家帮帮忙

23 个解决方案

#1


框架是这样的,手头没编译器,你先看看试试。原理就是建立一个socket捕获内核发过来的netlink消息,很简单的。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <sys/un.h> 
#include <sys/ioctl.h> 
#include <sys/socket.h> 
#include <linux/types.h> 
#include <linux/netlink.h> 
#include <errno.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 

#define UEVENT_BUFFER_SIZE 2048 

static int init_hotplug_sock() 

    const int buffersize = 1024; 
    int ret; 

    struct sockaddr_nl snl; 
    bzero(&snl, sizeof(struct sockaddr_nl)); 
    snl.nl_family = AF_NETLINK; 
    snl.nl_pid = getpid(); 
    snl.nl_groups = 1; 

    int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); 
    if (s == -1)  
    { 
        perror("socket"); 
        return -1; 
    } 
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); 

    ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); 
    if (ret < 0)  
    { 
        perror("bind"); 
        close(s); 
        return -1; 
    } 

    return s; 


int main(int argc, char* argv[]) 

    int hotplug_sock = init_hotplug_sock(); 

    while(1) 
    { 
        /* Netlink message buffer */ 
        char buf[UEVENT_BUFFER_SIZE * 2] = {0}; 
        recv(hotplug_sock, &buf, sizeof(buf), 0); 
printf("%s\n", buf); 

        /* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */

    }
    return 0; 
}

#2


..学习

#3


如果是驱动层的话肯定会有拔出来的消息的,那时候将设备删除
一楼的好像说的是网络层的吧

#4


mark

#5


这样的话还是要建立一个线程监控它们。有没有中断机制啊。
如果建立一个线程监控的话。浪费的系统资源比较多。如果采用这种方法其实有个简单的方法就是判断U盘的文件夹
是否存在。如果插上U盘的话文件夹就会出现。否则的话没有文件夹。

#6


为什么不使用udev或mdev???

#7


楼上大侠。怎么用啊?能不能说详细点。刚学linux不久。我的内核是linux 2.6.14的。能不能用udev啊?

#8


udevmonitor 的原理也是捕捉 netlink 的 socket 消息,这个消息是内核发出的,打印出来的消息跟我上面的小程序一样,2.6内核支持udev,udev是在用户空间实现的程序,在终端输入 udevmonitor(有的版本或许是 udevadm -monitor) 然后插拔 USB 设备,可以看到提示信息。

#9


楼上的意思是用户态驱动吧。
无论如何都需要有一个线程来监控设备的状态。比如,插槽上或下位产生的中断,这个型号可以通过很多方式,如netlink、内存映射、软中断等等方式,让用户态线程能够感知是否有USB设备上线,如果有则调用mount函数,否则的话umonut。

#10


学习了。我原来都是写配置文件来实现的。。。

#11


学习一下!

#12


顶一下~

继续讨论

我们也遇到个usb设备读取目录的问题,先检测后mount再读取目录...

#13


mark

#14


这个我说一下。我用的是二楼的方法。早已经实现功能了。

#15


貌似时间很久,我也关注一下。

#16


看看???????????????

#17


该回复于2011-03-03 17:30:25被版主删除

#18


/* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */

怎么对比这些信息,才能识别我的usb设备呢

#19


 当U盘插进去后 出现add@/dev/sda1,当U盘拔了过后是remove@/dev/sda1之类的信息。

#20


该回复于2012-05-22 09:33:52被版主删除

#21


学习了,感谢二楼 Breathomn 的分享

#22


http://blog.csdn.net/yanzi1225627/article/details/7855124原来是用qt的dbus实现的,基于hal。但纠结了一个星期,程序到arm上没反应。好像arm不支持hal。文件系统是yaffs2,的所以udev也不支持。最后选择了hotplug。太蛋疼了!绕了一个大弯。。。。。。。。

#23


引用 8 楼  的回复:
udevmonitor 的原理也是捕捉 netlink 的 socket 消息,这个消息是内核发出的,打印出来的消息跟我上面的小程序一样,2.6内核支持udev,udev是在用户空间实现的程序,在终端输入 udevmonitor(有的版本或许是 udevadm -monitor) 然后插拔 USB 设备,可以看到提示信息。

问题是,老大arm板子上没有啊!!!

#1


框架是这样的,手头没编译器,你先看看试试。原理就是建立一个socket捕获内核发过来的netlink消息,很简单的。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <ctype.h> 
#include <sys/un.h> 
#include <sys/ioctl.h> 
#include <sys/socket.h> 
#include <linux/types.h> 
#include <linux/netlink.h> 
#include <errno.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <netinet/in.h> 

#define UEVENT_BUFFER_SIZE 2048 

static int init_hotplug_sock() 

    const int buffersize = 1024; 
    int ret; 

    struct sockaddr_nl snl; 
    bzero(&snl, sizeof(struct sockaddr_nl)); 
    snl.nl_family = AF_NETLINK; 
    snl.nl_pid = getpid(); 
    snl.nl_groups = 1; 

    int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); 
    if (s == -1)  
    { 
        perror("socket"); 
        return -1; 
    } 
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); 

    ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); 
    if (ret < 0)  
    { 
        perror("bind"); 
        close(s); 
        return -1; 
    } 

    return s; 


int main(int argc, char* argv[]) 

    int hotplug_sock = init_hotplug_sock(); 

    while(1) 
    { 
        /* Netlink message buffer */ 
        char buf[UEVENT_BUFFER_SIZE * 2] = {0}; 
        recv(hotplug_sock, &buf, sizeof(buf), 0); 
printf("%s\n", buf); 

        /* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */

    }
    return 0; 
}

#2


..学习

#3


如果是驱动层的话肯定会有拔出来的消息的,那时候将设备删除
一楼的好像说的是网络层的吧

#4


mark

#5


这样的话还是要建立一个线程监控它们。有没有中断机制啊。
如果建立一个线程监控的话。浪费的系统资源比较多。如果采用这种方法其实有个简单的方法就是判断U盘的文件夹
是否存在。如果插上U盘的话文件夹就会出现。否则的话没有文件夹。

#6


为什么不使用udev或mdev???

#7


楼上大侠。怎么用啊?能不能说详细点。刚学linux不久。我的内核是linux 2.6.14的。能不能用udev啊?

#8


udevmonitor 的原理也是捕捉 netlink 的 socket 消息,这个消息是内核发出的,打印出来的消息跟我上面的小程序一样,2.6内核支持udev,udev是在用户空间实现的程序,在终端输入 udevmonitor(有的版本或许是 udevadm -monitor) 然后插拔 USB 设备,可以看到提示信息。

#9


楼上的意思是用户态驱动吧。
无论如何都需要有一个线程来监控设备的状态。比如,插槽上或下位产生的中断,这个型号可以通过很多方式,如netlink、内存映射、软中断等等方式,让用户态线程能够感知是否有USB设备上线,如果有则调用mount函数,否则的话umonut。

#10


学习了。我原来都是写配置文件来实现的。。。

#11


学习一下!

#12


顶一下~

继续讨论

我们也遇到个usb设备读取目录的问题,先检测后mount再读取目录...

#13


mark

#14


这个我说一下。我用的是二楼的方法。早已经实现功能了。

#15


貌似时间很久,我也关注一下。

#16


看看???????????????

#17


该回复于2011-03-03 17:30:25被版主删除

#18


/* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */

怎么对比这些信息,才能识别我的usb设备呢

#19


 当U盘插进去后 出现add@/dev/sda1,当U盘拔了过后是remove@/dev/sda1之类的信息。

#20


该回复于2012-05-22 09:33:52被版主删除

#21


学习了,感谢二楼 Breathomn 的分享

#22


http://blog.csdn.net/yanzi1225627/article/details/7855124原来是用qt的dbus实现的,基于hal。但纠结了一个星期,程序到arm上没反应。好像arm不支持hal。文件系统是yaffs2,的所以udev也不支持。最后选择了hotplug。太蛋疼了!绕了一个大弯。。。。。。。。

#23


引用 8 楼  的回复:
udevmonitor 的原理也是捕捉 netlink 的 socket 消息,这个消息是内核发出的,打印出来的消息跟我上面的小程序一样,2.6内核支持udev,udev是在用户空间实现的程序,在终端输入 udevmonitor(有的版本或许是 udevadm -monitor) 然后插拔 USB 设备,可以看到提示信息。

问题是,老大arm板子上没有啊!!!