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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
; N4 ~3 o( L; j
目前要做一个在嵌入式平台上的USB口的热插拔事件。6 L; B# a( p& O
$ |$ G( x$ z. a) h) ]* z, ~
经过我现在的分析总结目前有如下方法:4 m/ F/ H6 {- O/ }

1 U! q6 e7 S9 B2 m; r7 h! K5 {1,定时检查/proc/scsi/scsi文件
' s' `2 W7 B( N& a, P! Q0 @: T) ]0 V; t
# F; F6 `  A% i此方法只能在PC上,但在嵌入式平台上不可用。
0 ~" L( O$ ]% y# m! A% Y/ w/ ~6 X6 ]$ @( e. _
2,netlink方式/ ]9 ]- _- c7 \" ^# g2 l: \+ ^
9 @3 E' A, n$ J
使用netlink.
' R8 L" m, l7 t( _4 _
7 p3 f" v& @" i; }! q! g#include <stdio.h>$ _* G3 x# X  Y( V" Y
#include <stdlib.h>
3 x8 ]% z1 P4 j& _# m#include <string.h>
4 }' p8 d! b. L) w, P' [" r& @" m5 A#include <ctype.h>
* \# ?3 U& i. q#include <sys/un.h>, x7 \7 b" H0 P* a* l! f
#include <sys/ioctl.h>
3 T  k3 }) ~" ~( X7 d#include <sys/socket.h>6 q  a* T, d; s% o2 r! r
#include <linux/types.h>  y1 S- }2 U+ b% y+ w& c4 o
#include <linux/netlink.h>3 a( V' E. @8 _* B. l" ~
#include <errno.h>
$ k& X/ v9 c. w4 l/ c#include <unistd.h>
" M* [" `0 U+ Z9 I5 v$ {+ L#include <arpa/inet.h>" _0 }; H  @& m/ d4 Q4 `/ Z
#include <netinet/in.h>: t6 R& @& h7 @7 `' \, A

6 L' i& s; f8 b- e( W8 q( O#define UEVENT_BUFFER_SIZE 2048( w, z( j2 C- _# I. h5 f. k

9 ]  Q5 M. H& l* D. o0 a+ y5 @( Cstatic int init_hotplug_sock()
4 O9 f3 `) m( m{
: W0 Z" r: \! e3 S! u& g  const int buffersize = 1024;
% [% ]0 N' S4 R. _) v1 U0 ?* H  int ret;
" c7 w1 c. L% M4 o; N
9 J1 N' Z7 j* A: [) g  struct sockaddr_nl snl;
( U( Z0 v' f) H, h4 y  bzero(&snl, sizeof(struct sockaddr_nl));8 @3 p. J! g) ^3 D: B% ]" S
  snl.nl_family = AF_NETLINK;# f, x- d' O7 {. N. W( I( H. Q
  snl.nl_pid = getpid();$ {0 H  N  a* R6 E! u5 N8 X
  snl.nl_groups = 1;
- p& E: ~9 t- c' x. O# ?: V% Z. X9 P$ P
  int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
% ^4 C3 F, u, E& v& F9 O  if (s == -1)- f  h4 F- O8 c/ X- A
  {
# s/ m8 E! M+ J/ o7 y4 X% R- |        perror("socket");- ?% ?- ], A; T
        return -1;
8 @9 u/ J( q/ b* K  }
2 H5 p3 H7 H6 r- L3 V$ a5 `" J  setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));
9 y7 n/ L  Z' M9 K$ v6 E, t3 T% ]6 i, S& H/ ]  v% Z8 _
  ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
- h) t8 {) F4 @# A  if (ret < 0)% o$ t4 ^/ P. g$ F; H
  {& \# j) m4 W! y1 }1 A6 g% X
        perror("bind");* _  v( F) Z7 {# g
        close(s);' G. _! e1 ]5 k+ m# o/ A
        return -1;
5 v  O, K7 J' o6 v  }+ {; @. F$ [! {5 W* N

! A5 \- S# A$ X+ C" h! @3 s  return s;! C8 n  h! Q9 v- {
}5 ]) T6 L5 M3 J, Z- t4 F

" B9 Q1 M% t, j( Z" k4 R3 J' aint main(int argc, char* argv[])
' d- F% ?# D# k2 j6 T. A; @{/ j- P* J" i4 X
  int hotplug_sock = init_hotplug_sock();6 w) L: S1 S8 w- k# x- }

6 k& ~' @8 h" G8 {2 i, P  while(1)' |, ?% t1 p; S
  {" ~" \4 T& e% e/ j+ [
      /* Netlink message buffer */
( X, e. a! u! H      char buf[UEVENT_BUFFER_SIZE * 2] = {0};& L# q" J4 M1 R1 s9 y4 s) X, }
      recv(hotplug_sock, &buf, sizeof(buf), 0);
8 |5 e7 P$ B1 X- U, X      printf("%s\n", buf);
; T, ?# @3 i5 ]* q# _) v. n
% g+ s* h: q& s) C* P/ r     /* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */) o: [" v/ E# Q
  }
0 X/ V/ }3 v- n# y# i8 _  return 0;2 t- P' _4 k+ @1 b2 J: n9 A
! P# l9 A) j# ~0 f
}' N7 i/ j4 Q- D3 f8 q
0 e4 S4 T+ R4 i7 n: ^
经过测试发现只能实现插与拔,但是无法具体到具体是什么设备。% J# D2 z$ }# _# e2 R; _" C
0 R$ N$ a# f% B$ T, a& i
3,使用mdev。
' \2 q0 E0 _- l0 J
; P7 E( C0 k  ]% Z+ r此方法相当麻烦,现在在研究中。
: {( S7 e  w7 t8 O, s6 _' H6 W3 l/ D8 Z
4,使用最原始的解析文件方式
6 [2 T4 N! P2 i$ l
/ J9 R6 i% ?9 E% S6 V6 [9 R此方法相当麻烦,生成很多文件。
; N. D* G! G7 L2 Q, e& \! Q9 X) H& n1 C
就是用cat /proc/bus/usb/devices的信息生成的文件进行解析。! |* M0 s9 `) Y1 ~

. p, z4 L9 G. e. s  B; t目前我已经完成此功能。虽然能用,但是效率太低。

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-25 03:23 , Processed in 0.156250 second(s), 23 queries , Gzip On.

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

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

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