从几个层面上来解释一下吧,目前似乎没有太完整的回答。
首先,给一个链接:https://www.ti.com/lit/an/slaa514/slaa514.pdf
这里有USB键盘的原理图和状态机,能从硬件层面上解释所有的问题。
首先,键盘其实就是一套开关矩阵(key matrix):
按键会接通相关的管脚,产生电信号。如果同时按下多个,就是多个信号。同时,手册上也描述了多个按键的情形,某些组合下,多个按键中的某几个会无法收到信号或者收到错误的信号("Ghost" Key):
所以,不管是按下一个,还是按下多个,对于芯片来说,都是可以处理的。
另外,键盘的键码叫做扫描码(Scan Code),扫描的意思已经很明显了,键盘控制器芯片是从周期性的扫描所有的管脚状态,对于高级的芯片,是一次性能处理多个按键的(比如我发的那个TI的),对于低级的芯片,可能就是一个一个的扫,扫到一个处理一个。所以如果是特别古老的键盘,同时按下几个键,在硬件上仍然是排队处理的。高级的芯片可以一次性获得所有的按键信息。
以TI这个芯片为例,它实际上支持多种模式,具体的扫描方式,手册中也给出了例子:
以上是硬件部分的设计。
再到传输层面上,PS/2和USB,这是两种不同的传输模式。
对于PS/2来说,使用的是键盘中断的方式,报告的是按下和弹起的事件。前面已经解释了,扫描码是从一个一个扫的,所以即使是同时按下,在扫描的过程中也是有先后次序的,按照这个次序报告键盘中断就可以了。
对于USB键盘就没有这种问题,USB键盘的报文格式是HID report,具体可以看这个回答:
HID report里只报告当前按下的按键信息,那么不管是同时按下几个键,都统一放到一个report里即可。所以USB键盘同时按下键位太多的时候,有些按键信息就丢失了。具体原因可以参见:
到了操作系统层面,比如Windows,实际上是针对硬件数据(HID report或者PS/2中断)再次重新解析。对于HID report,操作系统通常情况下就是从头开始读,所以哪个键码在report前面,哪个按键就被优先读取。
我在这个回答里,有描述Windows的处理方式(和调用栈):
复制部分内容出来(注意,调用栈比较老,不代表最新的Windows实现):
1)硬件中断/硬件端口数据 2)键盘Port驱动(USB or PS/2) //Filter驱动在此 //KeyboardClassServiceCallback也在这一层被调用 3)kbdclass驱动 //处理键盘布局和键盘语言,部分高端的病毒也工作在这里 4)Windows内核边界(zwCreate/zwReadFile) ----------------------(系统调用)---------------------- 5)Windows内核边界(zwCreate/zwReadFile) 6)csrss.exe的win32k!RawInputThread读取,完成scancode和vk的转换 //SetWindowHook工作在这里(全局) //kbd_event工作在这里 7)csrss.exe调用DispatchMessage等函数分发消息(此处开始广播键盘消息) //SetWindowHook工作在这里(进程) //PostMessage和SendMessage在这里 8)各个进程(窗口线程)处理消息
对于HID report或者PS/2中断信息来说,Windows的kbdclass驱动就会处理(重排),把按键转换成键盘布局指定的键码。Windows应用层是通过csrss.exe的win32k!RawInputThread来以Raw的方式读取按键的,这个时候都是一个一个读的。
这个问题下面有些使用脚本等方式模拟的,实际是在csrss这里实现的,包括Windows的VKEY的定义。
之后,再由csrss广播给各个窗口,这个时候已经是Windows的message格式的东西了。
如果能看得懂,最后放个结论:
从根源的位置判断:
a) 对于PS/2类型的键盘,取决于键盘电路上扫描线路的布局,哪个按键的管脚靠前,哪个按键就会被优先扫到并上报;
b) 对于USB类型的键盘,取决于HID report上的次序,在前面的优先被处理,report上的次序可能源于扫描电路的次序,也可能是芯片有特殊控制。
c) 操作系统会对键盘驱动获得的按键信息重新处理,实际应用层收到的内容不一定完全等价于总线信号的内容。
反对一下其他人的回答。。。
其他人的回答都是说:哪怕你以为是同时,但计算机很快,能分辨出先后
但实际上,计算机说快很快,说慢也能很慢
这里的快慢指的是时钟周期
如果把时钟周期调成0.1Hz,也就是10秒一周期,那计算机应该算我们通常意义的“慢”
在一个时钟周期内,所做的所有操作(A-B-A先不考虑),计算机都认为是“同时”
比如以0为起始,在第2秒的时候的操作和第8秒的时候的操作,对计算机来说是同时;第9秒和第11秒不是同时
回到原题
“同时”按下两个键,比如第2秒按了a,第8秒按了b,同一时钟周期,哪个先生效?
不知道
“先后”按下两个键,比如第9秒按了a,第11秒按了b,不同时钟周期,哪个先生效?
a吗?也不知道
为嘛?
现在键盘按键的识别,很多是通过矩阵逐行扫描的方式工作的
比如一个键盘4行4列
会先看第0行哪些键按了,然后再扫第1行第2行第3行,再回到第0行
也就是说需要4个时钟周期,才能扫描完整个键盘
假如你同时(第2秒第8秒)按了两个键,这两个键又在同一行,被同时扫描到
对键盘来说,这一次扫描识别了两个键被按下,我会把这两个键的信息给cpu,至于把a放前面还是把b放前面,完全看写键盘芯片控制程序的程序员的处理方式
那先后按ab呢(第9秒按a,第11秒按b),假如a在第1行,b在第三行,此时扫描到了第2行,一个键也没有,下一个时钟周期扫第三行,那对键盘来说,是b先按了,然后下一轮发现a被按了
如果当时扫描在第0行,那下一个时钟周期,会先发现a被按下了,所以,哪怕你先按了a再按了b,都不能保证a先被生效
本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度,google,bing,sogou 等
© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有