|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
0 H3 n3 l$ Y" j/ P) S目前要做一个在嵌入式平台上的USB口的热插拔事件。
2 p( h3 A, n7 a; E4 s* ~8 v9 h% X X, P
经过我现在的分析总结目前有如下方法:+ w* _9 L3 T5 a1 c
1 V+ d5 P2 i/ q H; u
1,定时检查/proc/scsi/scsi文件
: M, q- |5 E# n6 `' h6 |& H: M& G8 e/ }1 m
此方法只能在PC上,但在嵌入式平台上不可用。& b0 J# w) }* H
& f( z: b1 u" ?! _3 \% d/ q2,netlink方式( I% N) n. V1 h# d: ~! |# l: {
& N9 A _5 R9 @使用netlink.# E8 X! t8 j6 T9 u' h \4 ?8 Q
# a- _3 Z3 e' G# w
#include <stdio.h>0 J2 f5 A9 x u
#include <stdlib.h>
, f6 w0 ?: O7 @* x4 ]( ]; N#include <string.h>' Z6 s0 K+ h" ^% X5 Q! {; x2 n
#include <ctype.h>% v/ y1 b( j9 N! B7 w4 I4 a% Y
#include <sys/un.h>
( b. m! V' u! T. ~( u( t) a#include <sys/ioctl.h>
% N1 e o. m, z& x% @/ A C$ `#include <sys/socket.h>
4 S. R* w z0 k5 [! g/ k/ x- r1 j#include <linux/types.h>/ B1 M. W. o) E# w* t
#include <linux/netlink.h>
7 ?( p' I: G/ S#include <errno.h>/ J+ ^; ^# r* x* H! t( ~; a8 W
#include <unistd.h>
* q' b+ L2 }1 S8 n+ M R w2 j E#include <arpa/inet.h>
+ Q0 s' m3 Z+ h#include <netinet/in.h>
8 g/ d* J6 `8 x; G: l( u# {$ [3 L. n" a4 r9 W& v3 w. {
#define UEVENT_BUFFER_SIZE 2048
8 @' ?: ^0 u( i1 y9 [8 U0 } Y9 C1 ~7 T M1 Y3 E
static int init_hotplug_sock()& o- z3 q9 [0 d A$ J
{1 m% ?2 L4 X3 D- d
const int buffersize = 1024;4 t5 S( X) R8 D6 H
int ret;! ]& s- `! @' d F2 [
& i# b$ t3 Z5 Z
struct sockaddr_nl snl;/ F, |5 s1 S( I1 ]
bzero(&snl, sizeof(struct sockaddr_nl));0 E/ `. w4 i3 R- W. N' H- R6 b
snl.nl_family = AF_NETLINK;# V2 d% I1 c$ r8 A- U# w
snl.nl_pid = getpid(); i$ W: s3 o5 V$ k- t
snl.nl_groups = 1;
4 V7 _8 ^) ^5 i- } Q1 [
# {, i; B3 q3 R' O* @( Y5 \8 X6 E) r3 ~ int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);$ _5 `4 J6 Q* ]7 g& W
if (s == -1) ^8 S1 M6 G7 n1 i; b& k- M
{
# \: ~0 ^4 d6 b3 o0 j5 e perror("socket");. h4 z- P* W8 C5 C# \# G
return -1;; w. O9 _! ?8 `! C
}
+ f3 T j2 |0 k+ [; h" s9 L( v setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize));. n) c% s5 Y, U8 m& P7 @% o
4 E2 Y& F! T/ O ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl));
9 z. R* l# V3 _$ [# L1 v4 w if (ret < 0)' {$ G0 O: |1 B( D- M) _& l
{
* O& V: C5 h$ P8 U perror("bind"); R% H3 e: i8 U; d \7 F
close(s);) L; G+ r: Z6 i6 z; |
return -1;4 g3 B# W4 K: Y3 T- ^
}
% Q/ z) {9 Z- a# C6 E0 k) a- y: B7 k# Y! J: n7 B
return s;
$ o$ D* s7 X3 X+ q}5 J( @) C+ R. c: B* g% M' |1 A
7 k8 o% Y, C) E/ {/ w
int main(int argc, char* argv[])' \4 w4 a6 T0 V; A& D
{
' B: S0 A/ n& N, |: x- V int hotplug_sock = init_hotplug_sock();+ A, u. n# Q% j/ f) i% Q w
O. I6 _$ v- @
while(1)- L2 d3 T% d1 }
{/ m, P0 s* z$ t/ p) }- d0 R) }
/* Netlink message buffer */( [2 `) [0 P3 u0 \7 U9 L. {& e' o
char buf[UEVENT_BUFFER_SIZE * 2] = {0};: I6 n: D+ w# g8 r+ r" K% K
recv(hotplug_sock, &buf, sizeof(buf), 0);3 q$ o, S0 ^0 i* Y, R9 R4 s5 \6 E. n
printf("%s\n", buf);& D% x: O3 T4 W/ m- |
: q" O) M1 P7 C% }# ^$ J
/* USB 设备的插拔会出现字符信息,通过比较不同的信息确定特定设备的插拔,在这添加比较代码 */
C8 U! H, D% F }9 N6 V& q! ?8 i* y
return 0;# r9 I/ N0 O% q+ K
/ U2 b) T% `: I}
+ g, m) t, f7 e2 e- h4 Y' _
% a, x7 R) h5 u) h, i经过测试发现只能实现插与拔,但是无法具体到具体是什么设备。
+ a# K, v5 |3 i; l
- n8 o1 r, u/ r) J8 U3,使用mdev。
. t4 n7 j1 P3 Q9 C r) E" F3 }5 j G% j \5 ? [) S" v2 L
此方法相当麻烦,现在在研究中。
) D9 J3 K R0 i: K, [% w
- g' z; ^4 @; H4 S: w& ^. Y4,使用最原始的解析文件方式
" L% G) x) U8 V B1 h' a* U6 S& I" _6 m A9 A
此方法相当麻烦,生成很多文件。' ?, E9 O! q6 U& ]7 b) m
6 ~. s8 J5 T C
就是用cat /proc/bus/usb/devices的信息生成的文件进行解析。
( @, x, Z/ V e4 U5 Y4 U4 V
( q0 U' g9 S: @* Z5 C6 t. L: z目前我已经完成此功能。虽然能用,但是效率太低。 |
|