- 在线时间
- 63 小时
- 最后登录
- 2019-5-3
- 注册时间
- 2004-5-10
- 听众数
- 443
- 收听数
- 0
- 能力
- -250 分
- 体力
- 10122 点
- 威望
- -12 点
- 阅读权限
- 150
- 积分
- -516
- 相册
- 6
- 日志
- 10
- 记录
- 10
- 帖子
- 2003
- 主题
- 1253
- 精华
- 43
- 分享
- 8
- 好友
- 1292

复兴中华数学头子
TA的每日心情 | 开心 2011-9-26 17:31 |
|---|
签到天数: 3 天 [LV.2]偶尔看看I
- 自我介绍
- 数学中国网站(www.madio.cn)是目前中国最大的数学建模交流社区
群组: 越狱吧 群组: 湖南工业大学数学建模同盟会 群组: 四川农业大学数学建模协会 群组: 重庆交通大学数学建模协会 群组: 中国矿业大学数学建模协会 |
3#
发表于 2004-9-27 14:33
|只看该作者
|
|邮箱已经成功绑定
UNUSUAL_DEV(07c4, a400, 0x0000, 0xffff,
) B! i! z8 m, u- w# N" USB ", " Mass Storage ", & A$ _1 s+ F, Z- V) H# U
US_SC_SCSI, US_PR_BULK, NULL, ( }. X% g8 z# G7 p
US_FL_FIX_INQUIRY | US_FL_START_STOP |US_FL_MODE_XLATE ) ) V* @1 I/ e6 t. O; v! c. ]4 u
) z- `: I ?' ?+ }% E. U注意:添加以上几句的位置,一定要正确。比较发现,usb-storage驱动对所有注册都是按idVendor, idProduct数值从小到大排列的。我们也要放在相应位置。
! S* r w, c& ?7 F; M% @7 G最后,填入以上信息,我们就可以重新编译生成内核或usb-storage.o模块。这时候插入我们的设备就可以跟其他U盘一样作为SCSI设备去访问了。 0 ?5 a. Z( L; L% V) ~6 z
键盘飞梭支持 0 H6 D$ a% I! z) Y2 h
目前很多键盘都有飞梭和手写板,下面我们就尝试为一款键盘飞梭加入一个驱动。在通常情况,当我们插入USB接口键盘时,在/proc/bus/usb/devices会看到多个USB设备。比如:你的USB键盘上的飞梭会是一个,你的手写板会是一个,若是你的USB键盘有USB扩展连接埠,也会看到。 9 B2 S, i. q" w {% {5 j/ ]
下面是具体看到的信息 - \0 x6 ~6 J% b3 _; Z- m
+ q% [2 I4 m- G8 }, |1 |
T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2 $ e) D5 P8 O1 Q7 Z9 [+ _. g5 U9 `
B: Alloc= 11/900 us ( 1%), #Int= 1, #Iso= 0
, k! n1 X: I" D+ Q7 {D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 ( O9 A! o! n. J' l4 x" o U
P: Vendor=0000 ProdID=0000 Rev= 0.00
+ Y, S( M) d J9 @! {: `5 D; E5 yS: Product=USB UHCI Root Hub ' u4 v: c8 N Q z' M! u2 @
S: SerialNumber=d800 # `% ~3 p E$ o( W/ O7 f0 v
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA . I* v( z1 `( w' F; n7 a5 z
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
x/ |* Y }9 b: I& D" f5 E$ pE: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms ' G2 f' ?* |7 b' L$ d' g) Y
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 3 4 x& O) R- r0 |/ n! ~2 }4 C/ s" Y
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 ; Y" r* d, G {: F' k
P: Vendor=07e4 ProdID=9473 Rev= 0.02
* w: |6 [ \$ @0 @0 U0 ?5 sS: Manufacturer=ALCOR
9 ]0 \' b1 l1 Z0 x8 B5 L0 TS: Product=Movado USB Keyboard
# r9 _; T8 j2 pC:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
" ^+ D/ x+ a6 o$ ]% q. FI: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub / z8 p* w2 c/ s6 s$ V6 J
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
! Y8 ?" F* x6 K2 I" B找到相应的信息后就可开始工作了。实际上,飞梭的定义和键盘键码通常是一样的,所以我们参照drivers/usb/usbkbd..c代码进行一些改动就可以了。因为没能拿到相应的硬件USB协议,我无从知道飞梭在按下时通讯协议众到底发什么,我只能把它的信息打出来进行分析。幸好,它比较简单,在下面代码的usb_kbd_irq函数中if(kbd->new[0] == (char)0x01)和if(((kbd->new[1]>>4)&0x0f)!=0x7)就是判断飞梭左旋。usb_kbd_irq函数就是键盘中断响应函数。他的挂接,就是在usb_kbd_probe函数中 / M; I$ d. j" [& i
, a5 u1 j1 q- o1 L, Q
FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, ) C4 X' `7 ?- A6 O9 N9 }
usb_kbd_irq, kbd, endpoint->bInterval); 4 l: ^( R9 x( w5 x# k4 ~
) A8 x+ S8 ]: u' |$ J
一句中实现。 : }# b+ P# |, C {& Y& F
从usb骨架中我们知道,usb_kbd_probe函数就是在USB设备被系统发现是运行的。其他部分就都不是关键了。你可以根据具体的探测值(Vendor=07e4 ProdID=9473等)进行一些修改就可以了。值得一提的是,在键盘中断中,我们的做法是收到USB飞梭消息后,把它模拟成左方向键和右方向键,在这里,就看你想怎么去响应它了。当然你也可以响应模拟成F14、F15等扩展键码。
; b& p/ `2 i3 D& E3 }在了解了此基本的驱动后,对于一个你已经拿到通讯协议的键盘所带手写板,你就应该能进行相应驱动的开发了吧。 7 A. n5 x1 g3 n6 [( U& d, k
程序见附录1:键盘飞梭驱动。 ( i. I8 [+ r2 U2 s6 j0 n
使用此驱动要注意的问题:在加载此驱动时你必须先把hid设备卸载,加载完usbhkey.o模块后再加载hid.o。因为若hid存在,它的probe会屏蔽系统去利用我们的驱动发现我们的设备。其实,飞梭本来就是一个hid设备,正确的方法,或许你应该修改hid的probe函数,然后把我们的驱动融入其中。
: k) z4 N* W4 S& r( _1 \参考资料
+ L2 u& _- N$ K2 e1. 《LINUX设备驱动程序》
, b: u7 ?3 a1 _) \( ] }% ZALESSANDRO RUBINI著
7 Y! ?- ?# D$ a6 \; z. | f. PLISOLEG 译 * T+ H; o r: C S9 K5 a
2. 《Linux系统分析与高级编程技术》 - Y$ ^% F& l0 N" k" y n. z/ R, V7 B
周巍松 编著
" e, ?8 u. p0 @ X# N& O3. Linux Kernel-2.4.20源码和文档说明 1 |; o# }2 @! ?7 n' {, i! l$ W. { V7 k
附录1:键盘飞梭驱动
: G- X3 R. d" t5 `
' O, d8 g# r' V4 p#include <linux/kernel.h>
: u8 \6 R8 ]7 q, [- Y#include <linux/slab.h>
$ F- @8 W2 u2 Y* w# i! M#include <linux/module.h> " d' \+ z1 A. w# B
#include <linux/input.h>
* j$ O+ ]( A% s& f+ p#include <linux/init.h>
2 i! B9 T9 O, ^, P#include <linux/usb.h> ( S, V$ X. N) ~% W6 j; E
#include <linux/kbd_ll.h> % m$ M4 Y. A% @
* x! U( l! g8 B( U4 z
/*
" B5 Y( b; |) k" `; j * Version Information
7 @8 }; \4 \( O/ D5 e) y% M! M */
3 U: A5 N$ \* x3 N4 A#define DRIVER_VERSION ""
- c" n& I8 G4 I! I! h* T3 I; R6 x#define DRIVER_AUTHOR "TGE HOTKEY "
* K: [$ Y9 H) F) Z#define DRIVER_DESC "USB HID Tge hotkey driver"
8 i( Y! @& V7 t
* y% |4 J+ x0 w#define USB_HOTKEY_VENDOR_ID 0x07e4
& S9 V. t0 C$ ?$ N, A; i#define USB_HOTKEY_PRODUCT_ID 0x9473 ) r+ c+ U2 o. i
//厂商和产品ID信息就是/proc/bus/usb/devices中看到的值 " E! ?0 G9 M. w( D# c, N! N
/ e$ W+ @2 T7 r1 g; b. v2 BMODULE_AUTHOR( DRIVER_AUTHOR );
$ E( E. M: [1 N: V+ OMODULE_DESCRIPTION( DRIVER_DESC ); % X0 B5 a" X f2 y$ a! ^* C
& g+ ~+ g# n6 T; i0 C3 u6 C# P! xstruct usb_kbd { K4 }- Q' ^6 i& T/ l
struct input_dev dev; 7 y i; _# `& S7 Q( _$ Q k
struct usb_device *usbdev;
+ m/ O- N) D' F( G5 ~. uunsigned char new[8];
! W6 {: ]8 C. J7 B- Bunsigned char old[8]; & A; W, r6 |2 D! @. @( b/ T% B' P& k
struct urb irq, led;
& R: n9 ~2 {& J* d// devrequest dr;
7 g V2 D! F8 p% k1 |//这一行和下一行的区别在于kernel2.4.20版本对usb_kbd键盘结构定义发生了变化
& v2 R) S1 x! s" x% }! Q4 ~ struct usb_ctrlrequest dr; $ _' I2 a# x ]5 u$ a
unsigned char leds, newleds;
" i3 ^2 g' @# fchar name[128];
9 Q+ X; X) @& y4 |; g4 i' zint open; + K; m% H0 q7 A8 ? ]: E9 I: D$ }
};
5 j# P; B% y, O4 v; A$ O3 p$ T//此结构来自内核中drivers/usb/usbkbd..c ! T' G; G6 B/ t* g
$ D |" M6 O2 h9 `: {$ I3 z
static void usb_kbd_irq(struct urb *urb)
$ Q* i. K* V+ N" k N{ 0 {( T. L0 X! M- U$ b# \. N" N% V9 ~/ [
struct usb_kbd *kbd = urb->context;
7 h9 J* P2 A/ `# [/ |6 E- Y. c int *new;
; S" b, _0 a9 \/ ? new = (int *) kbd->new;
" ^3 m! ~9 @" f1 Z3 j _! E, ~# L6 g( y# Z
if(kbd->new[0] == (char)0x01) % L/ u% {# N0 Y
{
$ U8 m) ` [. ?- x/ n1 sif(((kbd->new[1]>>4)&0x0f)!=0x7) + v0 D6 O/ R" S6 M/ r
{ ) ? ?, e8 ^) {8 n3 O1 ?
handle_scancode(0xe0,1);
/ |- b" o1 E3 r7 nhandle_scancode(0x4b,1);
* O" W1 h: k7 H7 ~ handle_scancode(0xe0,0);
) g, k9 }0 K; \; @% n" r7 j4 I handle_scancode(0x4b,0);
1 X4 `2 C+ d& V! N- P" ~} - B7 y3 [1 j/ v. B0 O
else
. Q& H1 U6 z1 U2 b3 g{
4 I2 c# q2 k$ e6 o% zhandle_scancode(0xe0,1); 9 d! \2 |( N* N
handle_scancode(0x4d,1); . ^! x1 L3 m+ R* a4 F/ x
handle_scancode(0xe0,0); 9 J9 i- Q- z: B& |
handle_scancode(0x4d,0);
$ Q7 Z4 P5 t7 P$ L: H7 k! Q}
5 J7 V1 q& ?1 \ f6 ~/ S}
/ x' u4 P3 z( y
0 f0 n% n" | p; j: ^0 U5 X6 G+ {. X$ J$ H$ _$ T: X' z
printk("new=%x %x %x %x %x %x %x %x",
b) o- ` ?8 L0 D% U1 o: |kbd->new[0],kbd->new[1],kbd->new[2],kbd->new[3],
# j( c* o. i1 @kbd->new[4],kbd->new[5],kbd->new[6],kbd->new[7]); + y$ I. ]) ^ X: l
; U" e/ |8 L! H
} ) ~# t( l# h/ @' v; Q+ L5 b
8 Y4 v. m0 `+ I Z7 X( x2 \& Ustatic void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
5 t; `( \2 z2 u5 {, }; i const struct usb_device_id *id)
$ T g, I; e$ g{ ; Z3 N+ c4 I5 K
struct usb_interface *iface;
- k/ c. A2 g9 P* W struct usb_interface_descriptor *interface; : C( J t) h; b! r& C9 L
struct usb_endpoint_descriptor *endpoint; , V+ T% J9 c! `% q% v4 p$ r" k
struct usb_kbd *kbd; % c( e) ]' {) O# T
int pipe, maxp;
, i+ ? }8 H1 Q4 I( Y8 e6 p& q- {2 }. {) @: q5 l* Q0 c" v
iface = &dev->actconfig->interface[ifnum];
_6 b' J& ]' X. g5 x interface = &iface->altsetting[iface->act_altsetting];
u" g( j7 H/ u: ?6 o" |1 R" b3 n$ O1 e
if ((dev->descriptor.idVendor != USB_HOTKEY_VENDOR_ID) ||
. o/ l7 [# m" j4 F; X; f, S: Z(dev->descriptor.idProduct != USB_HOTKEY_PRODUCT_ID) || / Y, t6 H9 Z. J* ]
(ifnum != 1))
4 C' l! _; k; F8 h# N* X, R9 V{ 0 W5 g2 x5 p6 F
return NULL; 4 k2 k( n% w$ F3 D- M3 B- P
}
2 D2 N/ s8 q8 f- J! D6 u1 mif (dev->actconfig->bNumInterfaces != 2)
& H, h1 Y5 q5 Y4 |{ $ N6 U6 |/ n7 K5 z( l* f2 o
return NULL;
" |& t0 M; Z/ o# |" p9 q}
/ m! I# A7 V+ l. n( R" d, b; O& Q. t
if (interface->bNumEndpoints != 1) return NULL;
/ ^' r5 [. ], G/ E3 E
* R" }$ j6 i" E2 y endpoint = interface->endpoint + 0;
4 l" l( J. J% O
7 U9 b! _8 Z% ^7 L# N9 C pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); 6 s5 @3 z+ r. K& @: A; i) k3 L
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); 6 S, K1 }; r9 s. }( G0 t3 ^
4 C/ Y+ p1 r, r3 d9 I usb_set_protocol(dev, interface->bInterfaceNumber, 0);
- u, `- R G% F3 [5 P/ L) o usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); 6 b/ C- W5 B0 W! _' d0 f) \/ w& b
. Y) l4 u6 E! |- N, Bprintk(KERN_INFO "GU Vid = %.4x, Pid = %.4x, Device = %.2x, ifnum = %.2x, bufCount = %.8x\\n", 7 n; M1 _' v5 e1 c, s3 ?% o
dev->descriptor.idVendor,dev->descriptor.idProduct,dev->descriptor.bcdDevice, ifnum, maxp); # ~* {+ h; [/ | \) g
; z! }& \& H" y if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
6 I: ~! ]! G; \3 c memset(kbd, 0, sizeof(struct usb_kbd));
- `& K8 N! p, y( j; z, R! m7 z5 ~2 N; O; z& x R1 c8 [8 V. i3 }5 J
kbd->usbdev = dev; A# M" o- b4 m9 m9 l
% H3 q3 ?& ?* Q) K6 t
FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp,
[; l. `8 x( u9 c4 D$ a( I8 A ausb_kbd_irq, kbd, endpoint->bInterval);
& u+ A7 `$ _* |7 L# U$ v0 V+ t7 r, w* Z% E& c9 `" d
kbd->irq.dev = kbd->usbdev;
; c8 Y1 d$ q& M8 }" b8 x; f! Z V; N6 Z i6 ^8 j/ u
if (dev->descriptor.iManufacturer) 4 X; e0 t$ e& A" L7 w; g
usb_string(dev, dev->descriptor.iManufacturer, kbd->name, 63);
- P* b: Z( U8 j2 D
( X7 c% I [' {/ Q. }) Vif (usb_submit_urb(&kbd->irq)) {
9 \, ?4 f/ r, a8 w( L5 l' w kfree(kbd);
! E4 B7 T/ B% i5 N return NULL;
6 [( E9 ?7 ], d4 g4 y Y }
6 z& m) s* ~2 Q8 s$ x3 B. r0 K X q5 T
printk(KERN_INFO "input%d: %s on usb%d:%d.%d\\n",
0 {! [2 Q x2 l- o. ~9 K kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum); + S6 u; b. n5 I$ E( n! A
* a/ o/ e0 C J! e9 x4 ^ return kbd;
, W+ }7 M+ p$ @, j% L+ D3 A( [}
I! K, Q' d$ T6 M2 x: N( m+ @6 Q+ F2 [, r
static void usb_kbd_disconnect(struct usb_device *dev, void *ptr)
# S" Z% n/ \/ I9 m& n{
+ ~' G* X% Q" d* n/ ystruct usb_kbd *kbd = ptr; . C$ m1 Z( G: R4 c
usb_unlink_urb(&kbd->irq); 2 s* `5 i O; z# _. w6 N) H7 e# T, @( |
kfree(kbd); " G6 Q8 M1 }0 }) p$ o- P) E
" M# Q1 Z \# g9 [) `8 D
}
/ V1 c4 v; U% n& i5 i' u% v4 N% _% x" T7 y3 T
static struct usb_device_id usb_kbd_id_table [] = {
3 z& r' W) F4 C! \" c* M& Z{ USB_DEVICE(USB_HOTKEY_VENDOR_ID, USB_HOTKEY_PRODUCT_ID) }, 4 N$ i- H4 n! y) C# E) y" L3 K9 n
{ } /* Terminating entry */
6 m9 }8 |. U, n, c! m};
- P4 \/ _4 H4 s* J4 n% G# U' g- g% Q/ i
MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); : c6 T" a1 Z) T9 j7 F
. D |! ^! _9 ystatic struct usb_driver usb_kbd_driver = { 2 H9 R6 b w4 F1 Q8 W0 a0 O+ B
name: "Hotkey", _) @) h* \6 L, k# l2 k S6 K
probe: usb_kbd_probe,
9 c) K4 [* A' n: U$ qdisconnect: usb_kbd_disconnect,
" W) A2 @0 U4 G1 C& n! i$ F6 pid_table: usb_kbd_id_table,
4 D& i0 e( g/ \NULL, 3 Y& _5 Q8 E+ n1 F& N5 r3 X
}; 8 H- r6 s4 {- X0 n8 c
' Q& ^7 m5 Q7 B* I8 sstatic int __init usb_kbd_init(void)
4 X7 z, g2 H' l- K0 k* x{
7 g$ T" j' o# ]1 ]5 K- yusb_register(&usb_kbd_driver); $ o% o; z, A( m( c
info(DRIVER_VERSION ":" DRIVER_DESC); 7 }) ^& ^/ g0 P4 W. ^) W0 B1 k
return 0;
2 _: u; @# j3 `8 M3 J, }$ w: h}
! _- H/ [7 S( ~6 Q% w) }9 w
' z# X% m0 {% y2 ^. K1 S' ostatic void __exit usb_kbd_exit(void)
4 ^( [, z$ a! T{
8 y2 f7 A8 T- X$ f/ ^+ p0 ]' zusb_deregister(&usb_kbd_driver);
( S ]' [3 y! V* p$ {6 G} & y; e/ i- _& b# q' o/ \ l
% [# n. G0 N3 e* G# Z2 i; I) v
module_init(usb_kbd_init); & E5 r6 N1 q7 i# G5 r
module_exit(usb_kbd_exit); |
|