JIURL键盘驱动 1

JIURL键盘驱动 3 JIURL键盘驱动 3作者: JIURL                 主页: http://jiurl.yeah.net     日期: 2003-12-13 4 编译与调试环境简介4.1 源码    ps/2键盘驱动的设备栈有3层,最底层设备对象的驱动是 acpi,中间层设备对 阅读详情

0 概述

    我们将讨论 ps/2 键盘的驱动。主要讨论的内容有,ps/2 键盘的硬件,使用键盘驱动的应用层,键盘驱动的初始化,键盘驱动如何完成自己的工作,以及一些涉及到的相关内容。需要注意的是,以后我们提到的键盘,如果没有特殊说明,都是指 ps/2 键盘。

1 ps/2 键盘的硬件

    要以写一个硬件的驱动为目的的话,需要对这个硬件有一定的了解,但并不需要太深入,只要对于写驱动足够就可以了。关于 ps/2 键盘的硬件知识,我们也是对讨论键盘驱动足够就可以了,一些对于驱动没有帮助的硬件实现的细节,我们不讨论。

1.1 ps/2 键盘硬件概述

    对于驱动来说,和键盘相关的最重要的硬件是两个芯片。一个是 intel 8042 芯片,位于主板上,CPU 通过 IO 端口直接和这个芯片通信,获得按键的扫描码或者发送各种键盘命令。另一个是 intel 8048 芯片或者其兼容芯片,位于键盘中,这个芯片主要作用是从键盘的硬件中得到被按的键所产生的扫描码,与 i8042 通信,控制键盘本身。

    当键盘上有键被按下时,i8048 直接获得键盘硬件产生的扫描码。i8048 也负责键盘本身的控制,比如点亮 LED 指示灯,熄灭 LED 指示灯。i8048 通过 ps/2 口和 i8042 通信,把得到的扫描码传送给 i8042。CPU 通过读写端口,可以直接把 i8042 中的数据读入到 CPU 的寄存器中,或者把 CPU 寄存器中的数据写入 i8042 中。ps/2 口一共有 6 个引脚,可以拔下 ps/2 插头看一下,这 6 个引脚分别为,时钟,数据,电源地,电源+5V,还有2个引脚没有被用到。由于只有一个引脚传输数据,所以 ps/2 口上的数据传输是串行的。

    下面几幅图是一个键盘的内部,可以看到用来产生扫描码的按键矩阵( Key Martix ),可以看到键盘中的芯片(这里不是i8048,是一个兼容的其他型号的芯片)。

 

注意,i8042 并不一定在主板上单独出现,可能被整合在某一芯片中。

1.2 扫描码 ,Make Code ,Break Code ,Typematic 

    当键盘上有键被按下,松开,按住,键盘将产生扫描码( Scan Code ),这些扫描码将被 i8048 直接得到。扫描码有两种,Make Code 和 Break Code。当一个键被按下或按住时产生的是 Make Code ,当一个键被松开产生的是 Break Code。每个键被分配了唯一的 Make Code 和 Break Code ,这样主机通过扫描码就可以知道是哪一个键。简单的说就是按下键,产生一个 Make Code。松开键,产生一个 Break Code。

    而对于按住不放的情况呢。我们可以打开一个记事本,把 'a' 键按住不放,可以看到会不停的产生 'a' 直到我们松开。这是由于,当按住一个键不放时,将会 Typematic ,也就是自动打。每隔一定时间,自动产生一个被按住的键的 Make Code,直到最后松开该键。对于 Typematic 有两个重要的参数,一个是 Typematic Delay ,决定了按下多长时间之后,进入 Typematic,另一个是 Typematic Rate,决定了在进入 Typematic 之后,一秒钟内能产生多少个 Make Code 。现在我们再打开记事本,按住 'a' 不放,仔细观察,将看到第一个 'a' 和第二个 'a' 之间间隔的时间明显比其他的要长,而之后每个'a'之间的时间间隔是一样的。

    而对于同时按下多个键的情况呢。在一个键被按下,产生了 Make Code,而没有被松开,没有产生 Break Code 的时候,再按下另一个键,于是产生了另一个键的 Make Code ,就算是这两个键被同时按下。之后,这两个键松开时,各自产生各自的 Break Code。更多的键的情况也是一样。比如要按 Ctrl 和 A,下面的情况就算作是同时按下了 Ctrl 和 A。按Ctrl,产生 Ctrl 的 Make Code,然后按A,产生 A 的 Make Code,然后各自松开,各自产生各自的 Break Code。

    而对于按一个键不放的时候,再按另一个键的情况呢。我们可以打开一个记事本,把'a'键按住不放,不要松开,然后再按's'键不放。我们可以看到当按下 's'时,'a'键并没有松,但是并没有'a'再出现了,而是's'开始出现,这时即使松开了's','a'也不会继续出现了。


1.3 扫描码集

    到目前为止一共有三套扫描码集( Scan Code Set ),ps/2 键盘默认使用第二套。不过可以设置 i8042,让 i8042 把得到的 Scan Code 翻译成 Scan Code Set 1 中的 Scan Code ,这样键盘驱动从 i8042 得到的所有 Scan Code 都是第一套中的 Scan Code(实际中驱动也是这么做的)。所以我们只讨论 Scan Code Set 1 。需要说明的是 Scan Code 和 ASCII码完全不相同。

    在 Scan Code Set 1 中,大多数键的 Make Code,Break Code 都是一个字节。他们的 Make Code 的最高位都为0,也就是他们的 Make Code 都小于 0x7F。而他们的 Break Code 为其 Make Code 或运算 80h ,也就是把 Make Code 的低7位不变,最高位设置为1。

    还有一些扩展按键,他们的 Scan Code 是双字节的。他们的第一个字节都是E0h,表明这是一个扩展键。第2个字节,和单字节 Scan Code 的情况相同。

    还有一个特殊的键,Pause/Break 键,它的 Make Code 为 E1,1D,45 E1,9D,C5,注意是 E1h 开头。而且它没有 Break Code 。

我们按键的 Make Code 的值的大小,列出 Scan Code Set 1 中的所有扫描码

KEY MAKE BREAK

ESC 01 81 
1 02 82 
2 03 83 
3 04 84 
4 05 85 
5 06 86 
6 07 87 
7 08 88 
8 09 89 
9 0A 8A 
0 0B 8B 
- 0C 8C 
= 0D 8D 
BKSP 0E 8E 

TAB 0F 8F 
Q 10 19 
W 11 91 
E 12 92 
R 13 93 
T 14 94 
Y 15 95 
U 16 96 
I 17 97 
O 18 98 
P 19 99 
[ 1A 9A 
] 1B 9B 
ENTER 1C 9C 

L_CTRL 1D 9D 
A 1E 9E 
S 1F 9F 
D 20 A0 
F 21 A1 
G 22 A2 
H 23 A3 
J 24 A4 
K 25 A5 
L 26 A6 
; 27 A7 
' 28 A8 

` 29 89 
L_SHFT 2A AA 
/ 2B AB 
Z 2C AC 
X 2D AD 
C 2E AE 
V 2F AF 
B 30 B0 
N 31 B1 
M 32 B2 
, 33 B3 
. 34 B4 
/ 35 B5 
R_SHFT 36 B6 

KP * 37 B7 
L_ALT 38 B8 
SPACE 39 B9 
CAPS 3A BA 

F1 3B BB 
F2 3C BC 
F3 3D BD 
F4 3E BE 
F5 3F BF 
F6 40 C0 
F7 41 C1 
F8 42 C2 
F9 43 C3 
F10 44 C4 

NUM 45 C5 
SCROLL 46 C6 

KP 7 47 C7 
KP 8 48 C8 
KP 9 49 C9 
KP - 4A CA 

KP 4 4B CB 
KP 5 4C CC 
KP 6 4D CD 
KP + 4E CE 

KP 1 4F CF 
KP 2 50 D0 
KP 3 51 D1 

KP 0 52 D2 
KP . 53 D3 

F11 57 D7 
F12 58 D8 

KP EN E0,1C E0,9C 
R_CTRL E0,1D E0,9D 

KP / E0,35 E0,B5 
R_ALT E0,38 E0,B8 

HOME E0,47 E0,C7 
UP ARROW E0,48 E0,C8 
PG UP E0,49 E0,C9 

L ARROW E0,4B E0,CB 
R ARROW E0,4D E0,CD 

END E0,4F E0,CF 
D ARROW E0,50 E0,D0 
PG DN E0,51 E0,D1 
INSERT E0,52 E0,D2 
DELETE E0,53 E0,D3 

L GUI E0,5B E0,DB 
R GUI E0,5C E0,DC 
APPS E0,5D E0,DD 

PRNT SCRN E0,2A, E0,37 E0,B7, E0,AA 

PAUSE E1,1D,45 E1,9D,C5 -NONE 

这 里说几句对驱动没有帮助的题外话,记不清是由于先有了关于 Scan Code 的值的猜测,才去按这个顺序列 Scan Code ,还是先这样列 Scan Code ,才有了关于 Scan Code 的值的猜测。总之,用这个 Make Code 的顺序,和我们现在键盘上键的布局做对照,我们大致就能猜到为什么 A 键的 Make Code 值为 0x1e,为什么 H 键的 Make Code 值为 0x23。我们拿其中的一小段举例子,A 1E,S 1F,D 20,F 21,G 22,H 23,看看键盘上 A,S,D,F,G,H 的位置吧。能感觉到些什么吧,感觉不到就算了,这个和驱动是无关的。从 Scan Code Set 1,可能还能推测出来最早的键盘的样子。以及发生在键盘上的一些变化。我们注意到 F10 和 F11,F12 的 Make Code 不是连在一起的,估计比较早的键盘只有10个功能键,而不是现在的12个功能键。从键的 Make Code 来看,有可能曾经使用的一些键,现在已经不出现在键盘上了。

还有一个值得注意的是,如果有 Make Code 为 0x60 的键,那么它的 Break Code 应该为 0x60+0x80=0xE0。那么这个键的 Break Code 将会和 表示扩展码的 0xE0 搞混。不过还好,并没有 Make Code 为 0x60 的键,所以不会发生搞混的情况。

1.4 i8042 键盘控制器

    键盘驱动直接读写 i8042 芯片,通过 i8042 间接的向键盘中的 i8048 发命令。所以对于驱动来说,直接发生联系的只有 i8042 ,因此我们只介绍 i8042 ,不介绍 i8048。

    象 i8042,i8048 这样的芯片,本身就是一个小的处理器,它的内部有自己的处理器,有自己的 Ram,有自己的寄存器,等等。

    i8042 有 4 个 8 bits 的寄存器,他们是 Status Register(状态寄存器),Output Buffer(输出缓冲器),Input Buffer(输入缓冲器),Control Register(控制寄存器)。使用两个 IO 端口,60h 和 64h。


Status Register(状态寄存器)

状态寄存器是一个8位只读寄存器,任何时刻均可被cpu读取。其各位定义如下

Bit7: PARITY-EVEN(P_E): 从键盘获得的数据奇偶校验错误
Bit6: RCV-TMOUT(R_T): 接收超时,置1
Bit5: TRANS_TMOUT(T_T): 发送超时,置1
Bit4: KYBD_INH(K_I): 为1,键盘没有被禁止。为0,键盘被禁止。
Bit3: CMD_DATA(C_D): 为1,输入缓冲器中的内容为命令,为0,输入缓冲器中的内容为数据。
Bit2: SYS_FLAG(S_F): 系统标志,加电启动置0,自检通过后置1
Bit1: INPUT_BUF_FULL(I_B_F): 输入缓冲器满置1,i8042 取走后置0
BitO: OUT_BUF_FULL(O_B_F): 输出缓冲器满置1,CPU读取后置0


Output Buffer(输出缓冲器)

输出缓冲器是一个8位只读寄存器。驱动从这个寄存器中读取数据。这些数据包括,扫描码,发往 i8042 命令的响应,间接的发往 i8048 命令的响应。


Input Buffer(输入缓冲器)

输入缓冲器是一个8位只写寄存器。缓冲驱动发来的内容。这些内容包括,发往 i8042 的命令,通过 i8042 间接发往 i8048 的命令,以及作为命令参数的数据。


Control Register(控制寄存器)

也被称作 Controller Command Byte (控制器命令字节)。其各位定义如下

Bit7: 保留,应该为0
Bit6: 将第二套扫描码翻译为第一套
Bit5: 置1,禁止鼠标
Bit4: 置1,禁止键盘
Bit3: 置1,忽略状态寄存器中的 Bit4
Bit2: 设置状态寄存器中的 Bit2
Bit1: 置1,enable 鼠标中断
BitO: 置1,enable 键盘中断

2个端口 0x60,0x64

驱动中把 0x60 叫数据端口
驱动中把 0x64 叫命令端口

1.5 命令

驱动可以直接给 i8042 发命令,可以通过 i8042 间接给 i8048 发命令。命令这部分内容直接来自 < 参考资料 [1] >。


1.5.1 发给i8042的命令

驱动对键盘控制器发送命令是通过写端口64h实现的,共有12条命令,分别为

20h 
准备读取8042芯片的Command Byte;其行为是将当前8042 Command Byte的内容放置于Output Register中,下一个从60H端口的读操作将会将其读取出来。

60h 
准备写入8042芯片的Command Byte;下一个通过60h写入的字节将会被放入Command Byte。

A4h 
测试一下键盘密码是否被设置;测试结果放置在Output Register,然后可以通过60h读取出来。测试结果可以有两种值:FAh=密码被设置;F1h=没有密码。

A5h 
设置键盘密码。其结果被按照顺序通过60h端口一个一个被放置在Input Register中。密码的最后是一个空字节(内容为0)。

A6h
让密码生效。在发布这个命令之前,必须首先使用A5h命令设置密码。

AAh
自检。诊断结果放置在Output Register中,可以通过60h读取。55h=OK。

ADh
禁止键盘接口。Command Byte的bit-4被设置。当此命令被发布后,Keyboard将被禁止发送数据到Output Register。

AEh
打开键盘接口。Command Byte的bit-4被清除。当此命令被发布后,Keyboard将被允许发送数据到Output Register。

C0h
准备读取Input Port。Input Port的内容被放置于Output Register中,随后可以通过60h端口读取。

D0h
准备读取Outport端口。结果被放在Output Register中,随后通过60h端口读取出来。

D1h
准备写Output端口。随后通过60h端口写入的字节,会被放置在Output Port中。


D2h
准备写数据到Output Register中。随后通过60h写入到Input Register的字节会被放入到Output Register中,此功能被用来模拟来自于Keyboard发送的数据。如果中断被允许,则会触发一个中断。


1.5.2 发给8048的命令

共有10条命令,分别为

EDh
设 置LED。Keyboard收到此命令后,一个LED设置会话开始。Keyboard首先回复一个ACK(FAh),然后等待从60h端口写入的LED设 置字节,如果等到一个,则再次回复一个ACK,然后根据此字节设置LED。然后接着等待。。。直到等到一个非LED设置字节(高位被设置),此时LED设 置会话结束。

EEh
诊断Echo。此命令纯粹为了检测Keyboard是否正常,如果正常,当Keyboard收到此命令后,将会回复一个EEh字节。

F0h
选 择Scan code set。Keyboard系统共可能有3个Scan code set。当Keyboard收到此命令后,将回复一个ACK,然后等待一个来自于60h端口的Scan code set代码。系统必须在此命令之后发送给Keyboard一个Scan code set代码。当Keyboard收到此代码后,将再次回复一个ACK,然后将Scan code set设置为收到的Scan code set代码所要求的。

F2h
读取Keyboard ID。由于8042芯片后不仅仅能够接Keyboard。此命令是为了读取8042后所接的设备ID。设备ID为2个字节,Keyboard ID为83ABh。当键盘收到此命令后,会首先回复一个ACK,然后,将2字节的Keyboard ID一个一个回复回去。 

F3h
设置Typematic Rate/Delay。当Keyboard收到此命令后,将回复一个ACK。然后等待来自于60h的设置字节。一旦收到,将回复一个ACK,然后将Keyboard Rate/Delay设置为相应的值。

F4h
清理键盘的Output Buffer。一旦Keyboard收到此命令,将会将Output buffer清空,然后回复一个ACK。然后继续接受Keyboard的击键。

F5h
设 置默认状态(w/Disable)。一旦Keyboard收到此命令,将会将Keyboard完全初始化成默认状态。之前所有对它的设置都将失效—— Output buffer被清空,Typematic Rate/Delay被设置成默认值。然后回复一个ACK,接着等待下一个命令。需要注意的是,这个命令被执行后,键盘的击键接受是禁止的。如果想让键盘 接受击键输入,必须Enable Keyboard。

F6h
设置默认状态。和F5命令唯一不同的是,当此命令被执行之后,键盘的击键接收是允许的。 

FEh
Resend。如果Keyboard收到此命令,则必须将刚才发送到8042 Output Register中的数据重新发送一遍。当系统检测到一个来自于Keyboard的错误之后,可以使用自命令让Keyboard重新发送刚才发送的字节。

FFh
Reset Keyboard。如果Keyboard收到此命令,则首先回复一个ACK,然后启动自身的Reset程序,并进行自身基本正确性检测(BAT- Basic Assurance Test)。等这一切结束之后,将返回给系统一个单字节的结束码(AAh=Success, FCh=Failed),并将键盘的Scan code set设置为2。


1.5.3 读到的数据


00h/FFh
当 击键或释放键时检测到错误时,则在Output Bufer后放入此字节,如果Output Buffer已满,则会将Output Buffer的最后一个字节替代为此字节。使用Scan code set 1时使用00h,Scan code 2和Scan Code 3使用FFh。

AAh
BAT完成代码。如果键盘检测成功,则会将此字节发送到8042 Output Register中。

EEh
Echo响应。Keyboard使用EEh响应从60h发来的Echo请求。

F0h
在Scan code set 2和Scan code set 3中,被用作Break Code的前缀。

FAh
ACK。当Keyboard任何时候收到一个来自于60h端口的合法命令或合法数据之后,都回复一个FAh。

FCh
BAT失败代码。如果键盘检测失败,则会将此字节发送到8042 Output Register中。

FEh
Resend。当Keyboard任何时候收到一个来自于60h端口的非法命令或非法数据之后,或者数据的奇偶交验错误,都回复一个FEh,要求系统重新发送相关命令或数据。

83ABh
当键盘收到一个来自于60h的F2h命令之后,会依次回复83h,ABh。83AB是键盘的ID。

Scan code
除了上述那些特殊字节以外,剩下的都是Scan code。


1.6 端口操作

    首先介绍一下端口的读写操作,驱动中使用函数 READ_PORT_UCHAR 进行读操作,READ_PORT_UCHAR 中使用CPU读端口指令,in。驱动中使用函数 WRITE_PORT_UCHAR 进行写操作,WRITE_PORT_UCHAR 中使用CPU写端口指令,out。

1.6.1 读取状态寄存器

读取状态寄存器的方法,对64h端口进行读操作。

1.6.2 读数据

需要读取的数据有,i8042从i8048得到的按键的扫描码,i8042命令的ACK,i8042从i8048得到的i8048命令的ACK,需要命令重发的RESEND,一些需要返回结果的命令得到的结果。

当 有数据需要被驱动读走的时候,数据被放入输出缓冲器,同时将状态寄存器的bit0(OUTPUT_BUFFER_FULL)置1,引发键盘中断(键盘中断 的IRQ为1)。由于键盘中断,引起由键盘驱动提供的键盘中断服务例程被执行。在键盘中断服务例程中,驱动会从i8042读走数据。一旦数据读取完成,状 态寄存器的bit0会被清0。

读数据的方法,首先,读取状态寄存器,判断bit0,状态寄存器bit0为1,说明输出缓冲器中有数据。保证状态寄存器bit0为1,然后对60h端口进行读操作,读取数据。

这 里我们要谈一点很有用的题外话,前面提到的 IRQ,是 Interrupt Request line,中断请求线,是一个硬件线,它和中断向量是不同的。中断向量是用来在中断描述符表(IDT)中查找中断服务例程的那个序号。键盘的 IRQ 是1,键盘中断服务例程对应的中断向量可不是1。这点要弄清楚。

1.6.3 向i8042发命令

当命令被发往i8042的时候,命令被放入输入缓冲器,同时引起状态寄存器的 Bit1 置1,表示输入缓冲器满,同时引起状态寄存器的 Bit2 置1,表示写入输入缓冲器的是一个命令。

向i8042发命令的方法,首先,读取状态寄存器,判断bit1,状态寄存器bit1为0,说明输入缓冲器为空,可以写入。保证状态寄存器bit1为0,然后对64h端口进行写操作,写入命令。


1.6.4 间接向i8048发命令

向i8042 发这些命令,i8042会转发i8048,命令被放入输入缓冲器,同时引起状态寄存器的Bit1 置1,表示输入缓冲器满,同时引起状态寄存器的 Bit2 置1,表示写入输入缓冲器的是一个命令。这里我们要注意,向i8048发命令,是通过写60h端口,而后面发命令的参数,也是写60h端口。i8042如 何判断输入缓冲器中的内容是命令还是参数呢,我们在后面发命令的参数中一起讨论。

向i8048发命令的方法,首先,读取状态寄存器,判断bit1,状态寄存器bit1为0,说明输入缓冲器为空,可以写入。保证状态寄存器bit1为0,然后对60h端口进行写操作,写入命令。

1.6.5 发命令的参数

某 些命令需要参数,我们在发送命令之后,发送它的参数,参数被放入输入缓冲器,同时引起状态寄存器的Bit1 置1,表示输入缓冲器满。这里我们要注意,向i8048发命令,是通过写60h端口,发命令的参数,也是写60h端口。i8042如何判断输入缓冲器中的 内容是命令还是参数呢。i8042是这样判断的,如果当前状态寄存器的Bit3 为1,表示之前已经写入了一个命令,那么现在通过写60h端口放入输入缓冲器中的内容,就被当做之前命令的参数,并且引起状态寄存器的 Bit3 置0。如果当前状态寄存器的 Bit3 为0,表示之前没有写入命令,那么现在通过写60h端口放入输入缓冲器中的内容,就被当做一个间接发往i8048的命令,并且引起状态寄存器的 Bit3 置1。

向i8048发参数的方法,首先,读取状态寄存器,判断bit1,状态寄存器bit1为0,说明输入缓冲器为空,可以写入。保证状态寄存器bit1为0,然后对60h端口进行写操作,写入参数。



"1 ps/2 键盘的硬件" 主要参考下面的资料,关于 ps/2 键盘硬件更多的内容也请参考下面的资料

[1] http://pagoda-ooos.51.net/os_book/driver/driver-keyboard_2.htm (中文)
[2] http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/PS2.pdf (中文)
[3] http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/ (英文)


欢迎交流,欢迎交朋友,
欢迎访问
主页 http://jiurl.yeah.net http://jiurl.nease.net 论坛 http://jiurl.cosoft.org.cn/forum

f啊k,不带你们这样的啊,有好事不叫我。

 

 
JIURL品牌键盘驱动程序详解与安装指南 传统驱动开发往往把所有参数写死在代码里:轮询率是多少?哪些键能重映射?背光模式有哪些?一旦要改就得重新编译。但 JIURL 的做法完全不同——它采用“驱动核心 + 外部配置”的分离架构。这意味着:✅ 同一份.ko或.sys文件,可以通过加载不同的.ini或.xml文件,变成办公版、游戏版、紧凑60%版……✅ 用户无需更新驱动即可自定义按键、设置宏、调整性能参数。✅ 厂商发布新机型时,只要提供新的配置文件,就能快速上线支持。 阅读详情

相关推荐

winio驱动级模拟键盘鼠标源码

winio模拟键盘鼠标实例源码内有详细注释,如果不懂的地方.优快云中有很多其它相关资料.

32位/64位WINDOWS驱动开发之驱动加载

加载驱动的过程1、用OpenSCManager 打开服务控制管理器2、用CreateService创建对应服务3、如果驱动服务已经创建过,则用OpenService打开服务4、用StartService加载启动驱动服务5、清理工作,用CloseServiceHandle关闭释放句柄MFC操作如下应用层:首先加两个按钮 加载驱动 ID IDC_BUTTON2_LOAD_SYS卸载驱动 ID IDC_BUTTON1_UNLOAD_SYS。

a756598009的博客 1242

JIURL键盘驱动

些关于键盘驱动的东西

按键精灵初步,使用winIO实现驱动级模拟按键

winIO是目前非常古老的技术,是用底层驱动来实现程序控制键盘按键,要使用winIO,需要用到两个文件WinIo64.dll,与WinIo64.sys。 也有32为的 WinIO32.dll, WinIO32.sys。基于现在的操作系统,都是用的32位的,且都是win7 以上的了,所以,本文用的是winIO64.dll,WinIO64.sys 第一步: 命令行运行: cmd-> bcd...

chen249191508的专栏 8774

c#驱动级模拟按键

c#开发的模拟按键,类似按键精灵的简单代码,可以直接运行winform程序,具有一定的参考价值

【Ragflow】9.问答为什么比搜索响应慢?从源码角度深入分析

前几天看到有群友提到一个现象:Ragflow的搜索界面的问答速度很快,但聊天界面的问答速度很慢,究竟是什么原因?在深入挖掘源码之后,逐渐发现了问题的答案。

兴趣使然的创作者 2906

WinIo驱动级键盘模拟编程

前天无聊,翻翻自己的兴趣项目文件夹,发现了这个放下很久的项目!那是大三时候的事了。当时是为了提高我魔兽三的按键速度,用了个叫移花接木的软件,把键盘的键位改了。的确是有所帮助,但这是共享软件,用40次就不能再用了除非注册。于是乎就有了做一个类似的软件出来,在网上搜索了一把发现WinIo模拟按键是最可靠的了,就决定向这方向钻进去了。哎...技术不够,看了很久的技术文章和代码也只是了解了一点,而且那时MFC技术还没到家根本做不出什么能用的东西来...后来听个兄弟说:反汇编破解。于是又试了下,居然真的被我破解了!一

fgrass_163的专栏 4512

Ubuntu 上 1Panel 的安装与高效运维实践

本文详细介绍了在Ubuntu系统上安装和高效运维1Panel面板的完整实践指南。内容涵盖了一键安装、Docker容器可视化部署、计划任务自动化以及网站数据库管理等核心功能,并提供了安全加固、资源监控与数据备份等进阶技巧,旨在帮助用户快速搭建并管理一个强大易用的服务器环境。

weixin_29210759的博客 144

键盘驱动系列---JIURL键盘驱动 1

0 概述     我们将讨论 ps/2 键盘的驱动。主要讨论的内容有,ps/2 键盘的硬件,使用键盘驱动的应用层,键盘驱动的初始化,键盘驱动如何完成自己的工作,以及一些涉及到的相关内容。需要注意的是,以后我们提到的键盘,如果没有特殊说明,都是指 ps/2 键盘。 1 ps/2 键盘的硬件     要以写一个硬件的驱动为目的的话,需要对这个硬件有一定的了解,但并不需要太深入,只要对

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1207

MuJoCo 相机图片怎么拿?视角调整获取物体图片及实时显示(附代码)

在Mujoco的仿真中,对于识别抓取场景来说,如何获得添加的body等物体的实时图像很重要,今天就分享下如何添加相机视角及可视化小方块(举例)的实时图片。复制一个scene.xml为scene_withcamera.xml,在xml中添加camera和小方块如下。设置xml文件中添加的相机body id。需要创建一个离屏渲染器。

darcsdn 2128

微生物组数据分析实战:从OTU/ASV过滤到相对丰度转换的标准化流程

本文详细介绍了微生物组数据分析中从原始OTU/ASV表格到标准化相对丰度表格的完整预处理流程。通过基于绝对丰度和出现频率的过滤步骤有效剔除测序噪音与污染,再通过相对丰度转换解决样本间测序深度差异问题,为后续的多样性分析和差异比较奠定可靠基础。文章提供了清晰的R语言实战代码与参数设置思路。

tree的博客 1260

JIURL键盘驱动 2

JIURL键盘驱动 2作者: JIURL                 主页: http://jiurl.yeah.net     日期: 2003-12-13 2 应用层基础知识    在讨论使用键盘的应用程序这个问题之前,我们首先介绍一下 Windows 中,应用程序使用驱动,

jiurl的专栏 3857

GIS应用技巧之三招搞定重叠区域数据提取

在很多分析过程中,常常需要分析判断哪些图形发生了重叠,该重叠情况的发生在对应分析环境下具有特定意义。例如在缓冲区分析中,若两个受灾点周边的受灾面积(即缓冲区)有所重叠,分析重叠区域的受灾影响时,就需要考虑相互影响的因素。本例中先用【要素转面】工具提取出发生重叠的区域,其次用【空间连接】工具将原始图层信息连接到重叠数据的图层,分析重叠数据的属性表,即可得到发生重叠的原始图层数据。 Step1 提取重叠区属数据。打开【数据管理工具】|【要素】|【要素转面】工具,输入要素设置为“circles”,输出要素类设置为

端木宛白的博客家园 6万+

键盘驱动系列---JIURL键盘驱动 2

2 应用层基础知识     在讨论使用键盘的应用程序这个问题之前,我们首先介绍一下 Windows 中,应用程序使用驱动,应用程序与驱动通信的一些问题。 2.1 应用程序如何使用驱动     应用程序中使用 CreateFile,ReadFile,WriteFile,DeviceIoControl,CloseHandle 来指示驱动程序完成某种任务。比如我们在应用程序中使用 Re

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 963

Grok 3国内怎么用?超详细使用指南+实用指令模板

主要是用于快速分析学术论文,提取关键信息,总结研究成果。Analyze the following research paper: [粘贴或上传论文内容]1. Extract key findings, methodologies, and conclusions. (提取主要发现、方法和结论。2. Identify statistical significance and data points. (识别统计显著性和数据点。

Survivor_sl的博客 1万+

LIN总线从入门到精通:低成本汽车通信协议原理与实战

在汽车电子和嵌入式系统中,串行通信协议是实现分布式控制的关键技术。其中,LIN(Local Interconnect Network)总线作为一种专为低成本应用设计的单主多从网络协议,其核心原理在于通过简化的“领导-汇报”通信模式,在满足车身控制、传感器数据采集等场景需求的同时,将硬件与布线成本降至最低。LIN总线采用标准化的帧结构,包含间隔场、同步场和受保护标识符场,并依赖调度表来管理通信时序,确保了网络的确定性与可靠性。其技术价值在于为车窗、座椅、灯光等非安全关键系统提供了高性价比的解决方案,是构建分层

weixin_29185167的博客 261

键盘驱动系列---JIURL键盘驱动 4

6.2 初始化与注册表 在驱动的初始化中,注册表起着非常重要的作用。 6.2.1 重要认识     每台计算机的硬件配置可能是不同的,系统是如何知道需要为哪些硬件载入驱动?系统是如何知道要载入的驱动文件是哪个文件?答案是通过注册表,注册表中保存着这些信息。那么注册表中的这些信息是哪里来的?答案是在安装驱动的时候,安装程序放到注册表中的。 6.2.2 确定驱动载入顺序的基本知

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 2282

鸿蒙接入微信支付 微信H5网页在鸿蒙系统的适配方法(含支付兼容方案) 微信H5适配鸿蒙系统 | ArkWeb识别 | 鸿蒙浏览器UA | 微信支付鸿蒙适配 | 鸿蒙微信判断方式

微信H5网页鸿蒙系统适配指南 针对微信H5网页在鸿蒙系统出现的兼容问题,本文提供完整适配方案。关键点包括: 环境识别:

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1301

键盘驱动系列---JIURL键盘驱动 5

7 键盘驱动的运作 7.1 输入数据队列简介 i8042prt 和 kbdclass 各有一个输入数据队列,他们是循环使用的缓冲区。他们的每个单元是一个 KEYBOARD_INPUT_DATA 结构。 i8042prt 的自定义的设备扩展中,保存着一些指针和计数值,用来使用它的那个输入数据队列。 PKEYBOARD_INPUT_DATA 类型的 InputData , Da

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 2027

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

键盘驱动系列---JIURL键盘驱动 3

4 编译与调试环境简介 4.1 源码     ps/2键盘驱动的设备栈有3层,最底层设备对象的驱动是 acpi,中间层设备对象的驱动是 i8042prt,最高层设备对象的驱动是 kbdclass。     DDK 所附的源码中有 i8042prt 和 kbdclass 的源码,分别位于 ...\NTDDK\src\input\pnpi8042 ,...\NTDDK\src\inp

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1192

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

上一篇: JIURL键盘驱动 2
下一篇: 终于比IceSword底层了
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值