
QMK Firmware 2026-02-22 破坏性变更解析移除废弃 GPIO 定义与 isLeftHand附完整变更清单【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware本文围绕 QMK Firmware 2026 年 2 月 22 日发布的破坏性变更Breaking Changes周期展开核心讲解两个被彻底移除的废弃 API——Arduino 风格的 GPIO 宏定义和isLeftHand变量——的迁移方案与源码级原理并完整梳理本次周期中 Core、CLI、Keyboards 与 Bug 修复的全部变更清单。读完后你可以准确完成老代码向新 API 的迁移理解 QMK GPIO 抽象层与 Split 键盘左右手判定机制的底层实现并掌握该版本引入的 CLI 与构建系统改动。一、变更背景为什么 QMK 会做破坏性变更QMK 的破坏性变更集中记录在 docs/ChangeLog 目录下的按日期命名的文件中从20190830.md一直延续到20260531.md本周期对应的文档即 docs/ChangeLog/20260222.md。QMK 采用季度节奏发布 Breaking Changes先提供兼容性过渡期deprecated 警告再在后续周期正式移除。本周期移除的两个目标正是之前几个周期中已发出弃用通知的旧接口这符合 QMK 的弃用策略——过渡期结束后不再保留向后兼容层。二、移除废弃的 GPIO 定义PR #260282.1 问题背景QMK 长期使用 Arduino 风格的 GPIO 命名习惯例如DDx、PORTx、PINx这类寄存器级宏。随着平台演进这类命名不断出现新的变体也导致用户误以为 QMK 兼容整个 Arduino 生态。为此QMK 决定将 GPIO 操作函数统一重命名为符合 QMK Firmware 自身代码风格的gpio_*系列函数并在本周期移除了全部向后兼容的旧定义。2.2 现行 GPIO 抽象层 API官方推荐的替代接口完整收录于 GPIO 控制文档其核心宏定义位于platforms/platform/gpio.h每个平台一份实现抽象层与具体微控制器无关。常用宏及语义如下宏说明gpio_set_pin_input(pin)设置为高阻态输入High-Zgpio_set_pin_input_high(pin)设置为带内部上拉电阻的输入gpio_set_pin_input_low(pin)设置为带内部下拉电阻的输入AVR 上不可用gpio_set_pin_output(pin)设置为输出gpio_set_pin_output_push_pull的别名gpio_set_pin_output_push_pull(pin)设置为推挽输出gpio_set_pin_output_open_drain(pin)设置为开漏输出AVR 上不可用gpio_write_pin_high(pin)/gpio_write_pin_low(pin)将输出引脚电平置高 / 置低gpio_write_pin(pin, level)按给定电平写输出引脚gpio_read_pin(pin)读取引脚电平gpio_toggle_pin(pin)翻转输出引脚电平对于架构相关的进阶需求抽象层并不限制直接使用平台原生接口AVR 使用标准avr/io.h库STM32ChibiOS使用 PAL 库。2.3 原子性注意事项需要提醒的是上述函数并不保证原子性。若在多个 GPIO 操作组合中不希望被中断打断应使用ATOMIC_BLOCK_FORCEON宏包裹关键段例如void some_function(void) { // some process ATOMIC_BLOCK_FORCEON { // Atomic Processing } // some process }ATOMIC_BLOCK_FORCEON会无条件在块执行前关中断、执行完毕后开中断因此仅在你确定进入块前中断是开启的、且块结束时允许开中断的场景下使用。从源码结构看这套 API 已被广泛用于 QMK 内部。例如 split_util.c 中读取 Split 键盘左右手判定引脚时就调用了gpio_set_pin_input与gpio_read_pin说明新命名规范不仅是对外接口也是内部实现的一致标准。三、移除废弃的 isLeftHandPR #258973.1 迁移方式使用 Split 键盘的用户应从全局变量isLeftHand迁移到 split_util.h 提供的is_keyboard_left()函数。官方给出的典型迁移示例OLED 旋转角度按左右手区分oled_rotation_t oled_init_user(oled_rotation_t rotation) { - return isLeftHand ? OLED_ROTATION_180 : OLED_ROTATION_0; return is_keyboard_left() ? OLED_ROTATION_180 : OLED_ROTATION_0; }原文档说明废弃变量isLeftHand将在下一个破坏性变更周期被移除。而从当前仓库快照看quantum/与tmk_core/目录下已搜索不到isLeftHand的任何定义或引用可以推断该变量在后续周期本仓库 ChangeLog 序列中已有更晚的20260531.md中已被彻底清除迁移到函数式 API 已无退路。3.2 源码级原理is_keyboard_left() 是如何计算的is_keyboard_left()的声明位于 quantum/keyboard.h其实现与判定逻辑集中在 quantum/split_common/split_util.c。核心结构是一个弱符号 初始化时固化的设计is_keyboard_left_impl()弱符号可被键盘覆写按编译期宏依次采用不同判定策略——SPLIT_HAND_PIN将引脚设为输入等待 100us 后读取电平SPLIT_HAND_PIN_LOW_IS_LEFT可反转高低电平含义SPLIT_HAND_MATRIX_GRID直接窥视矩阵交点peek_matrix_intersection()即利用矩阵中的某个按键组合区分左右手EE_HANDS从 EEPROM 读取手性配置eeconfig_read_handedness()并支持INIT_EE_HANDS_LEFT/RIGHT的初始伪造逻辑MASTER_RIGHT以是否为主侧取反判定默认无宏定义左右手等价于主从侧is_keyboard_master()。split_pre_init()固化配置在键盘完全初始化之前先调用is_keyboard_master_impl()与is_keyboard_left_impl()把结果写入全局结构split_config.master/split_config.left。其中is_keyboard_master_impl()通过usb_bus_detected()判断哪一侧连着 USB 线。is_keyboard_left()本体只是一个弱符号默认返回split_config.left即启动时算一次、之后 O(1) 读取避免在高频调用路径上反复读引脚。这套机制的调用面很广从源码可以确认它被用于矩阵扫描的半侧行偏移计算quantum/matrix.c 与 quantum/matrix_common.c、Bootmagic 功能仅在右手侧启用quantum/bootmagic/bootmagic.c、RGB 矩阵左右侧 LED 索引裁剪quantum/rgb_matrix/rgb_matrix.c、LED 矩阵侧向裁剪quantum/led_matrix/led_matrix.h以及 Split 传输事务quantum/split_common/transactions.c。这正是变量改函数迁移的价值函数式接口可以统一走split_config缓存并允许用户在用户空间以 weak symbol 覆写方式自定义判定逻辑而一个裸全局变量无法提供这种扩展点。四、Core 核心变更清单本次 Core 层变更共 10 项全部继承自原文档并补充上下文重构 Makefile 中定位 keymap 的逻辑#25808keymap 查找流程收敛到 builddefs/locate_keymap.mk 等构建定义文件中属于构建系统内部重构将关机延迟移入 audio 特性#25859SHUTDOWN_DELAY_MS相关行为从通用启动路径归位到 audio 模块未启用音频的构建不再承担该逻辑重构核心代码中对废弃isLeftHand的使用#25888即上文第三节的内部迁移允许社区模块自定义数据同步#25955community modules 的data sync跨侧同步变量机制开放给第三方模块定制移除一个不可达的 break 语句#26006移除重复的 host.h#26007移除冗余的 EEPROM 更新#26008减少 Flash/EEPROM 写入与磨损均衡方向一致移除apa102_set_brightness中冗余的无符号比较#26010移除未使用的头文件#26011分配失败时返回INVALID_DEFERRED_TOKEN#26012Deferred 键码如DT(M)延迟宏在动态内存分配失败时的返回值由静默失败变为显式无效 token行为更可预测移除废弃的 GPIO 定义#26028本周期最重要的破坏性变更见第二节。五、CLI 工具链变更qmk命令行工具Python本周期改动 11 项对使用 CLI 开发流程的用户影响最大格式化文件时强制 EOL#24989qmk format输出的换行风格保持一致允许 keymap.json 关闭配置项#25502keymap 级配置可以显式 disable 某些 feature flag而不仅是 enable移除未使用的qmk.keymap.write_file/qmk.keymap.write_json内部接口#25854version.h 中加入 userspace 版本号QMK_USERSPACE_VERSION#25882使用外部 userspace 时烧录出的固件版本字符串可以区分 userspace 版本对越界 bootmagic 配置执行 lint 校验#25899并与第六节的 bootmagic 越界修复#25898配套qmk doctor报告权限问题#25931环境诊断命令能提示文件权限导致的异常CLI 格式化命令的排版微调#25946lint 新增 keymap 名称合法性校验#25969不合规的 keymap 命名会在 lint 阶段报错new-keyboard的开发板提示增加以上都不是选项#25998生成的 info.json 不再包含config_h_features#26024info.json 字段收敛feature 开关统一由构建系统推导defaults 重复检查从警告提升为错误#26025KEYMAP与LAYOUT_宏重复等冲突配置将直接导致构建失败而非静默选择。六、Keyboards 层变更与 Bug 修复6.1 键盘定义与代码整理新增Soldered Macro Pad键盘#25834对应目录 keyboards/soldered从各键盘.json中移除冗余 URL 字段#25856为projectcain/vault*增加编码器行为的守卫条件#25864避免特定构建下编码器配置冲突重构键盘与 keymap 中对废弃isLeftHand的使用#25891即键盘层面的迁移移除部分不必要的 matrix extern 声明#25975ROW_SHIFTER迁移到核心MATRIX_ROW_SHIFTER#25977行移位扫描不再依赖键盘侧定义统一由核心矩阵处理减少各键盘重复实现。6.2 Bug 修复对稳定性影响最大的一节修复 Flash 磨损均衡的扇区计算错误#24776影响 drivers/wear_leveling 模块在多次 EEPROM 写入后的扇区轮转修复 Split 键盘上 WS2812 的 LED 索引错误#25407左右两侧 LED 编号拼接逻辑修正与RGBLED_SPLIT裁剪机制相关qmk new-keymap能正确解析键盘别名#25570通过 alias 引用的键盘在创建 keymap 时不再解析失败修复 is31fl3729 LED 矩阵驱动的 off-by-one 错误#25902SPI LED 矩阵IS31FL3729行列边界偏差修正Match Key 覆写索引类型与边界类型对齐防止溢出#25939MATCH_KEY匹配覆写的索引计算改为与边界检查相同的有符号类型消除负值比较绕过问题。6.3 其他变更为 DDdouble tap双重触发键码定义补充缺失的标签#25503改善键码文档与自动补全新增面向 Pull Request 的 Copilot 协作说明#25857属于协作流程改进不影响固件行为。七、给开发者的落地检查清单全局搜索旧 GPIO 宏在你的 keymap、keyboard 与 userspace 中搜索DD[A-Z]、PORT[A-Z]、PIN[A-Z]、_HIGH/_LOW等 Arduino 风格用法全部替换为第二节表格中的gpio_*函数搜索isLeftHand替换为is_keyboard_left()并确认头文件包含来自split_util.h的声明路径quantum/keyboard.h 亦可作为声明来源升级后跑一遍qmk lint与qmk doctor本周期 lint 新增了 keymap 名称与 bootmagic 越界检查qmk doctor增加了权限诊断能提前暴露配置问题注意构建失败语义变化defaults 重复等过去仅是警告的场景现在会直接报错#26025CI 中若有忽略警告的宽松策略需要更新关注 info.json 消费方若你有脚本解析键盘info.json的config_h_features字段需要适配该字段的移除#26024。本次变更周期的完整原始记录见 docs/ChangeLog/20260222.mdGPIO 抽象层详细说明见 docs/drivers/gpio.mdGPIO 各平台实现位于 platforms 目录下对应平台的gpio.h。【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考