前言
QMK 算是目前较为成熟的开源键盘固件之一,拥有详细的开发文档和配套软件,目前绝大多数客制化键盘都支持此固件。QMK 固件非常灵活,既可以通过编程的方式深度定制键盘功能,也可以通过 VIA、Vial 等驱动软件简单编辑键层。
对大部分用户来说,通过驱动改改键位完全够用。但是客制化的圈子良莠不齐,并不是任何键盘都能有完备的售后。尤其是随着键盘使用时间的增加,一些小问题会逐渐凸显,比如自定义层数太少、不支持某些特殊功能等等。
而开源固件的好处就是,如果官方不能提供固件支持,我们也可以研究研究文档,自己手搓一个新固件给键盘用。这篇文章,我们就讲讲如何给键盘搓一个自己用着更爽、还支持 VIA 的固件。
文章导读
本篇文章虽然重点在于 VIA 驱动,但是其实也可以算是 QMK 固件的入门指南,包含了配置 QMK 本地开发环境、创建自定义 keymap、编译键盘固件和刷写自定义键盘固件的全套流程。
没玩过的人可能很难理解自定义键盘固件的好处,这里就举一个我最喜欢的功能——Lead 键。按下 Lead 键后再按下预设的按键序列,就可以触发任意预设好的键鼠操作。虽然现在电脑上有许许多多的软件可以实现类似的功能,但是软件宏和硬件宏完全是两回事。
干说可能大家感受不深,这里以我以前给女朋友送过的一个小键盘具体说明。这个键盘的基础功能其实没啥好说的,就是个键帽特殊点的数字小键盘,但是里面却有许多彩蛋,按下 Lead 键后按下不同的数字序列会打印出不同的语句,比如一两百字的生日祝福,亦或是其他心里话。
想象一下,打开一个记事本,按下一串独属于两人的暗语,看着一个个字符依次打出,品味那仿佛穿越时空而来的书信,键盘也仿佛有了温度。
而这,不过是 QMK 固件实际应用的冰山一角。VIA 功能可以算是入门 QMK 固件最好的切入点之一,如果你曾经想过编写键盘固件但是又不得其门而入,本篇文章会是一个不错的起点。
前提条件
正常购买客制化键盘,卖家应该都会提供一份配套的固件源码,在 QMK 中被称为 keyboard
。
这里先简单介绍一下 keyboard
和 keymap
的关系:
- keyboard 可以视为一种特定的键盘型号,与键盘的 PCB 板绑定;
- keymap 则是一种键盘布局,它属于 keyboard,但是可以配置不同的软件特性以及键位布局,每一种 keyboard 下可以有多种 keymap。
如果没有源码的话也可以去 QMK 的官方仓库中寻找一下对应的 PCB 板型号,看一下是否已经集成在其中。键盘源码的目录结构比较简单,以我那块 PLANCK 配列键盘为例:
C:\USERS\ADMINISTRATOR\QMK_FIRMWARE\KEYBOARDS\KPREPUBLIC\BM40HSRGB
│ bm40hsrgb.c
│ config.h
│ info.json
│ readme.md
│ rules.mk
│
└─keymaps
├─dan
│ │ config.h
│ │ keymap.c
│ │ readme.md
│ │ rules.mk
│ │
│ └─features
│ custom_shift_keys.c
│ custom_shift_keys.h
│
├─default
│ keymap.c
│ readme.md
│
└─via
keymap.c
readme.md
rules.mk
这份源码对于大部分用户而言是必须的,没有的话后面的一切也就无从谈起。如果卖家在键盘介绍中明确说明支持 QMK 固件的话,那么一定是可以要到这份源码的。
有了源码之后又分为几种情况,最好的一种是卖家本身就给你的键盘刷了开启 VIA 支持的固件,那么皆大欢喜,你把源码留着备用即可,直接跳到文章后面看 VIA 软件的具体使用教程即可;最坏的情况是源码的 keymaps
文件夹中只有一个 default
文件夹,这就意味着你必须自己创建一个新的 keymap,并在其配置文件中开启 VIA 支持后编译固件刷入键盘,同时还要自己编写导入 VIA 软件中用于识别键盘的 json 文件。
下面的文章会以最坏的情况为例,一步一步实现键盘对 VIA 软件的支持,读者可以根据自己的实际情况 跳转。
搭建环境
这部分可以直接参考 QMK 官方文档,注意按照你的系统选择对应的步骤跟随。
其中,Windows 用户可以选择安装 Windows 专用的命令行环境 QMK MSYS(基于 MinGW),也可以选择在 WSL 环境下跟随 Linux 步骤安装。
安装完成后,用户主目录(macOS/Linux 下的 ~
,Windows 下的 %USERPROFILE%
即 C:\Users\[USERNAME]\
)会出现一个 qmk_firmware
文件夹,这就是 QMK 的主目录。
如果你在安装完成后的初始化步骤 qmk setup
遇到卡住不动的问题,是因为该命令会从 GitHub 拉取一系列仓库,请检查网络条件。
搭建完成后,可以输入如下指令,测试编译 Clueboard 66% 布局的效果:
qmk compile -kb clueboard/66/rev3 -km default
如果开头看到 WARNING 不用在意,只要编译过程全部显示 OK 并且最后出现固件体积的提示就代表编译环境已经配置完成。
创建 keymap
首先需要将目标键盘的 keyboard 源码放到上面提到的 qmk_firmware
文件夹下的 keyboards
文件夹中。
这里建议先以自己的用户名(随便给个英文名即可)创建一个文件夹,然后将键盘源码的文件夹复制到里面,这样以后如果有新的键盘也可以放在里面,方便查找。
如果键盘的源码已经包含在 QMK 官方仓库中,那么只要在 keyboards
文件夹中找到对应的路径即可。
做完上面的准备步骤后使用下面的命令在该 keyboard
下创建一个新的 keymap,作为开启 VIA 支持的专用 keymap。
qmk new-keymap -kb <keyboard> -km <keymap>
此处需要填写 keyboards 文件夹下的相对路径,只要与现有 keymap 的名称不相同即可,一般填 via。以下图中的 keyboard 为例,只需要使用如下命令:
qmk new-keymap -kb kprepublic/bm40hsrgb -km via
如果 keyboard
的路径没有写错的话就会成功创建一个新的 keymap,命令行中会给出其位置的绝对路径,根据路径打开该文件夹。
正常文件夹中只会有两个文件,一个是定义键位布局的 keymap.c
,另一个是说明文档 readme.md
。
这里不需要对这两个文件做任何处理,直接新建一个名为 rules.mk 的文件,在其中输入如下内容后保存。
VIA_ENABLE = yes
LTO_ENABLE = yes
简单解释一下这个文件的作用,它相当于一个配置文件,可以在里面开启或关闭键盘固件的功能。上面两个选项分别用来开启 VIA 支持以及压缩固件体积,后面这个 LTO_ENABLE 选项可能会和部分主控冲突,发生未知的 bug,如果后面刷写完固件发现功能有问题的话可以把第二行删了重新编译尝试一下。当然,碰到问题的可能性很小就是了。
增加动态键层数量
这算是一个补充知识点,默认情况下键盘会有 4 个动态键层可供 VIA 软件修改键位。大部分情况下 4 个键层肯定是够用了,再多也记不住。但是如果真的需要更多键层的话也可以,只需要在刚才的文件夹中再创建一个名为 config.h 的文件,然后在其中输入如下内容:
#define DYNAMIC_KEYMAP_LAYER_COUNT 8
后面的数字不能设置过大,因为每一个动态键层都需要占用一定的存储空间。追求极限的话可以先写个十几编译试试,如果编译失败就减小数字,直到编译成功为止。
编译固件
编译固件的方法其实在创建环境那一节中大家已经尝试过了,就是最后用来测试的那条命令,这里给出通用命令格式和一个示例:
qmk compile -kb <keyboard> -km <keymap>
qmk compile -kb kprepublic/bm40hsrgb -km via
这里我们先不急着将固件刷写到键盘中,等完成 VIA 驱动识别键盘需要的 json 文件后再一起 。
编写 VIA 配置文件
配置文件作用
这里先解释一下这个配置文件是干啥的。QMK 固件的配置文件中都会有两个参数,vid
和 pid
,分别代表供应商 ID 和 产品 ID,这两个 ID 组合在一起就构成了某种型号键盘的识别码。这个识别码会随着固件被刷写到键盘中,VIA 就是通过这个识别码来加载对应的配置文件。
配置文件中除了识别码外还保存有该种型号键盘的针脚定义以及每个键对应的位置、大小、颜色。换句话说,配置文件让 VIA 把实际的键盘按键与虚拟的针脚定义一一对应,从而实现按键的功能修改。
旧版配置文件问题
目前 VIA 已经更新到了 v3。将老版本的配置文件直接使用可能会报一些 WARNING,通常是灯光,不止会影响部分功能,还看着难受。
还有就是驱动中部分按键的颜色都是按照该键盘的默认配置设置的,如果后面自己修改键位布局可能会出现颜色无法匹配的问题。
上面两个问题都不会影响 VIA 最关键的改键功能,仅仅是影响观感。但我想,都玩客制化了,肯定都有一颗折腾的心,学一下自己编写配置文件总是好的,毕竟也不难。
配置文件结构
VIA 配置文件其实就是一个 json 文件,用于让 VIA 读出键盘的配置,相当于给现在连着的键盘下定义。按照官方规定好的字段把对应的数据填进去就算是编写完成了。
上图是最简单的配置,可以看到,其实也就六七个需要填的参数,前面四个参数非常简单,比较麻烦的其实就 layouts(配列排布)一个。
具体参数填写
简单参数
首先是 name
,这个是键盘名称,会显示在 VIA 软件界面的右上角,随自己高兴填一个就行,一般填键盘型号。剩下的需要打开键盘源码中的 info.json 文件查找。
目前比较新的源码都会带有这个 info.json
文件,但如果键盘买的比较早,或者是自己使用 Keyboard Firmware Builder 网站自制的源码就有可能出现不一样的文件结构,这个时候就需要打开下图中的两个文件来查找对应参数,具体方法在本节的最后 补充。
下面先以 info.json
文件来说明。
打开 info.json
后会看到许多字段,根据 usb.vid
和 usb.pid
填写 venderId
和 ProductId
,根据 matrix_pins.rows
和 matrix_pins.cols
中元素的数量填写 matrix.rows
和 matrix.cols
。
这里的 matrix_pins
后面的 cols
与 rows
写的,是每列每行分别连在了主控的哪一个针脚上。比如 cols
的第一个 B6
,意思就是「第 0 列连在 B6 针脚上」。
搞清楚了这点,我们接着往下看。
layout 含义
到这里我们已经解决了 VIA 配置文件中的 4 个参数,接下来的 layouts.keymap
较为复杂,在填写之前需要先理解一下 info.json
中 layout
的含义。
下面先给出一段比较有代表性的 layout:
{"matrix": [3, 0], "x": 0, "y": 3},
{"matrix": [3, 1], "x": 1, "y": 3},
{"matrix": [3, 2], "x": 2, "y": 3},
{"matrix": [3, 3], "x": 3, "y": 3},
{"matrix": [3, 4], "x": 4, "y": 3},
{"matrix": [3, 5], "x": 5, "y": 3, "w": 2},
{"matrix": [3, 7], "x": 7, "y": 3},
{"matrix": [3, 8], "x": 8, "y": 3},
{"matrix": [3, 9], "x": 9, "y": 3},
{"matrix": [3, 10], "x": 10, "y": 3},
{"matrix": [3, 11], "x": 11, "y": 3}
matrix 后面跟着的坐标,代表的是与行列针脚对应的虚拟矩阵下标。比如 [3,0]
,就是在矩阵的第 3 行,第 0 列,在我的小键盘上相当于左下角 Ctrl 的位置。
听着比较抽象,以上一节图中的行列针脚为例,可以列出如下矩阵:
B6 | C6 | B4 | D7 | D4 | D6 | C7 | F6 | F5 | F4 | F1 | F0 | |
B3 | (0,0) | (0,1) | (0,2) | (0,3) | (0,4) | (0,5) | (0,6) | (0,7) | (0,8) | (0,9) | (0,10) | (0,11) |
B2 | (1,0) | (1,1) | (1,2) | (1,3) | (1,4) | (1,5) | (1,6) | (1,7) | (1,8) | (1,9) | (1,10) | (1,11) |
E6 | (2,0) | (2,1) | (2,2) | (2,3) | (2,4) | (2,5) | (2,6) | (2,7) | (2,8) | (2,9) | (2,10) | (2,11) |
B5 | (3,0) | (3,1) | (3,2) | (3,3) | (3,4) | (3,5) | (3,6) | (3,7) | (3,8) | (3,9) | (3,10) | (3,11) |
表中坐标的数量就是键盘最多拥有的按键数量,每一个实体按键都必须和虚拟矩阵中的位置存在对应。
后面用 x、y、w 表示的是键盘按键的「实际位置」——这个实际位置是把键盘布局抽象成矩形后,对虚拟矩阵的重排。主要是为了让其更加贴近实际的键盘布局,方便记忆和安排键位。
x、y 的方向需要格外注意,还有就是 w,这个参数是在矩阵里占用的长度,其实没啥影响。
layouts.keymap 参数
理解上面的基础知识后就可以开始编写 layouts.keymap
这一参数了。这里我们需要借助一个官方的网页工具 KLE。
这个工具的使用方法就不介绍了。进入网页后先根据自己键盘的按键布局把键盘的外形创建出来。不管是直的还是斜的都可以通过调整按键的参数调出来,不规则形状的键盘需要更多的耐心调整,实在嫌麻烦也可以调个大概,只要按键数量正确,位置大概能认出来哪个键就能用了。
下一步比较繁琐,需要在每一个键的 top-left legend 处填上其在虚拟矩阵中对应的下标。在填写的过程中可以顺便修改 Key Color 的值,可以改变该键在 VIA 中显示的颜色效果。
VIA 中的键只支持三种颜色,#cccccc
代表普通按键,#aaaaaa
代表修饰键,#777777
代表重要按键(例如 Esc、Enter、方向键等)。在不同的主题下这三种键会显示出不同的颜色搭配,部分主题下不同种类的按键可能会呈现同样的颜色。
如果想要三种按键颜色分明的话推荐使用 OLIVE 主题。
完成后点击右上角的 Download,在子菜单中选择 Download JSON,将该 json 文件保存到本地。
打开该文件后直接全选复制,将整个中括号的内容粘贴到 layouts.keymap
后面,至此 VIA 配置文件的第 5 个参数也就填写完成了。
menus 参数
这个参数可以用来自定义 VIA 软件界面上除了基础功能外的其他功能菜单,例如灯光、声音等。内置的功能菜单有 5 个,在 menus 字段填入对应的菜单名称即可:
- qmk_backlight(键盘背光)
- qmk_rgblight(键盘按键光 RGB)
- qmk_backlight_rgblight(键盘背光 RGB)
- qmk_rgb_matrix(外部驱动 RGB 矩阵)
- qmk_audio(键盘声音)
不同的键盘使用的灯光控制方案不同,有效的菜单选项也就会有所差别,可以在 info.json 中查找关键词,例如 info.json 中有 rgb_matrix 的话一般就用 qmk_rgb_matrix。
如果实在不确定的话就用笨办法,一个个试,哪一个导入进去不报错,功能可以正常使用就用哪一个。
最后那个 keycodes 参数也是可选的,如果你的键盘支持 RGB 灯效的话就按照最开始的示例图那样填写,如果不支持的话就把它删去即可。这个参数唯一的影响就是 VIA 键位里是否会出现专门的灯光控制按键。
补充说明
之前提到的老版本键盘(只支持 VIA 3 之前的客户端)源码也可以用类似的方法找到所有的参数,可以看下图中的示例辅助理解。
因为我手边没有带旋钮的键盘 验证,所以关于键盘上旋钮的定义方法没有说明,不过大体上差不多,可以直接按照官方文档中的说明操作。
这一节只介绍了最简单的 VIA 配置文件编写方法,类似多布局、自定义菜单等高级特性都没有说明,相信大部分用户其实也用不上,如果真有需要,建议结合本节内容去看官方文档。
刷写固件
最简单的刷写固件的方法就是下载安装 QMK Toolbox 这一专用的图形化刷写软件。