笔记本电脑的键盘学习教程

笔记本电脑的内置键盘是不可缺少的输入设备,它经历了二十几年的迭代才形成如今的设计标准(key layout、connector、protocol、scancode...)。
在键盘的发展历程中,出现了很多标准,有一些标准至今仍被使用。有兴趣可以查阅 键盘的发展。接下来就详细了解下笔记本电脑的键盘。
01—scan code
电脑键盘一般有 80-120 个按键,因此采用矩阵设计可以减少gpio 的使用。
如下示意图,mcu 控制 “a/b/c/d” 都保持低电平,然后挨个输出高电平,每次输出高电平的同时采集“1/2/3/4” 电平。此过程称之为 “键盘扫描”。
如果 c-3 按键按下,当 mcu 在 “c” 列输出高电平时,在 “3” 行可检测到高电平。如此 mcu 即可判断出哪个按键被按下了。
mcu 判断出哪个按键被按下,需要以数据的形式传递给 host 使用。因此需要给每一个按键安排一个编码,这个编码就是 scancode,即 “扫描码”。
这个 mcu 负责扫描矩阵,称之为 ksc(keyboard scan controller)。使用最为广泛的型号是 intel 8048。
键盘的发展历程中,一共出现过 3 套 scancode。
scan code set-1
1983年随 ibm personal computer xt(xt:extended technology,type:5160) 一起发布的 xt keyboard 就使用的是此套扫描码。当时配套的操作系统可以直接识别此套扫描码。如今的 windows、linux 系统都在沿用。
scancode set-2
1984年随 ibm personal computer at(at:advanced technology,type:5170)一起发布的 at keyboard 就是使用的是此套扫描码。但是操作系统并没有兼容识别此套扫描码,而是在主板上增加了一个 mcu 把 set-2 翻译成 set-1,然后再发送给系统。当然也有操作系统也可以识别 set-2,但并不是主流。
新增的 mcu 称之为 kbc(keyboard controller),使用最为广泛的型号是 intel 8042,因此 i8042 也用来代指 keyboard controller。
scancode set-3
1986年,ibm 重新设计了键盘布局,在美国市场上推出了 mf2 keyboard,有 101个按键。
mf2 keyboard 设计上增加了逻辑更为合理的 scancode set-3,由 i8042 翻译成 scancode set-1 传递给 cpu。此套扫描码并未流行。
最后流行的 ps/2 键盘,采用的仍旧是 scancode set-2。
02—key number
在 mf2 键盘出现后,键盘 layout 基本即保持一致了,但是按键的丝印却是千变万化,不同丝印的键盘是为了满足不同语种的需求。
键盘设计中,一个按键会规定一个 scancode。系统端根据接收的 scancode 就知道是哪个按键触发了。同样是按键 “q” 触发,系统端最终识别的字符可不一定是字符 “q”,这是要根据系统语言判断的。
键盘语种不同,丝印就不同。因此每个按键还规定了一个 key number,以便区分按键。
一般键盘制造商生产的矩阵键盘,会配套一份设计图纸,会指明按键在矩阵中的位置,此时使用的就是 keynumber。
ksc 扫描这个矩阵,根据扫描结果,识别出触发按键在矩阵的位置,
先找到 keynumber,从而查找出 scancode。
03—keyboard protocol
xt keyboard 和 at keyboard 的设计中,同 pch 通讯的规范已经不再使用,因此此处只针对 ps/2 keyboard 做描述。
ps/2 keyboard 设计中,采用 ksc (keyboard scan controller) 扫描键盘矩阵,按键触发后会编码出 scancode set-2 发送。其中 ksc 是一个位于键盘内部的 mcu,以 intel 8048 最为典型。ksc 和 kbc 之间通过 ps/2 协议通讯,完成keycode、command 的传递。
ps/2 键盘结构
在 x86 cpu 系统中,有一个独立的 io 寻址空间,大小 64k。随着计算机的发展,默认 60/64 两个 io 地址被用作 pch 和 kbc(i8042) 交换数据。
有以上两个通讯的支持, ps/2 keyboard 外接在电脑 ps/2 接口上后就可以工作了。
设计框图如下
kbc 寄存器
i8042 作为一个 kbc 使用 io 60、64 和 pch 传递数据。
io 60/64 分别定义为数据寄存器和状态寄存器。
针对 status register,在 intel 8042 datasheet 中定义如下。
bit0:指示 kbc 是否在 output data register 写入了数据。
bit1:指示 cpu 是否在 input data register 写入了数据。
bit2:指示 cpu 是否读取了 output register。
bit3:指示 cpu 写了 60h 还是 64h。
bit4-7:用户自定义。
不同厂家在后续的 kbc 设计中,增加了一些自定义状态。
如下图所示,kbc 中增加了针对 ps/2 通讯状态的一些定义。
如上图,host 端的 keyboard driver 利用 io 60/64 和 kbc通讯。
kbc 内部有两个数据寄存器,input and output data register。
一个状态寄存器,status register。
kb driver 写 60h 或者 64h,都对应 kbc 内部 input register,kbc 内部的 status register bit3 会做出区分。
kb driver 写 60h,kbc 认为是 data。
kb driver 写 64h,kbc 认为是自己的 command。
kb driver 读 60h,kbc 返回 output register 内容,主要是 scancode。
kb driver 读 64h,kbc 返回 status register 内容,指示 keyboard 状态。
04—keyboard command
kbc 和 ksc 作为 mcu,分别设计了一组命令。keyboard driver 可以发送这些命令,从而控制 kbc 和 ksc 的一些行为。
05—ec keyboard
在上世纪的个人电脑设计中,ps/2 键盘属于一个外接设备。ps/2 键盘通过 ps/2 接口和主板上 kbc 通讯。kbc 在 pch 和键盘中间作为一个 superio 设备,管理 ps/2 键盘。
随着个人电脑的不断发展,逐渐演变出便携式电脑,即笔记本电脑。键盘作为笔记本电脑的标配输入设备,也遵守了 ps/2 键盘系统的大部分标准,并且沿用至今。
在如今的笔记本电脑设计中,不再有独立的 ksc(i8048,键盘扫描器)和 kbc(i8042,键盘控制器),因此也不再有 ps/2 接口和 ps/2 协议存在。
ksc 和 kbc 的功能全部集成在一个专用 mcu 中,即集成在 ec 中。
ec 作为一个专用 mcu,设计有 8*18 的键盘扫描模块,实现矩阵键盘的扫描。ec 也设计有 lpc 总线,和 pch 实现 io 6064 通讯。因此在 ec 固件中即可实现 kbc 功能。
ec 这颗专用 mcu 集成了原先 kbc 的功能,因此 ec 也会叫 kbc。
如今笔记本电脑中,ec 键盘系统设计框图如下:
06—keyboard init
ec 键盘的实际工作原理和 ps/2 键盘基本一致,其中的 kbc 需要被 host 端 driver 初始化后,才能正常工作。
kbc 由 ec 固件实现,因此上述 kbc、ksc 相关的指令必须由 ec 固件实现,并且返回正确的值,否则 os 端 kb driver 初始化无法完成,会导致windows 系统下设备管理器中 ps/2 设备出现黄色感叹号,键盘无法使用。
uefi 环境下,kbc 初始化。
ec 固件实现了 kbc 逻辑后,添加必要的 log后,当 uefi 环境启动后会对 kbc 初始化。ec 端 log 如下图:
上图是在 ec 中记录了进入 uefi shell 环境时的键盘初始化序列。
通讯释义
1 host->ec, i8042 cmd[ad] 8042 command disable keyboard
2 host->ec, i8042 cmd[a7] 8042 command disable mouse
3 host->ec, i8042 cmd[aa] 8042 command self test
4 ec->host, data=[55] ec response test results
5 host->ec, i8042 cmd[60] 8042 command write controller config byte
6 host->ec, i8042 data[67] controller config byte is 0x67
7 host->ec, i8042 data[f4] send to io_60 without command
8 host->ec, i8048 cmd[f4] 8048 command enable matrix scan
9 ec->host, data=[fa] ec send “ack”,must 0xfa
10 host->ec, i8042 cmd[ab] 8042 command keyboard interface test
11 ec->host, data=[00] ec response test results,must 00
12 host->ec, i8042 data[ff] send to io_60 without command
13 host->ec, i8048 cmd[ff] 8048 command reset and start self-test
14 ec->host, data=[fa] ec send “ack”,must 0xfa
15 ec->host, data=[aa] ec response test results
17 host->ec, i8042 data[f0] send to io_60 without command
18 host->ec, i8048 cmd[f0] 8048 command get/set current scan code set
19 ec->host, data=[fa] ec send “ack”,must 0xfa
20 host->ec, i8042 data[02] send to io_60 without command
21 host->ec, i8048 cmd[02] 8048 sub-command select scancode set-2
22 ec->host, data=[fa] ec send “ack”,must 0xfa
23 host->ec, i8042 data[f4] send to io_60 without command
24 host->ec, i8048 cmd[f4] 8048 command enable matrix scan
25 ec->host, data=[fa] ec send “ack”,must 0xfa
26 host->ec, i8042 data[ed] send to io_60 without command
27 host->ec, i8048 cmd[ed] 8048 command control led status
28 ec->host, data=[fa] ec send “ack”,must 0xfa
29 host->ec, i8042 data[00] send to io_60 without command
30 host->ec, i8048 cmd[00] 8048 set led off
31 ec->host, data=[fa] ec send “ack”,must 0xfa
上述初始化过程在如下文件中可以找到:
udk2018/intelframeworkmodulepkg/bus/isa/ps2keyboarddxe/ps2kbdctrller.c
os 环境下,kbc 初始化。
windows 或者 linux 系统在加载过程中,bios 声明了 ps/2 键盘设备后,os 内置的 ps/2 keyboard driver 就会加载,完成 ec 内 kbc 和 ksc 的初始化,以及配置。当然 windows inbox ps/2 driver 看不到源码,感兴趣的话可以看看 linux ps/2 driver 的源码。
需要注意的是,uefi 和 os 下 kbc 初始化流程基本一致。
差异点是,uefi 环境下 cpu 不响应 serirq 中的 irq-1,靠轮询的方式工作。os下 cpu 需要响应 irq-1,当有键盘中断触发后,driver 才会被回调,处理 io 60/64 的数据。

MAX98314单声道、3.2W D类放大器
元器件分销商应坚决走"正"道,向假货说"不"!
网络二层环路,老练的网工,都是这么排查的!
桥式三坐标测量仪
国产品牌的工控设备能完胜进口品牌吗
笔记本电脑的键盘学习教程
新款ipad参数,价格,配置怎么样?新款ipad采用A9处理器+9.7英寸+2699元起售
光伏产业向“N型时代”迈进 技术迭代将加速产能优胜劣汰
在物联网时代 是将长期共存还是会出现一统天下的“霸主”?
红米Note5什么时候上市?红米Note5曝光!或将是高通骁龙630首发,入门级红米Note5A价格太亲民,双摄不足千元
射频电路的电源设计要点
关于余压监控系统安装区域的分析
模拟压力表和数字压力表使用压力传感器读取的优缺点
iPhone8原型机有很多款:全面屏下按藏指纹识别最惊艳
预计到2030年全球光伏累计装机量有望达到1721GW
小米和联通深度合作 发布定制新品红米3X
苹果13最好的多少钱
可复位温度开关在电机中的重要作用
小技巧防止你的笔记本爆炸
AI时代的生物识别面临怎样的挑战