- 在线时间
- 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,
/ s& H! |- j. I" ^4 ?! r! C" USB ", " Mass Storage ", 5 [7 B+ o `; ~$ S* [
US_SC_SCSI, US_PR_BULK, NULL,
$ x3 V% {: L! }! ?7 c0 JUS_FL_FIX_INQUIRY | US_FL_START_STOP |US_FL_MODE_XLATE ) ! g. P* s% x. e* H
' o; x% Q( S3 N
注意:添加以上几句的位置,一定要正确。比较发现,usb-storage驱动对所有注册都是按idVendor, idProduct数值从小到大排列的。我们也要放在相应位置。 1 V7 Y/ F5 q7 t( b: S
最后,填入以上信息,我们就可以重新编译生成内核或usb-storage.o模块。这时候插入我们的设备就可以跟其他U盘一样作为SCSI设备去访问了。
5 U. B3 h6 _6 K' O0 Y C' B键盘飞梭支持
* O& x- ~; j; E; l/ c8 c目前很多键盘都有飞梭和手写板,下面我们就尝试为一款键盘飞梭加入一个驱动。在通常情况,当我们插入USB接口键盘时,在/proc/bus/usb/devices会看到多个USB设备。比如:你的USB键盘上的飞梭会是一个,你的手写板会是一个,若是你的USB键盘有USB扩展连接埠,也会看到。 - z; F/ P" Y; Y
下面是具体看到的信息 . Q: y" K* X/ ~: f, Z
5 t9 j5 q- O$ v" g# R; pT: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
% h* f0 Q( d2 l1 V h3 _9 P1 nB: Alloc= 11/900 us ( 1%), #Int= 1, #Iso= 0
+ o/ W% X2 i; A2 H8 V. \D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
; x' h9 S4 f& J- d. R$ C3 ~2 Y" xP: Vendor=0000 ProdID=0000 Rev= 0.00 * k% {3 L4 G1 [: Q) }7 s4 w. ?$ k$ X
S: Product=USB UHCI Root Hub
/ q6 R) y3 S+ R% c- k/ rS: SerialNumber=d800
7 u: ^8 v( m7 T- H/ {8 ]$ BC:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA x9 }* o, m! a5 W
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub 8 l& Q2 f4 a# y8 z0 S
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms . ~* h( z; L% ]( n7 e% U
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 3 / r# `1 u$ P; y4 g
D: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
( Q o$ U1 u5 n2 F* a; V4 n( ^P: Vendor=07e4 ProdID=9473 Rev= 0.02 ( o: V/ v/ T3 O0 Q4 E E
S: Manufacturer=ALCOR * K4 i7 d$ o7 w/ X' h9 Y
S: Product=Movado USB Keyboard . C4 w3 w- c: x( ^3 F1 h
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA % J: \# [, e3 [( C% J' ]
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub
\, _' N) U, ~6 Z* J: }E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms , m' A$ Q7 y3 _3 g6 _4 g" J
找到相应的信息后就可开始工作了。实际上,飞梭的定义和键盘键码通常是一样的,所以我们参照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函数中 " x* w7 S" G7 d( I) d; n1 y, D, E
. X1 M' S' _, b; Y5 A' W ^0 FFILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, 8 L. j6 e7 F3 e! G
usb_kbd_irq, kbd, endpoint->bInterval); " H6 _5 V: m1 ^. L
l% ~. p8 M+ N; }0 [( I一句中实现。
: r0 U* Z# i9 U, O% k' ~7 k从usb骨架中我们知道,usb_kbd_probe函数就是在USB设备被系统发现是运行的。其他部分就都不是关键了。你可以根据具体的探测值(Vendor=07e4 ProdID=9473等)进行一些修改就可以了。值得一提的是,在键盘中断中,我们的做法是收到USB飞梭消息后,把它模拟成左方向键和右方向键,在这里,就看你想怎么去响应它了。当然你也可以响应模拟成F14、F15等扩展键码。
2 }9 R6 N* r' t" @$ Q' ?7 D在了解了此基本的驱动后,对于一个你已经拿到通讯协议的键盘所带手写板,你就应该能进行相应驱动的开发了吧。
; ?( T5 x7 \5 R( x$ T7 F程序见附录1:键盘飞梭驱动。 3 V5 n7 @( w# ?) y, c
使用此驱动要注意的问题:在加载此驱动时你必须先把hid设备卸载,加载完usbhkey.o模块后再加载hid.o。因为若hid存在,它的probe会屏蔽系统去利用我们的驱动发现我们的设备。其实,飞梭本来就是一个hid设备,正确的方法,或许你应该修改hid的probe函数,然后把我们的驱动融入其中。 " k$ b/ L4 ~6 F, o4 J
参考资料
' w; O0 k& i' B/ w6 a1. 《LINUX设备驱动程序》 , ~1 G6 u5 Q6 z2 h% c
ALESSANDRO RUBINI著
- S9 t. g( }" R6 R, kLISOLEG 译 , d- }8 a5 ?2 E, w
2. 《Linux系统分析与高级编程技术》
4 u3 V5 K' g) {% k1 U; F M" S周巍松 编著 : U3 H* A$ s) J$ A& F
3. Linux Kernel-2.4.20源码和文档说明
5 a, h8 k* t K4 W8 _, |3 }附录1:键盘飞梭驱动 2 C" c% B' `6 L+ T" H& @1 L* f
6 N* R7 ?' ~. o
#include <linux/kernel.h>
4 p6 ?$ M7 o7 W) Z#include <linux/slab.h>
- }4 {& Q7 K3 ~0 _& D#include <linux/module.h>
; g" Y# P. r. I: c% R#include <linux/input.h> 5 i, w$ P7 V% y: T7 a$ s9 W
#include <linux/init.h>
$ Z: F# R/ t) y6 i4 e#include <linux/usb.h> {; k' p2 Z3 Y5 ^& M
#include <linux/kbd_ll.h>
v* }& E( ?8 Q, s& ]1 }8 I5 ]+ e& m2 D0 t4 b4 `0 N
/* $ e9 Q- t& W$ _. g/ w
* Version Information , z! n9 K7 J6 p8 S
*/ ; L% X& K0 S" ~$ }) v' _5 O
#define DRIVER_VERSION ""
6 V2 F4 f! n9 m3 Y5 f0 V5 `# r#define DRIVER_AUTHOR "TGE HOTKEY "
! A% Q% P' X* s, O#define DRIVER_DESC "USB HID Tge hotkey driver" 4 x0 ?. I- Q( }) U% [+ e2 j
# R# E* g+ {. p& i0 F) q. y6 J
#define USB_HOTKEY_VENDOR_ID 0x07e4
5 d H7 E& s1 o2 p& Z- v) k#define USB_HOTKEY_PRODUCT_ID 0x9473
* q& L6 B: h% c n" M//厂商和产品ID信息就是/proc/bus/usb/devices中看到的值
! A+ ~. m4 J/ T6 u: U& l+ v9 j) ]# d' H: H% m7 a
MODULE_AUTHOR( DRIVER_AUTHOR );
3 D9 ?6 a6 f) ^ O2 P* x4 ]! j% ?+ yMODULE_DESCRIPTION( DRIVER_DESC ); ; w" v0 |4 r: e2 Y( c3 J
) Z( T' ?- b& x7 Q$ Xstruct usb_kbd { " p( s8 _# R4 r
struct input_dev dev; ! z1 @* s, F7 _2 x$ z
struct usb_device *usbdev;
) |% Z% B, ]& |. m$ Iunsigned char new[8];
# `1 {" G, |- s6 [/ Nunsigned char old[8];
0 O" s* c! _' V! h, n0 ~struct urb irq, led;
4 q& o$ _, X; u% l/ H y8 r// devrequest dr; 8 O) L( E; f e9 p" ~
//这一行和下一行的区别在于kernel2.4.20版本对usb_kbd键盘结构定义发生了变化
6 R0 A r/ _* `- k struct usb_ctrlrequest dr;
3 s8 @& n% I: a4 Q3 N, Q1 M' [' ~unsigned char leds, newleds; ( M' Z9 I- |% p, b L2 a% Z8 _8 L# l
char name[128]; 2 q: D2 B( v: n% _3 K3 e2 ^! E
int open;
. k' y& s) O$ p! W3 T5 J}; " H" P8 m1 R, D% s2 q
//此结构来自内核中drivers/usb/usbkbd..c
1 G; G, W B) t1 [- ], x$ E/ `$ X; `6 s8 i4 E. C% D! u. V6 j! k' ]
static void usb_kbd_irq(struct urb *urb) . F$ k* n9 @* _! P3 [" t
{ ; q& e* H8 T$ J0 R: N+ G
struct usb_kbd *kbd = urb->context;
* l! m; B# _/ h8 _ int *new;
( @# ], A; P: }9 c8 N new = (int *) kbd->new;
3 _3 Y. k7 D% I, ~# C" O" z6 z: ?. e) R& ^$ r# c
if(kbd->new[0] == (char)0x01)
! I3 S# k3 |/ z, o{ 8 G5 d9 h4 c) I. b! `$ Q
if(((kbd->new[1]>>4)&0x0f)!=0x7) # Q& d+ d" s' I r' _5 j( A( \7 |
{
# D- T% @ W: V- k0 Ihandle_scancode(0xe0,1);
2 t: g9 h" N8 o+ U: s8 ? ahandle_scancode(0x4b,1);
5 S8 E4 d) r- m2 [* }% U handle_scancode(0xe0,0);
) a: u4 c. O- _$ b handle_scancode(0x4b,0);
: L3 T) e0 q: o8 W) c( n; y! L2 I}
" `7 \1 ]9 p5 C2 R4 H1 |else 9 i7 f+ _/ H# [. i2 k
{
9 e g Q0 K) ]7 }* rhandle_scancode(0xe0,1); ; @1 r) X) U9 \& b
handle_scancode(0x4d,1); ' Q @6 t5 E0 t* I: `. \$ U
handle_scancode(0xe0,0);
$ f6 K! T% Q8 f% g7 Y' q: s/ l# \ handle_scancode(0x4d,0);
( p& Y4 P/ o7 F. ~+ w$ }# A}
: m0 E' c: {' T} ( j. u2 L% @! |) l8 E% }% A- {
7 ~2 q8 s9 L/ |$ ~, ?% |. Y6 u, u3 L# K' S/ i' `
printk("new=%x %x %x %x %x %x %x %x", , R, E& p2 ^+ H3 k( J4 X j+ Q
kbd->new[0],kbd->new[1],kbd->new[2],kbd->new[3], ( @: w4 x; _9 E! l
kbd->new[4],kbd->new[5],kbd->new[6],kbd->new[7]); 9 T( A" D# S* a% u( c
0 b& U+ k4 g( j6 t1 B$ c7 Y8 a* M
} 8 M w2 V; j. u/ Q
- j7 N- w: a2 R$ ~% B" K2 {static void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
; x! d9 n5 j# [9 | const struct usb_device_id *id)
( f) O! k e" k; y* L( [{
9 A% N" [$ C1 }' g% tstruct usb_interface *iface;
' H i% t; }2 ~ struct usb_interface_descriptor *interface;
4 }& U6 d- u3 n. [: E5 mstruct usb_endpoint_descriptor *endpoint;
# d1 x) ?, ~3 W6 ? struct usb_kbd *kbd; ; ~% T7 N% w) l2 C7 ?9 a' ?
int pipe, maxp; : S1 n# r5 U* b
s( c! e/ A: a; I+ V
iface = &dev->actconfig->interface[ifnum]; ' H$ ?; d. }( e3 z0 M
interface = &iface->altsetting[iface->act_altsetting];
$ C) d! f( V% C) X, k
4 ?8 f. l. O) w& }$ l3 u1 V$ D+ v0 Rif ((dev->descriptor.idVendor != USB_HOTKEY_VENDOR_ID) ||
% Z, l1 ^% n7 ?0 N, ~0 j(dev->descriptor.idProduct != USB_HOTKEY_PRODUCT_ID) || : Q4 c2 v: c# U7 l
(ifnum != 1)) Q* ] c7 S0 V+ d: P2 c
{
4 u1 N9 p" N6 m/ Jreturn NULL;
; D0 c3 K4 h; X! z4 G$ |}
/ n" m6 ~6 w5 W0 _2 aif (dev->actconfig->bNumInterfaces != 2)
; g$ _5 p0 H& a/ Z u' H{
4 b% o' K$ Z' u- \0 treturn NULL;
) f7 f' S* G! s$ F' S/ j}
) d( ^' p. `/ O5 s" V) {
1 {5 \% Z# M1 Qif (interface->bNumEndpoints != 1) return NULL;
- R. w) a: m/ b! y* U5 P9 ]$ P& K3 @
endpoint = interface->endpoint + 0;
3 v5 y& `; |. k8 }" u
( `" a! |! j8 f8 ? pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
2 H5 ^4 `" H5 Y maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+ V$ f6 b2 u: d7 |- A% Q! u ~5 I1 H1 | E: _: ?8 \
usb_set_protocol(dev, interface->bInterfaceNumber, 0);
8 u/ P" n( z! P usb_set_idle(dev, interface->bInterfaceNumber, 0, 0); ' b5 @0 o% o' ~( ^
) n3 u! |9 \ U$ u* r0 ?
printk(KERN_INFO "GU Vid = %.4x, Pid = %.4x, Device = %.2x, ifnum = %.2x, bufCount = %.8x\\n", 6 C0 Z2 P- Y# X# E
dev->descriptor.idVendor,dev->descriptor.idProduct,dev->descriptor.bcdDevice, ifnum, maxp); / X# z1 T+ P, m# l. B
9 i7 A: O3 Q$ C r/ f if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; " a N$ ^. H4 v2 Y$ \# t3 P7 ~; j
memset(kbd, 0, sizeof(struct usb_kbd));
2 S N0 t: U! P1 D& u/ f6 f8 f* G' v) t n* x& s+ ]/ ^3 M7 y
kbd->usbdev = dev; 3 |6 X n- X- n* l0 X! x% |% t
" @4 z, D' E6 h/ j/ d/ D' W FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, 2 {" o% y+ x, F2 s
usb_kbd_irq, kbd, endpoint->bInterval); & B6 U! t3 Y' }6 i: m
% e& `0 P/ w4 Xkbd->irq.dev = kbd->usbdev; 2 \5 k5 }; @% ~( T
# k7 a2 `% m9 y( j4 mif (dev->descriptor.iManufacturer)
) _2 p3 p# h& Q6 u g |1 p/ M usb_string(dev, dev->descriptor.iManufacturer, kbd->name, 63);
; E9 _4 C$ h+ I* _* S# H* N
& T9 X" K1 C7 `* g! s; H2 S) s; xif (usb_submit_urb(&kbd->irq)) { 2 [% J' E$ s8 g6 K( m' z: G
kfree(kbd); , c8 \ X% Q! t
return NULL;
# `7 @9 X1 q+ ]- [ I } , |9 e W. J3 T. J, m' b
( @" u# V6 s3 s. j+ b3 xprintk(KERN_INFO "input%d: %s on usb%d:%d.%d\\n", , U K2 `, o& {+ ]2 Z9 C( b& @
kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum);
' c8 v! n6 j6 X6 w9 G Y1 M; S& i
- n$ y' G V* k1 {) ]$ N, L return kbd; 1 [) ^9 n3 G9 n# G9 w: o( L
} 0 Y' l- x$ I$ C
, r: P* `+ M, C6 @0 dstatic void usb_kbd_disconnect(struct usb_device *dev, void *ptr) / w3 M( b* [3 g9 @" T& @& u# l
{
Y! {( u1 t5 ]: Z( S: p- z5 q( ostruct usb_kbd *kbd = ptr; % b/ h' c/ g4 G
usb_unlink_urb(&kbd->irq); ^/ Q1 C* B4 L9 F3 G
kfree(kbd);
/ ?) l8 O$ \' i" [
; b! b6 \9 d; ?' B} # n5 {& P+ X' Q. E, J, s
- f: p+ l+ B# N6 c( m3 Xstatic struct usb_device_id usb_kbd_id_table [] = { 2 E& M" R h/ Y; o2 x7 }
{ USB_DEVICE(USB_HOTKEY_VENDOR_ID, USB_HOTKEY_PRODUCT_ID) }, ! r3 I' }* d2 T) G
{ } /* Terminating entry */ . {/ S1 B+ \' p# z$ r3 j
};
+ v, ~- ^% ]( [( G1 o$ g- E% P( o
MODULE_DEVICE_TABLE (usb, usb_kbd_id_table); ]& ]! G# Z9 T% C1 z$ a& S- Y
# y3 [% h3 n! t! A [' C6 h5 {static struct usb_driver usb_kbd_driver = {
& F* T* Z: ^3 V& ^' f5 Z6 F0 d3 Uname: "Hotkey",
0 F7 M t+ ]; E, }8 C1 jprobe: usb_kbd_probe,
$ T6 \, C& n5 @disconnect: usb_kbd_disconnect, 6 y, i' \& I, t% Z' ^. p0 g
id_table: usb_kbd_id_table, 3 d; _4 z7 @) g; \ \$ @+ h
NULL, 1 B) ]: S! D n) x, n
}; . h2 _5 m! Q) K3 J3 S% k6 g8 W
; P) W6 _" G. `9 |8 t$ m* [. b kstatic int __init usb_kbd_init(void)
& ?% D, ]5 ], C3 {- W* D{ " @! { i- B. o$ [/ A3 ~/ W( g
usb_register(&usb_kbd_driver);
% L5 Z d9 l/ c; Y M8 qinfo(DRIVER_VERSION ":" DRIVER_DESC); 4 @7 ]1 k9 T- G5 K& ?( ^
return 0; 1 F* r) U9 ]5 A, u
}
' Y, O/ B0 T8 T: ~$ F5 R) c7 s [9 l% D
static void __exit usb_kbd_exit(void)
# R4 d* T" v6 L. S5 O5 [& b{
7 ?% g: ^+ R6 R2 S$ [! G. N2 Husb_deregister(&usb_kbd_driver);
9 B8 i8 q8 n. p: I/ }$ Z} 3 U( y# \" K% x
2 z5 w" v# m; ?% s, E/ U8 M4 x0 t! `
module_init(usb_kbd_init); 3 V. m, a3 `" G U
module_exit(usb_kbd_exit); |
|