- 在线时间
- 63 小时
- 最后登录
- 2019-5-3
- 注册时间
- 2004-5-10
- 听众数
- 442
- 收听数
- 0
- 能力
- -250 分
- 体力
- 10122 点
- 威望
- -12 点
- 阅读权限
- 150
- 积分
- -586
- 相册
- 6
- 日志
- 10
- 记录
- 10
- 帖子
- 2003
- 主题
- 1253
- 精华
- 36
- 分享
- 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,
8 @5 W6 Y* E' h+ a5 S" USB ", " Mass Storage ",
, {. Q" `7 m. V, x* Q, bUS_SC_SCSI, US_PR_BULK, NULL,
! L# u' H1 K) ]" t" {US_FL_FIX_INQUIRY | US_FL_START_STOP |US_FL_MODE_XLATE ) 4 \* O: t1 r( ~
. S! j5 N: k: M! B( c注意:添加以上几句的位置,一定要正确。比较发现,usb-storage驱动对所有注册都是按idVendor, idProduct数值从小到大排列的。我们也要放在相应位置。
4 S8 D: i+ _) F0 L& n最后,填入以上信息,我们就可以重新编译生成内核或usb-storage.o模块。这时候插入我们的设备就可以跟其他U盘一样作为SCSI设备去访问了。
5 U3 i# ^ v$ T' ?) S键盘飞梭支持
' j* w# `; n, ?( A目前很多键盘都有飞梭和手写板,下面我们就尝试为一款键盘飞梭加入一个驱动。在通常情况,当我们插入USB接口键盘时,在/proc/bus/usb/devices会看到多个USB设备。比如:你的USB键盘上的飞梭会是一个,你的手写板会是一个,若是你的USB键盘有USB扩展连接埠,也会看到。
0 O, g# H1 ?9 _! _下面是具体看到的信息 # W# |0 d1 ?3 C- R/ c+ _: m, _- N
0 k: Q. B! @' g9 J' @, CT: Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#= 1 Spd=12 MxCh= 2
8 l- e6 k+ b# a8 d- s VB: Alloc= 11/900 us ( 1%), #Int= 1, #Iso= 0 0 T8 a% W* Y E y$ r. F( u9 P2 V
D: Ver= 1.00 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
" ]) c1 P; W8 M; h& z! m& V" VP: Vendor=0000 ProdID=0000 Rev= 0.00 * G2 p- j3 C: Y5 d- y9 H$ Z3 _ d
S: Product=USB UHCI Root Hub " w: q& @$ D7 b; e9 U+ \
S: SerialNumber=d800
( U4 {+ M* `' lC:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr= 0mA
7 {& Q6 x9 p8 U2 S: p; f+ oI: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub ) g: u: H _1 \7 n/ J! F
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=255ms
4 u! J: u( V0 @4 W1 o! W$ `' TT: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 3
4 D' b0 F* ?5 o* e( \ zD: Ver= 1.10 Cls=09(hub ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 4 [8 T) y, \' C9 V/ b `* k
P: Vendor=07e4 ProdID=9473 Rev= 0.02
: y; Q3 z8 P% b4 B9 f6 W, dS: Manufacturer=ALCOR
' f; `, l% H5 [+ S8 \, w. U ]; vS: Product=Movado USB Keyboard + u, @) T7 t: c) Q6 L/ ], @
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA ) W1 Y0 d: c7 [
I: If#= 0 Alt= 0 #EPs= 1 Cls=09(hub ) Sub=00 Prot=00 Driver=hub ; Y' K% J6 [; x8 C1 V2 {7 x8 k: `
E: Ad=81(I) Atr=03(Int.) MxPS= 1 Ivl=255ms
3 j0 e0 A9 i; \, r4 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函数中 0 A+ \9 e% T, l/ R, S( m
' G$ p1 ^* u& x5 f4 E4 l4 v/ z, iFILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp,
/ ^3 H0 [1 {1 Rusb_kbd_irq, kbd, endpoint->bInterval); ; l0 O; Q( O7 J; U) q
3 t+ N% X& ^; F3 e8 C一句中实现。
; c, |# L+ \) w从usb骨架中我们知道,usb_kbd_probe函数就是在USB设备被系统发现是运行的。其他部分就都不是关键了。你可以根据具体的探测值(Vendor=07e4 ProdID=9473等)进行一些修改就可以了。值得一提的是,在键盘中断中,我们的做法是收到USB飞梭消息后,把它模拟成左方向键和右方向键,在这里,就看你想怎么去响应它了。当然你也可以响应模拟成F14、F15等扩展键码。 7 s+ m- w4 a& Q( e) U$ J% d/ D
在了解了此基本的驱动后,对于一个你已经拿到通讯协议的键盘所带手写板,你就应该能进行相应驱动的开发了吧。 8 Z8 N T* s& _; P8 V
程序见附录1:键盘飞梭驱动。
4 O# M$ B+ w( _0 e7 n$ {, o使用此驱动要注意的问题:在加载此驱动时你必须先把hid设备卸载,加载完usbhkey.o模块后再加载hid.o。因为若hid存在,它的probe会屏蔽系统去利用我们的驱动发现我们的设备。其实,飞梭本来就是一个hid设备,正确的方法,或许你应该修改hid的probe函数,然后把我们的驱动融入其中。
6 G0 e) g) R5 z8 u9 v9 v9 A5 T参考资料 # g( o1 S. [; _% R5 |$ K
1. 《LINUX设备驱动程序》
! w4 O+ t# X+ S* R3 l, ?3 UALESSANDRO RUBINI著
: U l7 N6 |9 l5 n5 [. D! VLISOLEG 译
# E m$ f ]# I# p1 M- I$ r* x) D9 D2. 《Linux系统分析与高级编程技术》
! u* }5 f$ x9 ~9 ^& |3 u周巍松 编著 & P4 m) g K& Z* ~ C
3. Linux Kernel-2.4.20源码和文档说明
) B( {( z) s. \附录1:键盘飞梭驱动
$ D- p: X* p% U2 y9 P
m1 r3 O: m& c. r#include <linux/kernel.h>
5 s: J% l5 h& P3 P& Q#include <linux/slab.h>
( J# r: ~) e* K/ X1 O#include <linux/module.h> ) v( `) l6 r% q) D
#include <linux/input.h> 7 p }) r4 |( f7 O
#include <linux/init.h>
/ `1 r# c) [) w" H#include <linux/usb.h> $ p7 W5 P: |7 Q3 @" q
#include <linux/kbd_ll.h> . T( l7 |; H, \
( D2 @0 @5 D8 }; \, E' X* k/*
6 R0 P0 ]( f% u( K( \) E* U * Version Information
* B( _, K3 ~4 p0 [6 a B0 t" {2 R */
$ l; r9 a) a0 Z% ^2 A& d#define DRIVER_VERSION "" & K; _: \1 p, J P6 Q' S' w- T, s9 C
#define DRIVER_AUTHOR "TGE HOTKEY " - h+ u- C6 A2 z( D- b
#define DRIVER_DESC "USB HID Tge hotkey driver" # |7 I- P* _8 D
3 n2 f4 r5 ?) U- q" ~+ u
#define USB_HOTKEY_VENDOR_ID 0x07e4 % ]; @' a) d3 J
#define USB_HOTKEY_PRODUCT_ID 0x9473 + P G# Q7 H2 S0 C
//厂商和产品ID信息就是/proc/bus/usb/devices中看到的值 a+ p+ a7 x7 a
. s" k8 |; A$ l; h# f6 m" |MODULE_AUTHOR( DRIVER_AUTHOR );
+ {1 q0 [5 \: B' }3 U6 |3 _MODULE_DESCRIPTION( DRIVER_DESC );
9 n/ \1 R! B0 P1 T) x& z# T) G- @0 h" H+ r) |
struct usb_kbd {
0 k7 p6 o% `5 j3 d. G0 G' nstruct input_dev dev; 1 c' y2 N9 U$ ^' \' X) K
struct usb_device *usbdev;
& k# j k( r& u, y: d% sunsigned char new[8];
* V9 u& v. j, |2 h' zunsigned char old[8];
3 m8 i( }' L/ n( @! t% s1 Bstruct urb irq, led; * C0 f0 I% l& h9 u3 Y
// devrequest dr; ( U E) b, e! `; W* o. m
//这一行和下一行的区别在于kernel2.4.20版本对usb_kbd键盘结构定义发生了变化
: \# {7 B' ^. Z+ E0 k2 q* s/ Z+ D struct usb_ctrlrequest dr;
4 ~8 L C% a' H( W2 w8 H1 A# W5 Iunsigned char leds, newleds; , q$ a5 s: b, }" w0 }% C
char name[128]; " u8 H: ]5 M; E p) d+ W
int open;
4 a: O. @8 b0 I! `+ B7 f}; ( u w! o; ^1 t. M0 p! k
//此结构来自内核中drivers/usb/usbkbd..c % ^ J6 x2 ~% C: ]7 Y( s- n
4 Z( Z6 _: W4 A9 A9 q1 o
static void usb_kbd_irq(struct urb *urb)
; y0 e4 L0 _/ ?6 y6 {{ * R1 z9 o( Z! Z6 J. ]+ A. K
struct usb_kbd *kbd = urb->context;
& n# k% u) z- k9 m( \- f int *new; 2 k1 m4 ?7 J% y: Q5 q, {4 C
new = (int *) kbd->new;
, |4 B$ S6 N, S3 _: @" C
7 q2 P9 V$ e, ^: y, P" J3 hif(kbd->new[0] == (char)0x01)
; e3 Z) R' k+ I1 M8 Q& J# k! r: R# a{
4 I) @& D! x' y3 K# k, S! I$ Qif(((kbd->new[1]>>4)&0x0f)!=0x7) 4 e" R3 [+ b, T* C6 c+ ?& U
{
3 U$ v# x, h: b9 H v1 K5 rhandle_scancode(0xe0,1); . b3 ]) L5 S$ j; m" F# s. N6 m, {. e
handle_scancode(0x4b,1); 4 w% l1 s' ]: [) M- n2 ]
handle_scancode(0xe0,0); ( W" W' A7 R1 F$ O+ I& [, U# Q
handle_scancode(0x4b,0);
& y& {- t/ {+ Z} 5 L2 X7 d) L9 \% |: k( h
else ) B% n( X' y. x$ L
{ 6 g D% Q. R5 D
handle_scancode(0xe0,1);
$ X, s0 k2 J- G, h" l, T$ n handle_scancode(0x4d,1); ; ^+ {2 y# w) S" K
handle_scancode(0xe0,0);
+ {( b; n# ^7 m* U) s. j3 {9 J handle_scancode(0x4d,0); 1 l& c& s' Q; g& O q
}
& `2 V4 y1 i) D$ \: r- c! \} * Z+ V. W p) c! i4 {7 \
( g% \; n; D) f& ^8 s+ K# t7 h
& N% R) Y5 a1 \0 N @1 gprintk("new=%x %x %x %x %x %x %x %x",
& m; [$ a1 V) U; k9 j: ~kbd->new[0],kbd->new[1],kbd->new[2],kbd->new[3],
' _& o( ]. T) Q) v7 G* u1 {, Skbd->new[4],kbd->new[5],kbd->new[6],kbd->new[7]); ' [6 y/ Y% H- j: e
! W) }) j! r* T4 J}
( p: O( J; U4 W9 o1 r
4 I% f, Y( ^: ustatic void *usb_kbd_probe(struct usb_device *dev, unsigned int ifnum,
K' ~* D, n+ G. m& k" z' c& U const struct usb_device_id *id)
% v* N# T1 _6 z6 N, o; g{
0 o) X& c7 ^: _1 s/ zstruct usb_interface *iface; ! ]: R* |1 D1 X" o
struct usb_interface_descriptor *interface; / F4 U! |; K2 F( G9 H/ g
struct usb_endpoint_descriptor *endpoint;
+ y3 P3 R B: ~+ l3 I& a( z; V/ `) k struct usb_kbd *kbd; % h8 z; l$ O; I0 e) b& N% b
int pipe, maxp;
# ]) n) U) q6 W2 x% U* ?( _4 n; D8 M3 |' Q, N! ]- R
iface = &dev->actconfig->interface[ifnum]; 2 O' H/ O6 l8 t3 z/ V& t: y
interface = &iface->altsetting[iface->act_altsetting]; & H5 |; O) X8 a2 \2 [9 F1 V
; G) |: @ x9 @* h- b" C9 w" _; rif ((dev->descriptor.idVendor != USB_HOTKEY_VENDOR_ID) || 9 p& ~3 q, s/ C
(dev->descriptor.idProduct != USB_HOTKEY_PRODUCT_ID) ||
$ I, i+ W8 s" ~/ T(ifnum != 1))
L9 ^' f% _& [{
( B) G1 D, V# F: areturn NULL; / E1 e" o- k( K( |4 g- ]; f! p8 f
}
+ o3 `& z; ~' m3 j! ?- j2 jif (dev->actconfig->bNumInterfaces != 2) - x. b% Q+ A0 Z% A, \
{
. J/ v7 u) A& K9 e; z1 |% F: Jreturn NULL; 1 ]$ \8 ?! T% [( Z& ?7 w2 y- m
}
8 C9 u# l1 a+ T1 u: L1 ?, D. W8 E: F8 K
if (interface->bNumEndpoints != 1) return NULL;
4 b7 h7 B9 \; g' _. C: U; Y9 Z3 q1 R7 {7 d) r3 Y
endpoint = interface->endpoint + 0; ' L, `- N. r2 F# T3 s
* t& H3 i- e. d) \( C4 @
pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); 9 M6 m4 a6 L1 I$ w: ?5 ~) o
maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
( a5 A) T! \( t, X9 D8 u6 Q6 C2 L5 v" ~! |- @
usb_set_protocol(dev, interface->bInterfaceNumber, 0);
1 ]( M' I6 o2 D+ u: D usb_set_idle(dev, interface->bInterfaceNumber, 0, 0);
9 H0 c, C9 H% P4 a( {0 Z. H1 c* |3 r/ [2 ?' ^
printk(KERN_INFO "GU Vid = %.4x, Pid = %.4x, Device = %.2x, ifnum = %.2x, bufCount = %.8x\\n",
* u/ C1 F5 F: y% K) a* n; ldev->descriptor.idVendor,dev->descriptor.idProduct,dev->descriptor.bcdDevice, ifnum, maxp);
! _$ S( V$ o* R9 y' \5 i5 n4 y
; i# l1 n8 A1 k% Y: E4 Z if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL))) return NULL; ! y% F' y! A) m" \+ ^
memset(kbd, 0, sizeof(struct usb_kbd)); 7 I8 O+ F! u7 {% @5 l1 Y9 ~9 E& w
1 y$ g/ _! e9 [1 B3 S0 W kbd->usbdev = dev; ( C4 D: J# ]* h# C1 \3 Q* J
, ~ [2 T# ~ C2 R! J
FILL_INT_URB(&kbd->irq, dev, pipe, kbd->new, maxp > 8 ? 8 : maxp, 6 \, G7 b# l. d5 e
usb_kbd_irq, kbd, endpoint->bInterval);
9 m4 P4 t" n1 ~& [+ n; g7 [( t* x6 S2 W, i% I
kbd->irq.dev = kbd->usbdev; ' I- ~, T T5 L# k0 Q
, ^4 A" d. B4 b2 uif (dev->descriptor.iManufacturer) 0 }$ Y1 }5 y( t) Y
usb_string(dev, dev->descriptor.iManufacturer, kbd->name, 63); 3 \; X6 ?6 w4 J7 k
* u& d1 T% U. L' `if (usb_submit_urb(&kbd->irq)) {
; \- J: g3 V/ I! n0 s- ^# O kfree(kbd); " b! q9 z* Y; n: g- ?* X6 N7 p( s' ]
return NULL;
& a; q5 L- n) d( A2 y- Q# X } " N& X4 h" G2 k6 I/ I
4 ]- t# h! B- o
printk(KERN_INFO "input%d: %s on usb%d:%d.%d\\n",
* S M! Q. k# k; A$ H' | kbd->dev.number, kbd->name, dev->bus->busnum, dev->devnum, ifnum); ; O* Z- z# u G ~" a* S, D) C
# S8 \2 U" @# X6 U0 X8 H! ?1 K4 T
return kbd;
; d0 F9 d# Z8 o} / Y2 @9 p6 j$ B5 O/ B. u. g
$ s- j0 \9 w* p Y
static void usb_kbd_disconnect(struct usb_device *dev, void *ptr)
& O, Q x" C7 v) U/ I{
; s5 d/ _8 @. b4 i9 S+ s( n6 D: Qstruct usb_kbd *kbd = ptr; & x, v7 M! K$ K! i
usb_unlink_urb(&kbd->irq);
9 B1 C: x2 W4 g. B, D kfree(kbd);
" [# k0 l1 A3 m' b6 u
9 j& E" t n1 e; B} " c: U. j$ Y' c2 ?
( ?: ?+ E7 X3 L' b4 ~8 |1 ustatic struct usb_device_id usb_kbd_id_table [] = { 2 R9 H4 U1 U4 f2 K6 G
{ USB_DEVICE(USB_HOTKEY_VENDOR_ID, USB_HOTKEY_PRODUCT_ID) },
: L* i! z+ v6 { M/ [' P$ M{ } /* Terminating entry */
0 w$ v, L6 x: q7 y};
2 [5 A. e V( i6 n# k+ w
' k5 d; @: o }4 h3 t9 ]! vMODULE_DEVICE_TABLE (usb, usb_kbd_id_table); , ]7 I( x7 M0 q% P+ g
1 M- g# E: \: [1 K. d! l$ wstatic struct usb_driver usb_kbd_driver = { % y$ w/ m" g4 f M2 @! d
name: "Hotkey",
; Y. b/ ?* \* f8 v" N! p0 ?probe: usb_kbd_probe,
- y6 T, Y- f7 h2 `2 e }* l) ydisconnect: usb_kbd_disconnect,
! c0 g/ Z+ i0 V0 l9 Gid_table: usb_kbd_id_table, 1 k' s' l0 {1 l" _) N( `( {5 [. T# |
NULL,
; R, b* t/ b. ^0 m4 x* `};
5 ?; a0 V1 v1 S; U6 c
/ u8 ~4 I: V2 L2 \9 |( f) Lstatic int __init usb_kbd_init(void)
7 M8 i6 o, J! k; h8 C5 d! X9 I( T{
, e. D) ?9 W7 ], n6 n) k, T" O& c Musb_register(&usb_kbd_driver);
! G4 ^3 E; S; b g3 `% rinfo(DRIVER_VERSION ":" DRIVER_DESC); * ?, }7 b3 M8 N' s- s( W
return 0; W9 E& d8 x% o$ {) b. |
}
/ _ i$ R, l" Z5 [+ b8 e
* u$ @& D% F+ i, w: j @static void __exit usb_kbd_exit(void) # k( h: g; s+ S( j' `5 l w) ^7 W4 Y
{ d4 O1 m1 }% l5 R T0 [) P2 e) ~
usb_deregister(&usb_kbd_driver); 3 W. Q/ M2 f) Z$ W0 {
} " F2 ^% Q5 _# o2 \# T7 `
4 {6 ^$ j% G- C8 c7 G4 ] `
module_init(usb_kbd_init); 1 i7 p$ D; z/ o% M0 {9 |
module_exit(usb_kbd_exit); |
|