|
|
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目前我已经完成此功能。虽然能用,但是效率太低。 |
|