- 在线时间
- 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,
& l- b) _9 R( c8 _8 U- N" USB ", " Mass Storage ", 9 _5 C; V- [1 n0 O0 h9 {
US_SC_SCSI, US_PR_BULK, NULL,
6 i( X' V# Z: o$ Q* ~" ^US_FL_FIX_INQUIRY | US_FL_START_STOP |US_FL_MODE_XLATE ) . H+ Y- X A# c; d4 G0 w
* w7 k# f2 x7 x J0 b& I注意:添加以上几句的位置,一定要正确。比较发现,usb-storage驱动对所有注册都是按idVendor, idProduct数值从小到大排列的。我们也要放在相应位置。
) R. i% l8 G/ L8 |+ Z8 k9 A最后,填入以上信息,我们就可以重新编译生成内核或usb-storage.o模块。这时候插入我们的设备就可以跟其他U盘一样作为SCSI设备去访问了。 % s" ^9 `2 u7 A% i9 @7 D# S1 H
键盘飞梭支持
1 b, r* v6 h# w. g2 p' G' T3 Q+ o目前很多键盘都有飞梭和手写板,下面我们就尝试为一款键盘飞梭加入一个驱动。在通常情况,当我们插入USB接口键盘时,在/proc/bus/usb/devices会看到多个USB设备。比如:你的USB键盘上的飞梭会是一个,你的手写板会是一个,若是你的USB键盘有USB扩展连接埠,也会看到。 5 f& ]1 @4 S4 W3 p
下面是具体看到的信息
3 D9 K, F4 P% c
4 ~% ^9 \7 n( L5 C. }T: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
' p9 j4 m v; |" JB: Alloc= 11/900 us ( 1%), #Int= 1, #Iso= 0
3 l" K- a: ~. J- |& y( iD: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 ) z0 b$ d( w- D9 ]- T* a) c9 E* q) R
P: Vendor=0000 ProdID=0000 Rev= 0.00
3 [2 U4 d+ t1 h, WS: Product=USB UHCI Root Hub * S+ R8 c. F: C
S: SerialNumber=d800 $ L; R6 f3 m' n8 L" J
C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA , R, S" Q k3 |
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub % `4 ]5 y* B* b* O0 H' Z( I% V
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
2 x: s5 y7 D, xT: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 3
. i' P4 V, Y# E0 Q: o6 sD: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 2 ^* r: y' ^, `# c# U. Z
P: Vendor=07e4 ProdID=9473 Rev= 0.02
* `+ j0 n- \' x) f. u, rS: Manufacturer=ALCOR
$ { g( [% E/ `6 i% }" US: Product=Movado USB Keyboard $ q! K) z$ |* W. M1 z. q
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA 6 y8 G. _$ c. o7 E( C* J. a
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub 1 a& q5 K! x/ N3 Q; v/ z. j, j7 s
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
J8 f, g2 u. I0 o& o找到相应的信息后就可开始工作了。实际上,飞梭的定义和键盘键码通常是一样的,所以我们参照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函数中 ' n' J' f$ Q* O( F# d0 w
' G2 N/ T; Z* Z5 A
FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, 8 F7 G& n- h7 D$ t# Z
usb_kbd_irq, kbd, endpoint->bInterval); ! N- }& X; R8 I- O4 g$ S1 `
8 b5 _8 s5 G! f' {9 X一句中实现。
! f* c" m# E2 t0 C H$ ~# v从usb骨架中我们知道,usb_kbd_probe函数就是在USB设备被系统发现是运行的。其他部分就都不是关键了。你可以根据具体的探测值(Vendor=07e4 ProdID=9473等)进行一些修改就可以了。值得一提的是,在键盘中断中,我们的做法是收到USB飞梭消息后,把它模拟成左方向键和右方向键,在这里,就看你想怎么去响应它了。当然你也可以响应模拟成F14、F15等扩展键码。
$ x5 a; S6 u6 I% ?. }6 [在了解了此基本的驱动后,对于一个你已经拿到通讯协议的键盘所带手写板,你就应该能进行相应驱动的开发了吧。
# Z& P! S' n" p2 m2 }( J程序见附录1:键盘飞梭驱动。 ) j6 ^7 L' `# \5 V, m
使用此驱动要注意的问题:在加载此驱动时你必须先把hid设备卸载,加载完usbhkey.o模块后再加载hid.o。因为若hid存在,它的probe会屏蔽系统去利用我们的驱动发现我们的设备。其实,飞梭本来就是一个hid设备,正确的方法,或许你应该修改hid的probe函数,然后把我们的驱动融入其中。 3 ]% m; s4 E- S6 Z% W" w F+ X
参考资料
% L' z4 q& m2 F; Y. @1. 《LINUX设备驱动程序》 & z2 J. T8 I7 S% C3 w: y
ALESSANDRO RUBINI著
/ h8 i- K4 R8 Y1 |9 Z# j( QLISOLEG 译
3 ~. W) W; P! I# h0 X2. 《Linux系统分析与高级编程技术》
+ F# N; g# n4 w. W+ f- S/ W) V周巍松 编著 " M/ N9 D+ ` w! Z$ c
3. Linux Kernel-2.4.20源码和文档说明 : Y" \- N$ G# X1 s
附录1:键盘飞梭驱动
# V) q4 Y( J) |# e5 ~) Y w5 Z
#include <linux/kernel.h>
8 H1 w z2 w5 p9 M#include <linux/slab.h>
0 m6 ]2 O$ Z; [#include <linux/module.h> ; a6 o& z+ W" S' V, W3 C) u. A
#include <linux/input.h> + p2 U- E' e9 t, h4 M% c$ ~
#include <linux/init.h>
9 K! h9 o: Y$ S! a#include <linux/usb.h> & ]5 @& j& W: _5 G m5 f& l% r3 R
#include <linux/kbd_ll.h>
0 v! Y3 J4 k5 j( q* L, y! y9 S$ C+ P" Q
/* & S/ P, N. m" Z9 z/ |
* Version Information * _& R; Y: t9 c/ q! Q ?- d
*/ , D0 R# i( F3 [& o; D# [* ~# `
#define DRIVER_VERSION ""
, B3 g4 Z; W X. q2 ]/ U#define DRIVER_AUTHOR "TGE HOTKEY "
, w$ |: e/ r$ H5 @8 J+ l8 T#define DRIVER_DESC "USB HID Tge hotkey driver" / [' `/ V7 Z( O0 e. |
" D3 b% u- {" N1 ?# Y7 C3 @( R#define USB_HOTKEY_VENDOR_ID 0x07e4
4 f2 Y, q4 n+ }6 K2 L#define USB_HOTKEY_PRODUCT_ID 0x9473 ; a$ i. |) z+ F3 F3 r! \
//厂商和产品ID信息就是/proc/bus/usb/devices中看到的值 ) e {6 C7 n. j J5 {; v
2 u- U* {4 @% k p+ G' @) B- H, a/ \
MODULE_AUTHOR( DRIVER_AUTHOR ); 0 [/ u! S; y- w+ _, Y* m5 g9 G
MODULE_DESCRIPTION( DRIVER_DESC ); # ?* e& s+ ~3 }% c4 a$ e. x! [4 K
* R+ `% N$ C* v( h* q' e. Estruct usb_kbd {
2 @7 q- @+ |# g' Hstruct input_dev dev;
2 _* ^6 }, l6 wstruct usb_device *usbdev; : }# j% C8 E7 E! z
unsigned char new[8];
6 Q) {1 ^! k( B4 ]0 lunsigned char old[8]; . A% y8 ~& k( a$ ~) S& ~
struct urb irq, led;
/ s1 {7 ~8 k9 J* Z) N( r6 D0 ?: W// devrequest dr;
( O$ V0 k; e3 X: E# W: m% d//这一行和下一行的区别在于kernel2.4.20版本对usb_kbd键盘结构定义发生了变化
! V( R: g6 }2 s3 J/ Y7 v8 g% v struct usb_ctrlrequest dr;
% T2 A( o; I$ x$ v0 T- ], C- \unsigned char leds, newleds; ) E( W. G' P" N# t0 T$ I$ \6 R4 _
char name[128]; . Y* C5 A* r7 K* \
int open; ; l6 U# p: j% Q, ^
}; " f5 W+ @6 I7 K" C& V
//此结构来自内核中drivers/usb/usbkbd..c 7 K0 f- D- a% b2 m
4 m( e; i& J3 R8 p. v% G
static void usb_kbd_irq(struct urb *urb)
8 O& h$ m- t% Y. F{
$ [$ i# o h5 }8 y, q/ lstruct usb_kbd *kbd = urb->context; % {3 l" F r8 D
int *new;
7 \* F- t4 e% i S new = (int *) kbd->new;
/ p$ _1 O- V6 s4 F% Z# F$ H! l. z3 k" e1 v2 z' {
if(kbd->new[0] == (char)0x01) ( T/ P. K$ H$ t8 D- L* t) ?. y4 j
{ 1 y3 ~0 {( T# [* T2 l1 y. F4 I$ b
if(((kbd->new[1]>>4)&0x0f)!=0x7) ; D0 l- F" ~& e( O5 ]( c
{ ( a( ]3 L, n, `( B- r
handle_scancode(0xe0,1); / Y" A1 D" U3 v2 W1 L
handle_scancode(0x4b,1);
! \( P8 I2 _1 G$ t% @' y handle_scancode(0xe0,0); ' a" T. Z$ i' z: [" n6 _! Z
handle_scancode(0x4b,0);
5 I/ i1 e$ u b$ G}
+ T- `( X' d" V( U$ velse / b G. [0 `& p Z$ P }$ F
{
" O3 ` P& Y% C2 ^7 X$ `handle_scancode(0xe0,1); " p- M9 N) \, o
handle_scancode(0x4d,1); ; B7 s4 G3 c9 v* L
handle_scancode(0xe0,0);
# |8 ~4 m5 b9 Q8 x3 Q) s4 ]* c- G: @' a handle_scancode(0x4d,0); . P1 S: A; a% I6 H
} 6 z3 |/ D: @# Q3 X! Z* V% x
} # E0 M# L) M8 j3 b$ c' V: O+ d9 O. N9 H" P
5 h5 \, {1 |8 m/ B9 y3 a: \$ H: Y! y7 r# A. [6 f
printk("new=%x %x %x %x %x %x %x %x", ' d# Y$ O5 G# U# _! z5 J* ]
kbd->new[0],kbd->new[1],kbd->new[2],kbd->new[3], 4 U( c$ K$ j) g7 e, f" o4 \: x
kbd->new[4],kbd->new[5],kbd->new[6],kbd->new[7]);
2 H4 B+ Y" {; @; o. Z$ Q
4 n# H- m- {7 w# n: l% l) y}
9 [% I, M; |6 [% v/ X- H8 |
/ w1 ]7 F: {) D1 o5 l8 `static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
1 Y- s& k0 N2 K7 A3 l; j const struct usb_device_id *id) 1 a6 d# A2 N7 Q- g& b8 e+ P) G
{
6 U3 b! s% m& U% rstruct usb_interface *iface;
/ l! O, i% E; ~% i3 Q struct usb_interface_descriptor *interface;
0 t# @3 o0 K' [- K: K0 tstruct usb_endpoint_descriptor *endpoint;
) @: k/ P6 D1 i$ T L struct usb_kbd *kbd;
% O! `6 p0 h1 G- p- I( v int pipe, maxp;
- m% a6 ~" K" j3 d- F) \+ O1 G. R8 x1 R
iface = &dev->actconfig->interface[ifnum];
0 J: k5 L/ `3 o+ B4 q9 E interface = &iface->altsetting[iface->act_altsetting];
: T& ?& i+ ~3 E* Q( _7 Y
, A5 E5 Z0 M$ p, ?' x* k# J6 |if ((dev->descriptor.idVendor != USB_HOTKEY_VENDOR_ID) ||
3 X2 v c4 a; d( _(dev->descriptor.idProduct != USB_HOTKEY_PRODUCT_ID) ||
9 L1 b) O( f( ~% R% `, x/ B D(ifnum != 1))
5 C e3 |0 \4 r+ E{
( t H/ w X0 l3 V; c! treturn NULL; 7 K% D2 R2 t F# o7 i! A
}
# G7 ?" h/ y% M6 ~( y5 P1 f& vif (dev->actconfig->bNumInterfaces != 2)
! O4 s1 ]$ c$ @8 K! @% ]+ k9 d5 Q{ + N- p" v$ ?7 h
return NULL;
# U2 U+ S9 n9 i" u9 Y} ! L* V- D) s: Z1 }
7 \- B7 _, i' h% @ ?" D4 Kif (interface->bNumEndpoints != 1) return NULL; ! k0 [3 J7 Q; a
. q& J5 B5 D7 e9 s% p% _3 Z& ]
endpoint = interface->endpoint + 0;
2 C2 W6 y) E. E
, W$ ?# Q4 |2 P, }4 ]/ {9 p7 J pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
+ b; x5 q" E, [2 Y* ^ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
. Y6 y3 d/ c6 {* [. y
" ^2 z5 {+ b# V! B0 h) i usb_set_protocol(dev, interface->bInterfaceNumber, 0);
% ~2 Y2 K2 A. ^& Q! N' S* D usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
% h8 f/ q2 X+ U$ J) g7 V
' t# o8 c% f2 N5 Q9 Lprintk(KERN_INFO "GU Vid = %.4x, Pid = %.4x, Device = %.2x, ifnum = %.2x, bufCount = %.8x\\n",
, ~/ P% m9 z! l2 |/ s; Tdev->descriptor.idVendor,dev->descriptor.idProduct,dev->descriptor.bcdDevice, ifnum, maxp);
$ J7 H. K- K% ]# j, D9 ~# L
' a5 J- q1 n5 B. i y0 I0 k0 ~ if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL;
/ P4 b% \* c% H5 [9 h& t, A( ~7 T0 ` memset(kbd, 0, sizeof(struct usb_kbd));
" H! ?0 J0 [7 L' ~( b& B
+ U, e: A+ v8 j8 g$ O% v kbd->usbdev = dev; & R! b0 ~3 M w4 Z o# b% A9 ~
- c* u9 u2 b) G7 y. R& h2 o9 ^ FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, . _% G! H/ U& [& Z
usb_kbd_irq, kbd, endpoint->bInterval);
' W4 P/ ~$ f. n; N: S2 i: [- T3 Y* M& S- ~
kbd->irq.dev = kbd->usbdev; 7 ` Y: _) V0 P. U, N% Z8 s) ^
" V9 X u6 \9 c# H: _
if (dev->descriptor.iManufacturer) 2 G' Z- u8 N# A
usb_string(dev, dev->descriptor.iManufacturer, kbd->name, 63); 3 E% l+ m3 V; w1 a
6 G" b1 H5 m" c3 yif (usb_submit_urb(&kbd->irq)) {
; e P5 ?9 B6 n; e" v3 E: }8 g7 Q kfree(kbd); / w( i7 P. }, `1 V! G3 `4 H! O7 _
return NULL;
9 v2 y, o0 l# W) R- s4 i' D, h& n }
; S& @& P: Q: X% f
% M& P: z7 k1 P- ^* {printk(KERN_INFO "input%d: %s on usb%d:%d.%d\\n",
( E, ], O6 U( [( i: i* M B& V; D2 B/ u kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum);
/ H5 m9 g9 P4 u% O; a2 O: e8 r) [8 b7 T" Y1 p
return kbd;
0 q5 i; }3 F- b4 F& M0 q2 |}
! v: f9 Y2 ]. s) i8 p- E, t, }* Z0 Q" D% e. ?8 P x1 b
static void usb_kbd_disconnect(struct usb_device *dev, void *ptr)
8 K: g: W1 P3 G" y* ^- O: r! s{
' z/ G9 B7 ?1 g4 g& D( I* Xstruct usb_kbd *kbd = ptr;
/ ^4 I/ r* p+ T" \* K* \ usb_unlink_urb(&kbd->irq); 1 Y5 ^# N) N& O- f4 O: Q4 s6 R
kfree(kbd); 1 B. L. V; B3 G
* y' C3 r% |+ Z9 F}
4 j3 _& s3 j4 i0 Q' z7 Z2 Z9 _3 H" G4 h2 ^9 x1 W
static struct usb_device_id usb_kbd_id_table [] = {
% P8 |. L* x, f" \& N{ USB_DEVICE(USB_HOTKEY_VENDOR_ID, USB_HOTKEY_PRODUCT_ID) }, " x7 V; k; V4 k' n! o0 s3 b
{ } /* Terminating entry */
$ \* n7 C8 @( C" f/ K+ K6 A}; % @. X) r+ h. N2 |( r v
. S# p2 Z# N& |: w3 P- W5 DMODULE_DEVICE_TABLE (usb, usb_kbd_id_table); 1 I& i+ }" `) }. V
: C) a7 r' t$ s) I7 E/ d' @
static struct usb_driver usb_kbd_driver = { 3 I2 B1 k$ f4 `1 W& P& J/ ^7 r
name: "Hotkey",
4 c- G5 A% \; Q" z" z# G9 X2 x2 J1 lprobe: usb_kbd_probe,
( P( ]7 Y" T9 z! {& ?% U/ M* |disconnect: usb_kbd_disconnect, 1 M: B+ c1 u! V7 a$ x' C& n6 e4 J+ j
id_table: usb_kbd_id_table,
% g' |: C O; l% k0 g4 UNULL,
& X+ q6 s' I* V, W( o, w}; ' {3 p8 @' k7 C9 P' |$ b
@! T9 e# {) u/ `/ e' Z$ _( ^) X/ istatic int __init usb_kbd_init(void) / ~" [& Y- v* p$ l( {. R
{
* I2 ~8 {8 m S; F2 b+ m0 yusb_register(&usb_kbd_driver); . F8 [ W J! N" a7 T; {2 F
info(DRIVER_VERSION ":" DRIVER_DESC);
3 C$ N, u) A; C9 ?6 [return 0; 2 V9 q) ?7 L& @
} D6 v* `% i& a6 m# j, m- Z9 Q9 ~9 |
5 V+ k8 M5 Y! ?, m2 I" U1 t$ _static void __exit usb_kbd_exit(void)
' D3 G: D7 h( Q5 Y% ?{ & T+ J n* a7 r8 @/ N' T8 M
usb_deregister(&usb_kbd_driver);
' ~7 R2 e0 Z, B0 N} - f8 }- U" C: i9 i
E* y* W ~7 Y0 {
module_init(usb_kbd_init);
2 q' H+ [- Q0 f4 s* e, bmodule_exit(usb_kbd_exit); |
|