找回密码
 注册
关于网站域名变更的通知
查看: 236|回复: 1
打印 上一主题 下一主题

怎样在Linux环境下实现USB口的热插拔

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-11-11 11:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
: e0 Z) b5 v& l( k; g1 ^6 q! a
目前要做一个在嵌入式平台上的USB口的热插拔事件。
& }8 @: o. J. p( [
" ^( |. ^4 E# S; P% ^经过我现在的分析总结目前有如下方法:' X6 V% @6 w# r  V5 {& i3 b
6 S3 C" I: m0 j& C' S) J- m' M+ N
1,定时检查/proc/scsi/scsi文件  Z3 ]8 f' [+ V0 d$ C

" ~# h7 A( v- X: b4 I% |此方法只能在PC上,但在嵌入式平台上不可用。% E! x7 a- \2 O4 W0 W& M
) ]2 |1 T+ M3 E+ F
2,netlink方式& @  \" h6 Q' @1 t

* q- }, t  [( [8 Z9 D5 h7 {使用netlink.
* u  Q) [- A- e" O3 k
$ o2 Y$ A. _9 R0 J1 c1 C1 M#include <stdio.h>5 B+ `0 K1 A0 B5 A
#include <stdlib.h>
5 p( w) [8 f3 Q4 m8 _. J#include <string.h>/ p6 c  N# I) o8 ~( p' ?/ h
#include <ctype.h>3 n- J* K  n: y% l" m
#include <sys/un.h>
" m0 ^5 v5 i, ]8 z. S3 U7 I#include <sys/ioctl.h>' O7 q, [8 r7 q9 V4 g
#include <sys/socket.h>
6 u' M" I3 a1 {. _; a#include <linux/types.h>" }* K3 ~* [- I( J. O; A1 k6 \
#include <linux/netlink.h>
! b9 M4 `) U3 E+ H7 _#include <errno.h>
- B' B' m7 ]; i7 R. t#include <unistd.h>7 H6 K0 K  T( X  ?  l( X
#include <arpa/inet.h>
) r$ f; j) h+ w$ J2 m1 |#include <netinet/in.h>
' |6 E/ {0 l8 A
1 V" `8 e1 q# t  v4 @#define UEVENT_BUFFER_SIZE 2048( `( v8 e/ t' ~/ D8 k) o
# V2 Q: Y( F! x6 u4 }3 F$ t  S
static int init_hotplug_sock(); G+ K: C* J, A, t1 X3 y
{( I9 m8 J( k+ ^& C2 N8 U
  const int buffersize = 1024;
2 @# P) X, @" R3 u& b  int ret;% V. F) [5 |9 O2 V! b
: v7 L' k) O- b* x/ K$ `
  struct sockaddr_nl snl;7 M# y% E" k1 ]" J
  bzero(&snl, sizeof(struct sockaddr_nl));
' W% i8 d- f+ ]8 _( X/ ^7 W  snl.nl_family = AF_NETLINK;
" a" z- n4 {2 E& ~( X- f0 C  snl.nl_pid = getpid();) L! N; I6 ]0 q! M( @( |' P7 N9 G
  snl.nl_groups = 1;( [/ U( q* k  \$ ~+ {  ^5 G9 x- K3 g
0 n! r2 T4 q3 [  ]. d
  int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);) Y2 ]8 Y/ m4 w. T7 u5 O
  if (s == -1)
+ c! X8 w" A8 @5 r  S7 k# N  {, F1 V) y" U9 m3 p0 m! D5 j9 c
        perror("socket");
1 s3 L5 v5 n4 a) _( Y' f        return -1;
7 a& f1 A4 b: h1 C/ @7 O  }
. _$ B, k. S2 a1 {  setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
& \; ?* E6 c- Z& M
4 c; J) Y6 d2 w1 G' ^; Y/ ]5 _: N  ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));' B! _% Q8 B. W0 F$ O" D, e4 M
  if (ret < 0)* }$ Y" m( M8 {1 o& e0 d
  {$ R4 w, Q4 M, r: |
        perror("bind");; `& \8 x* z+ N. {! \2 v
        close(s);6 U. `+ E  H) P7 P0 ?
        return -1;% Z8 V' c' s0 x' D3 E
  }
7 h2 r) j( l' f% t$ N* P# N# b, x
: M" ~( M; ]' l" a$ U6 R3 G2 U6 {  return s;
8 p) a' b% W( r' \  h  M}
7 O1 J/ u: r5 v5 z
# D! d* s4 r/ p! J  `2 n( Wint main(int argc, char* argv[])
+ e. y% F; ^0 X  C/ }; e{
9 N" _; @) a- z+ v; U) e2 j" J  int hotplug_sock = init_hotplug_sock();9 I7 o# v6 y& Z4 K

# k# q4 ~4 h) }4 j6 k% Z0 O; r$ h' f  while(1)* r+ E# o% _) V+ h) o5 F( v: t
  {* s8 X+ y& X# s# x, n
      /* Netlink message buffer */
# K: U7 G9 M! e; {( f) N      char buf[UEVENT_BUFFER_SIZE * 2] = {0};
) K9 y+ Y0 N& Y, `5 }# v      recv(hotplug_sock, &buf, sizeof(buf), 0);
- r' G" u* Z; p" v! ~+ q- f; r; v! l      printf("%s\n", buf);
2 A, a/ l5 C) H5 x! _: O, k$ J0 S; F( m
     /* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */' f! F" {8 D5 n' {! h
  }0 R( S# l3 x! B
  return 0;% a: U' \! f- I5 A. g+ K
( L& C' K' {9 o, r' S4 r
}
+ H; f* V7 M6 @& f0 G3 Z" _& O5 h; M0 U+ x. c! m% T  |" _
经过测试发现只能实现插与拔,但是无法具体到具体是什么设备。; F3 E: D' C4 X& G/ A/ Q! z0 `# l

7 G& ~& f$ r. T- g2 N3,使用mdev。
  }/ }# R: y7 C2 L0 F2 J
! F9 W& o# f8 j! D此方法相当麻烦,现在在研究中。  S: _; B+ H% j( S

* t+ y& S1 o, i4,使用最原始的解析文件方式' x6 r9 a+ |8 ~- Q- W
$ C/ ?) A/ o% K' a+ D0 Q. {- |- w1 t8 y
此方法相当麻烦,生成很多文件。1 @; p' {3 ~+ n  P  a

' e* a6 ^$ T! @$ ~就是用cat /proc/bus/usb/devices的信息生成的文件进行解析。5 I: B4 k$ t- A$ z. U* D4 `

% I! \/ L9 f, R目前我已经完成此功能。虽然能用,但是效率太低。

该用户从未签到

2#
发表于 2019-11-21 13:38 | 只看该作者
看看楼主说的方法。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-24 17:38 , Processed in 0.125000 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表