日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下自动检测USB热插拔

發(fā)布時(shí)間:2025/3/15 linux 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下自动检测USB热插拔 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

嵌入式開發(fā),尤其在網(wǎng)關(guān)路由器或者其他支持USB設(shè)備的終端上,為了提高用戶體驗(yàn),我們常常需要支持自動(dòng)識(shí)別并掛載USB設(shè)備功能。某些應(yīng)用程序,在使用USB設(shè)備的過程中,也希望能夠偵測(cè)到USB斷開事件,不至于某些工作因?yàn)閁SB已經(jīng)不存在而白做。在Linux下,我們主要有兩種辦法檢測(cè)USB熱插拔。 ? ?

第一種便是定時(shí)檢查/proc/scsi/scsi文件,該文件內(nèi)會(huì)按照標(biāo)準(zhǔn)格式保存著當(dāng)前設(shè)備內(nèi)掛載的存儲(chǔ)介質(zhì)基本信息,如果在PC端,除了硬盤(ATA)、光驅(qū)(CD-ROM)外,就是USB設(shè)備(Direct-Access)了,輪詢?cè)搒csi文件,檢查文件內(nèi)是否新增或減少數(shù)據(jù)便可實(shí)現(xiàn)自動(dòng)偵測(cè)USB熱插拔的效果。但是這種方法對(duì)于熱插拔(hotplug)設(shè)備,如U盤,效果就沒那么理想了,因?yàn)槲覀儾恢涝O(shè)備什么時(shí)候插上,又是什么時(shí)候被拔掉了,只能驗(yàn)證當(dāng)前是否已經(jīng)插上或者已經(jīng)拔除的事實(shí)。于是便有了另一種辦法,我們采用一種特殊類的的文件描述符套結(jié)字)專門用于Linux內(nèi)核跟用戶空間之間的異步通信,這種技術(shù)通常被成為NETLINK。

由于NETLINK是Linux內(nèi)置功能,所以使用起來很簡(jiǎn)單:創(chuàng)建一個(gè)AF_NETLINK協(xié)議族下NETLINK_KOBJECT_UEVENT類型的特殊文件描述符(套結(jié)字)CppLive,然后利用setsocketopt允許該文件描述符(套結(jié)字)復(fù)用其他端口,再利用band函數(shù)將自身進(jìn)程綁定到特殊文件描述符(套結(jié)字)CppLive,最后利用select在while循環(huán)內(nèi)監(jiān)聽CppLive是否可讀,如果可讀則調(diào)用recv接收Linux系統(tǒng)內(nèi)核傳遞過來的數(shù)據(jù)并打印出來,這些輸出便是USB熱插拔信息。當(dāng)然你也可以個(gè)性化地處理來自內(nèi)核的熱插拔信息,讓程序變得更加智能以及人性化。

利用NETLINK檢測(cè)USB熱插拔的C語言實(shí)現(xiàn)代碼如下:

view plaincopy to clipboardprint?
  • #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;??
  • }??
  • 運(yùn)行程序,測(cè)試U盤插入/拔除,輸出如下:

    view plaincopy to clipboardprint?
  • 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 ?


    轉(zhuǎn)自http://www.cpplive.com/html/1355.html
  • 總結(jié)

    以上是生活随笔為你收集整理的Linux下自动检测USB热插拔的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。