QMK Firmware 2022 年 2 月 26 日破坏性变更解读:1kHz 轮询、分体指点设备与键盘目录重构实战指南
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
QMK Firmware 作为面向 Atmel AVR 与 Arm USB 系列的开源键盘固件,在每个开发周期都会通过 Breaking Changes(破坏性变更)机制整合大量核心改动。本文以官方docs/ChangeLog/20220226.md变更日志为主体,逐项解析 2022 年 2 月 26 日这一批变更中最值得关注的特性——默认 1kHz USB 轮询率、分体键盘指点设备支持、旧宏系统移除、bootloader 强制指定,以及覆盖上百款键盘的目录迁移表,并结合当前仓库源码给出可验证的实现细节,帮助开发者平滑升级自己的键位与键盘工程。
变更周期背景:为什么需要关注 Breaking Changes
QMK 采用固定节奏的合并窗口:开发分支develop上的破坏性改动会被集中到特定时间点统一合入master,避免用户每次拉取更新都被零散的 API 变动打断。本变更日志对应 2022 年 2 月 26 日的合并窗口,其中凡是标注"需要用户操作"(Changes Requiring User Action)的内容,都意味着键盘厂商或普通用户在升级后可能遇到编译失败或行为变化,需要主动修改配置。
显著新特性:默认 USB 轮询率统一为 1kHz
本周期最重要的行为变化之一:跨所有支持平台的默认 USB 轮询率被统一对齐为 1ms/1kHz。此前不同平台(LUFA、V-USB、ChibiOS 等)对轮询间隔的默认取值并不一致,现在统一收敛到 1ms。
从源码角度验证,当前仓库中轮询间隔由USB_POLLING_INTERVAL_MS宏控制:
- tmk_core/protocol/usb_descriptor.c 中定义
#ifndef USB_POLLING_INTERVAL_MS #define USB_POLLING_INTERVAL_MS 1,并随后在多处 HID 接口描述符(如PollingIntervalMS字段)中引用该值(见 usb_descriptor.c); - tmk_core/protocol/vusb/vusb.c 采用同样的
#ifndef ... #define USB_POLLING_INTERVAL_MS 1保护,并写入端点描述符的bInterval字段(vusb.c)。
两个实现都使用#ifndef包裹,意味着用户仍可在键盘或键位的配置文件里覆盖该默认值。1kHz 轮询对游戏玩家意味着更低的按键到主机的传输延迟,对一般输入体验也有感知层面的提升——这也是变更日志中"Let's go gamers!"调侃的由来。
显著新特性:分体键盘的指点设备支持
第二个头号特性是:指点设备(Pointing Device,如轨迹球、触摸板、光学传感器)现在可以跨分体键盘共享,既支持整个分体键盘只接一个指点设备,也支持左右两侧各接一个。
配置入口
在键位或键盘的rules.mk中启用指点设备与分体共享:
POINTING_DEVICE_ENABLE = yes POINTING_DEVICE_DRIVER = pmw3360 SPLIT_POINTING_ENABLE = yes当前仓库 builddefs/common_features.mk 维护了合法的指点设备驱动类型白名单,包括adns5050、adns9800、analog_joystick、azoteq_iqs5xx、cirque_pinnacle_i2c、cirque_pinnacle_spi、paw3204、paw3222、pmw3320、pmw3325、pmw3360、pmw3389、pimoroni_trackball与custom;若填写的驱动不在白名单内,构建系统会抛出POINTING_DEVICE_DRIVER="..." is not a valid pointing device type的错误。
左右侧归属与任务节流
分体键盘上指点设备可配置为属于左侧或右侧,分别通过POINTING_DEVICE_LEFT与POINTING_DEVICE_RIGHT宏声明。其底层同步逻辑位于 quantum/split_common/transactions.c:主控(master)侧通过GET_POINTING_CHECKSUM/GET_POINTING_DATA事务读取从机(slave)侧共享内存中的report_mouse_t报告,从机侧则调用驱动get_report()采集数据后写入共享内存并附带 CRC8 校验,供主控侧做校验和比对;CPI(每英寸计数)同样支持跨侧同步。
为保证低优先级传输不阻塞主循环,本周期还引入了POINTING_DEVICE_TASK_THROTTLE_MS默认任务节流(见 transactions.c),分体传输按节流间隔调度。相关的分体事务 ID 在 quantum/split_common/transaction_id_define.h 中按POINTING_DEVICE_ENABLE && SPLIT_POINTING_ENABLE条件编译。完整的配置选项请参阅 docs/features/pointing_device.md。
需要用户操作的变化(Changes Requiring User Action)
这一节是升级时必须逐条核对的部分,任何一项遗漏都可能导致编译失败或行为不符合预期。
旧宏系统与 action_function 被彻底移除
长期处于废弃状态的MACRO()宏与action_get_macro回调体系在本周期被彻底移除(对应 PR #16025 特性。升级建议:
- 若旧键位中还有
action_get_macro函数或MACRO(...)键码,请改用新版宏功能(如M(0)配合process_record_user中的case M_0:分支); - 涉及
action_function()的键盘(例如本周期顺带清理了 LFKeyboards 系列键盘,见下方变更清单)同样需要移除。
未指定 bootloader 将直接产生构建错误
此前若键盘未声明 bootloader,构建系统会"猜测"或静默处理;现在不再做任何假设,键盘必须在以下两处之一显式声明:
- 在
rules.mk中设置BOOTLOADER; - 在
info.json中设置bootloader字段。
如果两者都缺失,make将报错终止。仓库侧也有配套约束:本周期还加入了custom作为info.json中合法的 bootloader 类型(见变更清单 PR #16228),并集中为一批遗漏声明的键盘补上了BOOTLOADER(PR #16225、#16256)。
命令行工具侧,qmk flash同样依赖键盘的 bootloader 配置:若未指定,默认使用该键盘构建系统里配置的 bootloader(见 lib/python/qmk/cli/flash.py);可通过qmk flash -b/--bootloader覆盖,或用qmk flash -bl/--bootloaders列出可用的 bootloader 清单(flash.py)。键位信息查询命令qmk info也会显示键盘的 Bootloader 字段(lib/python/qmk/cli/info.py)。
AdafruitBLE更名为BluefruitLE
为给未来的蓝牙工作铺路,AdafruitBLE集成被更名为BluefruitLE,以便容纳 Adafruit 其他 BLE 产品。仍在键位中引用旧名称AdafruitBLE的用户需同步更新为BluefruitLE。
键盘代码目录迁移(重要:完整对照表)
本周期进行了大规模键盘代码归位,大量键盘从键盘根目录迁移到了厂商(vendor)/作者目录下。升级后若发现自己的键盘make找不到目标,请优先在此表中查找新路径:
| 旧键盘名称 | 新键盘名称 |
|---|---|
| 6ball | maple_computing/6ball |
| 7skb | salicylic_acid3/7skb |
| 7splus | salicylic_acid3/7splus |
| acr60 | mechkeys/acr60 |
| adalyn | tominabox1/adalyn |
| ajisai74 | salicylic_acid3/ajisai74 |
| aleth42 | 25keys/aleth42 |
| alicia_cook | ibnuda/alicia_cook |
| allison_numpad | prototypist/allison_numpad |
| allison | prototypist/allison |
| alu84 | mechkeys/alu84 |
| angel17 | kakunpc/angel17 |
| angel64/alpha | kakunpc/angel64/alpha |
| angel64/rev1 | kakunpc/angel64/rev1 |
| arch_36 | obosob/arch_36 |
| bakeneko60 | kkatano/bakeneko60 |
| bakeneko65/rev2 | kkatano/bakeneko65/rev2 |
| bakeneko65/rev3 | kkatano/bakeneko65/rev3 |
| bakeneko80 | kkatano/bakeneko80 |
| barleycorn | yiancardesigns/barleycorn |
| bat43/rev1 | dailycraft/bat43/rev1 |
| bat43/rev2 | dailycraft/bat43/rev2 |
| bigseries/1key | woodkeys/bigseries/1key |
| bigseries/2key | woodkeys/bigseries/2key |
| bigseries/3key | woodkeys/bigseries/3key |
| bigseries/4key | woodkeys/bigseries/4key |
| bkf | drhigsby/bkf |
| business_card/alpha | kakunpc/business_card/alpha |
| business_card/beta | kakunpc/business_card/beta |
| butterstick | gboards/butterstick |
| c39 | maple_computing/c39 |
| cassette42 | 25keys/cassette42 |
| chidori | kagizaraya/chidori |
| chili | ydkb/chili |
| chimera_ergo | glenpickle/chimera_ergo |
| chimera_ls | glenpickle/chimera_ls |
| chimera_ortho | glenpickle/chimera_ortho |
| chimera_ortho_plus | glenpickle/chimera_ortho_plus |
| choco60 | recompile_keys/choco60 |
| choc_taro | kakunpc/choc_taro |
| christmas_tree | maple_computing/christmas_tree |
| claw44/rev1 | dailycraft/claw44/rev1 |
| cocoa40 | recompile_keys/cocoa40 |
| comet46 | satt/comet46 |
| cu24 | capsunlocked/cu24 |
| cu75 | capsunlocked/cu75 |
| cu80 | capsunlocked/cu80/v1 |
| delilah | rainkeebs/delilah |
| diverge3 | unikeyboard/diverge3 |
| divergetm2 | unikeyboard/divergetm2 |
| dozen0 | yynmt/dozen0 |
| dubba175 | drhigsby/dubba175 |
| eggman | qpockets/eggman |
| ergo42 | biacco42/ergo42 |
| ergoarrows | salicylic_acid3/ergoarrows |
| ergodash/mini | omkbd/ergodash/mini |
| ergodash/rev1 | omkbd/ergodash/rev1 |
| ergodox_infinity | input_club/ergodox_infinity |
| ergotaco | gboards/ergotaco |
| espectro | mechkeys/espectro |
| felix | unikeyboard/felix |
| four_banger | bpiphany/four_banger |
| freyr | hnahkb/freyr |
| geminate60 | weirdo/geminate60 |
| georgi | gboards/georgi |
| gergo | gboards/gergo |
| getta25 | salicylic_acid3/getta25 |
| gingham | yiancardesigns/gingham |
| gurindam | ibnuda/gurindam |
| halberd | kagizaraya/halberd |
| hecomi/alpha | takashiski/hecomi/alpha |
| hid_liber | bpiphany/hid_liber |
| id67/default_rgb | idobao/id67/default_rgb |
| id67/rgb | idobao/id67/rgb |
| id80 | idobao/id80/v1 |
| id87 | idobao/id87/v1 |
| idobo | idobao/id75/v1 |
| infinity60 | input_club/infinity60 |
| ivy/rev1 | maple_computing/ivy/rev1 |
| jisplit89 | salicylic_acid3/jisplit89 |
| jnao | maple_computing/jnao |
| just60 | ydkb/just60 |
| kagamidget | yynmt/kagamidget |
| kelowna/rgb64 | weirdo/kelowna/rgb64 |
| kprepublic/bm65hsrgb_iso | kprepublic/bm65hsrgb_iso/rev1 |
| kprepublic/bm68hsrgb | kprepublic/bm68hsrgb/rev1 |
| k_type | input_club/k_type |
| latin17rgb | latincompass/latin17rgb |
| latin47ble | latincompass/latin47ble |
| latin60rgb | latincompass/latin60rgb |
| latin64ble | latincompass/latin64ble |
| latin6rgb | latincompass/latin6rgb |
| latinpadble | latincompass/latinpadble |
| latinpad | latincompass/latinpad |
| launchpad/rev1 | maple_computing/launchpad/rev1 |
| lck75 | lyso1/lck75 |
| le_chiffre | tominabox1/le_chiffre |
| lefishe | lyso1/lefishe |
| lets_split_eh/eh | maple_computing/lets_split_eh/eh |
| ls_60 | weirdo/ls_60 |
| m3n3van | matthewdias/m3n3van |
| mechmini/v1 | mechkeys/mechmini/v1 |
| mechmini/v2 | mechkeys/mechmini/v2 |
| meira | woodkeys/meira |
| meishi2 | biacco42/meishi2 |
| meishi | biacco42/meishi |
| minidox/rev1 | maple_computing/minidox/rev1 |
| minim | matthewdias/minim |
| mio | recompile_keys/mio |
| model_v | matthewdias/model_v |
| montex | idobao/montex/v1 |
| nafuda | salicylic_acid3/nafuda |
| naiping/np64 | weirdo/naiping/np64 |
| naiping/nphhkb | weirdo/naiping/nphhkb |
| naiping/npminila | weirdo/naiping/npminila |
| naked48 | salicylic_acid3/naked48 |
| naked60 | salicylic_acid3/naked60 |
| naked64 | salicylic_acid3/naked64 |
| namecard2x4 | takashiski/namecard2x4 |
| nebula12 | spaceholdings/nebula12 |
| nebula68b | spaceholdings/nebula68b |
| nebula68 | spaceholdings/nebula68 |
| niu_mini | kbdfans/niu_mini |
| nk1 | novelkeys/nk1 |
| nk65 | novelkeys/nk65 |
| nk87 | novelkeys/nk87 |
| nknl7en | salicylic_acid3/nknl7en |
| nknl7jp | salicylic_acid3/nknl7jp |
| nomu30 | recompile_keys/nomu30 |
| novelpad | novelkeys/novelpad |
| ogurec | drhigsby/ogurec |
| otaku_split/rev0 | takashiski/otaku_split/rev0 |
| otaku_split/rev1 | takashiski/otaku_split/rev1 |
| owl8 | dailycraft/owl8 |
| packrat | drhigsby/packrat |
| pistachio_mp | rate/pistachio_mp |
| pistachio_pro | rate/pistachio_pro |
| pistachio | rate/pistachio |
| plexus75 | checkerboards/plexus75 |
| pursuit40 | checkerboards/pursuit40 |
| qaz | tominabox1/qaz |
| quark | checkerboards/quark |
| rabbit_capture_plan | kakunpc/rabbit_capture_plan |
| rainkeeb | rainkeebs/rainkeeb |
| reviung33 | reviung/reviung33 |
| reviung34 | reviung/reviung34 |
| reviung39 | reviung/reviung39 |
| reviung41 | reviung/reviung41 |
| reviung53 | reviung/reviung53 |
| reviung5 | reviung/reviung5 |
| reviung61 | reviung/reviung61 |
| runner3680/3x6 | omkbd/runner3680/3x6 |
| runner3680/3x7 | omkbd/runner3680/3x7 |
| runner3680/3x8 | omkbd/runner3680/3x8 |
| runner3680/4x6 | omkbd/runner3680/4x6 |
| runner3680/4x7 | omkbd/runner3680/4x7 |
| runner3680/4x8 | omkbd/runner3680/4x8 |
| runner3680/5x6_5x8 | omkbd/runner3680/5x6_5x8 |
| runner3680/5x6 | omkbd/runner3680/5x6 |
| runner3680/5x7 | omkbd/runner3680/5x7 |
| runner3680/5x8 | omkbd/runner3680/5x8 |
| scarletbandana | woodkeys/scarletbandana |
| scythe | kagizaraya/scythe |
| seigaiha | yiancardesigns/seigaiha |
| setta21 | salicylic_acid3/setta21 |
| space_space/rev1 | qpockets/space_space/rev1 |
| space_space/rev2 | qpockets/space_space/rev2 |
| spiderisland/winry25tc | winry/winry25tc |
| splitreus62 | nacly/splitreus62 |
| squiggle/rev1 | ibnuda/squiggle/rev1 |
| standaside | edi/standaside |
| steal_this_keyboard | obosob/steal_this_keyboard |
| stella | hnahkb/stella |
| suihankey/alpha | kakunpc/suihankey/alpha |
| suihankey/rev1 | kakunpc/suihankey/rev1 |
| suihankey/split | kakunpc/suihankey/split |
| thedogkeyboard | kakunpc/thedogkeyboard |
| the_ruler | maple_computing/the_ruler |
| tiger910 | weirdo/tiger910 |
| treadstone32 | marksard/treadstone32 |
| treadstone48/rev1 | marksard/treadstone48/rev1 |
| treadstone48/rev2 | marksard/treadstone48/rev2 |
| txuu | matthewdias/txuu |
| ua62 | nacly/ua62 |
| underscore33/rev1 | tominabox1/underscore33/rev1 |
| underscore33/rev2 | tominabox1/underscore33/rev2 |
| vn66 | hnahkb/vn66 |
| wallaby | kkatano/wallaby |
| wanten | qpockets/wanten |
| whitefox | input_club/whitefox |
| wings42/rev1 | dailycraft/wings42/rev1 |
| wings42/rev1_extkeys | dailycraft/wings42/rev1_extkeys |
| wings42/rev2 | dailycraft/wings42/rev2 |
| yasui | rainkeebs/yasui |
| yd60mq | ymdk/yd60mq |
| yd68 | ydkb/yd68 |
| ymd75 | ymdk/ymd75 |
| ymd96 | ymdk/ymd96 |
| ymdk_np21 | ymdk/np21 |
| yurei | kkatano/yurei |
| zinc | 25keys/zinc |
| zinc/rev1 | 25keys/zinc/rev1 |
| zinc/reva | 25keys/zinc/reva |
这批迁移背后对应着大量的"move ... into vendor folder"系列 PR(如 PR #15758 的 capsunlocked、#15760 的 mechkeys、#15783 的 novelkeys、#15788 的 input_club、#16040 的 gboards 等),其动机是让键盘树按厂商/作者组织,方便长期维护。目录迁移的同时,本周期还清理了键盘代码中的父目录相对路径(PR #16282),从根上避免这类路径在重组时失效。
核心改动:新 MCU 支持与新增驱动
新 MCU:STM32L432 与 STM32L442
延续此前的支持节奏,QMK 本轮新增了两款 STM32L4 系列 MCU 支持(PR #16016)。STM32L432 与 STM32L442 属于低功耗 Arm Cortex-M4 系列,可运行在 80MHz 并具备丰富的 USB 外设,适合对功耗有要求的便携键盘方案。
新增 LED 驱动芯片
核心新增了以下 LED 矩阵/ RGB 矩阵驱动芯片支持(PR #14989):
- IS31FL3742A
- IS31FL3743A
- IS31FL3745
- IS31FL3746A
此外还为核心 LED Matrix 补上了IS31FL3733驱动(PR #15088 目录下,可用于高性能 RGB 键盘的量产与客制化方案。
新增 GPIO 扩展/解复用驱动
- SN74x138:三线转八线译码器(demultiplexer)驱动,用于用更少的 MCU 引脚驱动更多矩阵列(PR #16217);
- mcp23018:I2C GPIO 扩展芯片驱动被移入核心(PR #15944),并同步对齐了 pca9555 驱动的 API 风格(PR #16277),便于分体键盘扩展 IO。
完整变更清单分类导读
除上述重点外,本周期还包含大量核心、CLI、键盘与修复类改动,可按类别快速检索(完整列表见 docs/ChangeLog/20220226.md):
- 核心(Core):数据驱动的新键盘子命令初版(PR #12795)、无变化的键盘报告不再发送给主机(PR #14065)、分体键盘 Custom Matrix Lite 支持(PR #14674)、新增
sym_defer_pr去抖类型(PR #14948)、Combo 新配置项(PR #15083)、开漏 GPIO 支持(PR #15282)、cancel_key_lock函数(PR #15321)、MAGIC_TOGGLE_CONTROL_CAPSLOCK(PR #15368)、外部 SPI Flash 驱动(PR #15419)、PMW3360/PMW3389 光学传感器驱动增强(PR #15431、#15740 等)、高级 deferred_exec 框架(PR #15579)、RGB Matrix 从 EEPROM 重载(PR #15923)、Pixel Flow RGB 特效(PR #15829)等; - CLI:
develop分支的变更日志生成器改用 PR 标题、跳过列表中的代码格式化(PR #15537、#16215); - 键盘(Keyboards):大量目录迁移(如 Reviung 归入 reviung/、winry25tc 移入 winry/、ymd 系列归入 ymdk/、IDOBAO 系列归入 idobao/ 等)、Durgod 提高扫描率、GMMK Pro 新增键位、ergoinu/not_so_minidox/ai03/orbit 等转换为
SPLIT_KEYBOARD、部分键盘改用 Matrix Lite、新增 Sol 3 键盘(PR #15687)等; - 键盘修复(Keyboard fixes):UT47、grs_70ec、Tractyl Manuform 4x6、Clueboard 66 hotswap、helix 等一系列编译失败修复,以及反复修正的
DEFAULT_FOLDER(PR #15904、#16135)与 bootloader 补漏(PR #16225、#16256); - 其他与 Bug 修复(Others / Bugs):兼容 MCU 列表补充示例(PR #15935)、
version.h每次构建重新生成并加入 gitignore(PR #16188、#16222)、动态宏在结束时的layer_state恢复修复(PR #16230)、PMW3360 SPI 写时序修复(PR #15519)、分体右侧 ws2812 LED 双索引修复(PR #15985)、ChibiOS UART 驱动编译修复(PR #16348)等。
升级清单速查
汇总本节,升级到本批次代码时建议按以下顺序自查:
- 声明 bootloader:检查键盘
rules.mk或info.json中是否已配置BOOTLOADER/bootloader,缺失则补上,否则构建直接失败; - 移除旧宏系统:搜索键位代码中的
MACRO(、action_get_macro、action_function(并迁移到新版宏机制; - 蓝牙改名:将
AdafruitBLE配置/引用改为BluefruitLE; - 核对键盘路径:若
make目标找不到键盘,对照上文迁移表使用新路径; - 重新审视轮询率与指点设备配置:确认 1kHz 默认值是否符合预期,分体键盘启用指点设备时按需开启
SPLIT_POINTING_ENABLE。
通过逐项对照本文与 docs/ChangeLog/20220226.md,开发者可以在升级 QMK 时快速定位破坏点、修复配置,并第一时间用上新 MCU、新驱动与分体指点设备等能力。
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考