当前位置: 首页 > news >正文

QMK键盘固件开发全解析:QMK 固件开发的最新架构和规范(2025最新版)

QMK键盘固件开发全解析:QMK 固件开发的最新架构和规范(2025最新版)

📚 前言概述

QMK(Quantum Mechanical Keyboard)作为目前开源键盘固件领域的"扛把子",凭借其强大的功能和活跃的社区支持,已经成为众多DIY键盘爱好者的首选开发框架。无论是入门级玩家还是资深大佬,都能在QMK的海洋里找到适合自己的开发方式。

本文将为大家带来最新版本的QMK开发全解析,从零开始讲解QMK的文件结构、命名规范和开发流程,助力键盘DIY爱好者快速掌握这一强大工具。不仅如此,我们还会深入QMK的核心架构设计,解析数据驱动配置等进阶内容,帮助你从入门者迅速成长为QMK开发高手!

核心亮点:

  • 最新QMK架构详解与文件结构剖析
  • 标准命名规范与开发流程指南
  • 键盘配置文件详细说明
  • 进阶开发技巧与性能优化方案

让我们一起开启这段QMK开发之旅吧!

🔧 QMK开发规范

QMK Lint工具使用指南

QMK提供了一个强大的代码检查工具——qmk lint,它能够自动检测你的键盘配置是否符合规范。强烈建议在开发过程中经常使用它来确保你的代码质量。

通过检查的示例:

$ qmk lint -kb rominronin/katana60/rev2
Ψ Lint check passed!  # 检查通过,表示配置符合规范

未通过检查的示例:

$ qmk lint -kb clueboard/66/rev3
☒ Missing keyboards/clueboard/66/rev3/readme.md  # 缺少readme.md文件
☒ Lint check failed!  # 检查失败,需要修复问题

💡 小贴士:养成随时使用qmk lint检查代码的习惯,能帮你提前发现并解决潜在问题,避免后期调试的痛苦。

键盘项目命名规范

QMK对键盘名称有严格的命名规范,这有助于保持代码库的整洁和一致性:

  • 所有键盘名称必须全部小写
  • 只能包含字母、数字和下划线(_)
  • 名称不能以下划线开头
  • 使用正斜杠(/)作为子文件夹分隔符

特别注意:testkeyboardall是QMK的保留关键词,不能用作键盘或子文件夹的名称。

符合规范的命名示例:

412_64               # 合法:数字和下划线组合
chimera_ortho        # 合法:字母和下划线组合
clueboard/66/rev3    # 合法:使用斜杠分隔子文件夹
planck               # 合法:纯字母
v60_type_r           # 合法:字母、数字和下划线组合

子文件夹组织结构

QMK使用子文件夹来组织代码并在同一键盘的不同版本之间共享代码。子文件夹最多可以嵌套4层深度:

qmk_firmware/keyboards/top_folder/sub_1/sub_2/sub_3/sub_4

如果一个子文件夹包含rules.mk文件,它就会被视为可编译键盘,将在QMK Configurator中显示,并通过make all进行测试。对于组织多个键盘的顶层文件夹,不应该包含rules.mk文件。

组织结构示例 - Clueboard系列键盘:

qmk_firmware
└── keyboards└── clueboard  ← 组织文件夹,没有rules.mk文件├── 60     ← 可编译键盘,有rules.mk文件└── 66     ← 也是可编译的,指定rev3为默认版本├── rev1  ← 可编译:make clueboard/66/rev1├── rev2  ← 可编译:make clueboard/66/rev2└── rev3  ← 可编译:make clueboard/66/rev3或make clueboard/66

🔍 进阶提示:良好的文件夹结构不仅有助于代码管理,还能简化版本控制和团队协作。对于有多个版本或变体的键盘,使用子文件夹结构能大大提高代码复用率。

📁 键盘文件夹必要文件

开发QMK键盘需要创建一系列必要文件,下面详细介绍这些文件及其作用:

readme.md

每个键盘项目都必须包含一个readme.md文件,用于提供键盘的基本信息:

  • 键盘的功能和特点介绍
  • 制造商/设计者信息
  • 购买或获取途径
  • 相关资源链接(如官网、社区等)
# 键盘名称![键盘图片](图片链接)一款功能强大的机械键盘。* 键盘维护者: [维护者名称](https://github.com/维护者)
* 硬件支持: 详细描述硬件信息
* 硬件设计源文件: [链接](源文件链接)## 固件构建请按照[构建环境设置](链接)进行操作,然后执行:```make 键盘名称:默认配置```更多信息参考[QMK文档](链接)

info.json

info.json是QMK键盘配置的核心文件,被QMK API和Configurator使用,包含键盘布局、键位和元数据等信息:

{"keyboard_name": "示例键盘",  // 键盘名称"maintainer": "维护者",      // 维护者GitHub用户名"manufacturer": "制造商",    // 制造商名称"url": "https://example.com", // 键盘官网或项目页面"usb": {"vid": "0xFEED",           // USB厂商ID"pid": "0x0000",           // USB产品ID"device_version": "1.0.0"  // 设备版本号},"layouts": {"LAYOUT": {                // 键盘布局定义"layout": [{"x": 0, "y": 0, "matrix": [0, 0]},{"x": 1, "y": 0, "matrix": [0, 1]},// 更多按键定义...]}}
}

💡 拓展知识:QMK正在逐步向数据驱动配置迁移,将更多配置信息放入info.json中,使配置更加结构化。这种方式不仅便于图形化工具使用,还简化了固件编译流程。

config.h

config.h文件用于设置键盘的基本参数和默认值:

#pragma once  // 防止头文件重复包含/* USB设备描述符参数 */
#define VENDOR_ID       0xFEED  // USB供应商ID
#define PRODUCT_ID      0x0000  // USB产品ID
#define DEVICE_VER      0x0001  // 设备版本号
#define MANUFACTURER    "制造商名称"  // 制造商名称
#define PRODUCT         "键盘名称"   // 产品名称/* 键盘矩阵尺寸 */
#define MATRIX_ROWS 5  // 矩阵行数
#define MATRIX_COLS 14  // 矩阵列数/* 矩阵引脚定义 */
#define MATRIX_ROW_PINS { B0, B1, B2, B3, B4 }  // 行引脚
#define MATRIX_COL_PINS { A0, A1, A2, A3, A4, A5, A6, A7, C7, C6, C5, C4, C3, C2 }  // 列引脚
#define DIODE_DIRECTION COL2ROW  // 二极管方向(COL2ROW或ROW2COL)

QMK按特定顺序读取config.h文件:

  1. keyboards/top_folder/config.h
  2. keyboards/top_folder/sub_1/config.h
  3. keyboards/top_folder/sub_1/sub_2/config.h
  4. keyboards/top_folder/sub_1/sub_2/sub_3/config.h
  5. keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/config.h
  6. .build/objs_<keyboard>/src/info_config.h(数据驱动配置)
  7. users/a_user_folder/config.h
  8. keyboards/top_folder/keymaps/a_keymap/config.h
  9. 各级post_config.h文件

post_config.h文件可用于处理基于前面配置的高级设置,例如:

#ifndef IOS_DEVICE_ENABLE// 普通设备的USB最大功耗设置#define USB_MAX_POWER_CONSUMPTION 400
#else// iOS设备特殊功耗限制(低于100mA)#define USB_MAX_POWER_CONSUMPTION 100
#endif// RGB灯光配置根据设备类型调整
#ifdef RGBLIGHT_ENABLE#ifndef IOS_DEVICE_ENABLE// 普通设备的RGB亮度设置#define RGBLIGHT_LIMIT_VAL 200#define RGBLIGHT_VAL_STEP 17#else// iOS设备的低功耗RGB设置#define RGBLIGHT_LIMIT_VAL 35#define RGBLIGHT_VAL_STEP 4#endif
#endif

rules.mk

rules.mk文件标志着一个文件夹是可编译的键盘目标,用于配置构建环境和功能选项:

# MCU名称和子架构
MCU = atmega32u4  # 微控制器型号
BOOTLOADER = atmel-dfu  # 引导加载程序类型# 构建选项
BOOTMAGIC_ENABLE = yes  # 启用引导魔术键
MOUSEKEY_ENABLE = yes   # 鼠标键
EXTRAKEY_ENABLE = yes   # 媒体控制和系统控制键
CONSOLE_ENABLE = no     # 控制台用于调试
COMMAND_ENABLE = no     # 命令用于调试和配置
NKRO_ENABLE = yes       # USB N-Key Rollover支持
BACKLIGHT_ENABLE = yes  # 启用背光
RGBLIGHT_ENABLE = yes   # 启用RGB灯光
AUDIO_ENABLE = no       # 音频输出

rules.mk文件的读取顺序如下:

  1. keyboards/top_folder/rules.mk
  2. keyboards/top_folder/sub_1/rules.mk
  3. 依此类推…
  4. keyboards/top_folder/keymaps/a_keymap/rules.mk
  5. users/a_user_folder/rules.mk
  6. 各级post_rules.mk文件
  7. common_features.mk

post_rules.mk文件可以根据用户配置选择性启用功能:

# 根据用户选择的RGB灯光类型配置相应参数
ifeq ($(strip $(RGBLED_OPTION_TYPE)),backlight)RGBLIGHT_ENABLE = yesOPT_DEFS += -DRGBLIGHT_LED_COUNT=30  # 背光模式使用30个LED
endif
ifeq ($(strip $(RGBLED_OPTION_TYPE)),underglow)RGBLIGHT_ENABLE = yesOPT_DEFS += -DRGBLIGHT_LED_COUNT=6   # 底光模式使用6个LED
endif

⚙️ 技术深入rules.mk文件的逐级加载机制使QMK能够实现"继承式"配置,子文件夹可以覆盖父文件夹的设置,而自定义键映射可以覆盖默认设置,这提供了极大的灵活性。

<keyboard_name>.c

这个文件包含键盘的自定义代码,主要用于初始化和控制键盘硬件。如果键盘结构简单(只有键矩阵,没有LED、扬声器等辅助硬件),此文件可以为空。

常见函数定义:

#include "kb.h"  // 包含键盘头文件// 键盘初始化函数
void matrix_init_kb(void) {// 初始化LED引脚setPinOutput(B0);  // Caps Lock LEDsetPinOutput(B1);  // Scroll Lock LEDsetPinOutput(B2);  // Num Lock LED// 调用用户初始化函数matrix_init_user();
}// 键盘矩阵扫描函数,定期执行
void matrix_scan_kb(void) {// 添加自定义扫描代码matrix_scan_user();  // 调用用户扫描函数
}// 按键处理函数
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {// 如果用户处理函数返回false,则终止处理if (!process_record_user(keycode, record)) {return false;}// 添加自定义按键处理逻辑return true;  // 继续处理
}// LED状态更新函数
bool led_update_kb(led_t led_state) {if (!led_update_user(led_state)) {return false;}// 更新物理LED状态writePin(B0, led_state.caps_lock);    // Caps Lock LEDwritePin(B1, led_state.scroll_lock);  // Scroll Lock LEDwritePin(B2, led_state.num_lock);     // Num Lock LEDreturn true;
}

<keyboard_name>.h

此文件定义键盘的矩阵布局,将键码数组转换为表示键盘物理开关矩阵的结构:

#pragma once#include "quantum.h"// 布局宏定义,将键映射中的键码对应到物理矩阵位置
// 此例中展示了一个60%键盘的ANSI布局
#define LAYOUT_60_ansi( \K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,      K2D, \K30,      K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B,      K3D, \K40, K41, K42,                K46,                K4A, K4B, K4C, K4D  \
) { \{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, KC_NO, K2D }, \{ K30, KC_NO, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, KC_NO, K3D }, \{ K40, K41, K42, KC_NO, KC_NO, KC_NO, K46, KC_NO, KC_NO, KC_NO, K4A, K4B, K4C, K4D } \
}// 支持所有可能按键位置的完整布局
#define LAYOUT_all( \K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, \K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \K40, K41, K42, K43, K44,      K46,      K48, K49, K4A, K4B, K4C, K4D  \
) { \{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \{ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \{ K40, K41, K42, K43, K44, KC_NO, K46, KC_NO, K48, K49, K4A, K4B, K4C, K4D } \
}

当键盘支持多种布局时,应该定义相应的布局宏。例如,一个支持ANSI和ISO布局的60%键盘可以定义:

布局名称键映射名称描述
LAYOUT_alldefault支持所有可能按键位置的布局
LAYOUT_60_ansidefault_ansiANSI标准布局
LAYOUT_60_isodefault_isoISO标准布局

🛠️ 实用建议:应该始终提供全部布局的定义,而不仅仅是LAYOUT_all,这样第三方工具能更好地支持你的键盘。给布局取有意义的名称(如LAYOUT_60_ansi而非简单的LAYOUT_ansi)可以提高代码可读性。

📊 其他重要文件

图像和硬件文件

为了保持QMK代码库的轻量级,通常不接受将二进制格式的图片或文件直接添加到仓库中。建议将这些文件托管在其他平台(如Imgur)上,然后在readme.md中提供链接。

对于与键盘硬件相关的文件(PCB设计、外壳文件等),可以贡献到qmk.fm仓库,这些文件会在QMK官网上提供下载:

  • 可下载文件存储在/<keyboard>/目录
  • 网页内容生成自/_pages/<keyboard>/目录

💼 键盘默认设置推荐

QMK提供了大量功能,为避免新用户感到困惑,建议在默认固件中只启用必要的功能:

魔术键码和命令

Magic Keycodes和Command功能允许用户以特殊方式控制键盘。对于这些高级功能,建议:

  • 默认禁用或限制Bootmagic功能,避免新用户意外触发(如不小心按住Alt和空格导致这些键功能互换)
  • 如果启用,将BOOTMAGIC_KEY_SALT设置为不常用的按键组合
  • 即使禁用Command功能,也应为IS_COMMAND提供合理的默认值,方便用户日后启用

自定义键盘编程

为键盘开发自定义功能时,应考虑:

  • 确保自定义函数也调用相应的_user()版本,给用户留下自定义空间
  • 尊重用户函数的返回值,只有在用户返回true时才继续执行
  • 提供清晰的文档说明如何扩展这些功能
// 良好实践的自定义函数示例
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {// 先调用用户函数,如果它返回false则终止处理if (!process_record_user(keycode, record)) {return false;}// 键盘特定的处理逻辑...return true;  // 允许继续处理
}

非生产/手动连线项目

QMK欢迎所有使用其框架的项目,包括原型和手工连线的键盘。这类项目应放在/keyboards/handwired/文件夹中,如果将来变成生产项目,再移至主/keyboards/目录。

警告作为错误

QMK项目中所有编译警告都被视为错误。即使是看似微小的警告也可能积累并导致更严重的问题,因此应当重视并修复所有警告。

版权声明

代码文件应包含适当的版权声明:

  • 如果是你创建的新文件:

    Copyright 2025 你的名字 <your@email.com>
    
  • 如果你修改了他人的代码:

    Copyright 2020 原作者 <original_author@example.com>
    Copyright 2025 你的名字 <your@email.com>
    
  • 持续改进的文件可以使用年份范围:

    Copyright 2019-2025 你的名字 <your@email.com>
    

🚀 进阶开发技巧

数据驱动配置

QMK正在向数据驱动配置模式转变,将配置信息集中到info.json文件中:

{"keyboard_name": "高级键盘","usb": {"vid": "0xC1ED","pid": "0x23B0"},"matrix_pins": {"cols": ["A0", "A1", "A2", "A3", "A4"],"rows": ["B0", "B1", "B2", "B3"]},"diode_direction": "COL2ROW","features": {"bootmagic": true,"rgblight": true,"extrakey": true}
}

数据驱动配置的优势:

  1. 更结构化的配置方式
  2. 便于图形化工具读取和编辑
  3. 减少配置文件间的冗余
  4. 统一配置标准

优化固件大小

当固件接近芯片容量限制时,可以采取以下措施:

  1. 禁用不必要功能

    CONSOLE_ENABLE = no     # 禁用调试控制台
    COMMAND_ENABLE = no     # 禁用命令功能
    MOUSEKEY_ENABLE = no    # 禁用鼠标键功能
    EXTRAKEY_ENABLE = no    # 禁用多媒体键
    
  2. 代码优化

    • 使用查找表代替复杂计算
    • 减少全局变量的使用
    • 合并类似的函数
  3. 启用链接时优化

    LTO_ENABLE = yes        # 启用链接时优化
    
  4. 使用更高效的算法

    • 优化矩阵扫描算法
    • 简化灯光效果算法

调试技巧

开发过程中可利用QMK提供的调试工具:

// 启用调试输出
debug_enable = true;// 输出调试信息
dprintf("按键状态: %d\n", record->event.pressed);// 调试矩阵状态
debug_matrix = true;// 调试键码
debug_keyboard = true;

⚠️ 注意:发布键盘固件前记得关闭调试功能,否则会影响键盘性能。

📝 info.json深度解析

info.json文件是QMK新架构的核心,下面是一些关键配置项的详细说明:

{"keyboard_name": "超级键盘",        // 键盘名称"maintainer": "你的GitHub用户名",   // 维护者信息"manufacturer": "你的工作室",      // 制造商名称"url": "https://yoursite.com",     // 项目网址"bootloader": "atmel-dfu",         // 引导加载程序类型"processor": "atmega32u4",         // 处理器型号"usb": {                           // USB配置"vid": "0xFEED","pid": "0x0000","device_version": "1.0.0"},"matrix_pins": {                   // 矩阵引脚配置"cols": ["A0", "A1", "A2", "A3", "A4"],"rows": ["B0", "B1", "B2", "B3", "B4"]},"diode_direction": "COL2ROW",      // 二极管方向"features": {                      // 功能启用配置"bootmagic": true,"mousekey": true,"extrakey": true,"rgblight": true},"rgblight": {                      // RGB灯带配置"led_count": 16,"animations": {"breathing": true,"rainbow_mood": true,"rainbow_swirl": true}},"layouts": {                       // 键盘布局定义"LAYOUT_65_ansi": {"layout": [{"x": 0, "y": 0, "matrix": [0, 0]},{"x": 1, "y": 0, "matrix": [0, 1]},// 更多按键定义...]}}
}

🏁 总结

QMK固件框架为键盘爱好者提供了一个强大而灵活的开发环境。通过遵循本文介绍的最新架构和规范,你可以更高效地开发和维护QMK键盘项目:

  1. 使用qmk lint工具确保代码符合规范
  2. 遵循命名规范和文件夹组织结构
  3. 创建必要的配置文件(readme.mdinfo.jsonconfig.hrules.mk等)
  4. 合理设计键盘布局和默认功能
  5. 利用数据驱动配置简化开发流程
  6. 应用性能优化技巧提升用户体验

随着QMK不断发展,数据驱动配置将成为主流,建议开发者逐步熟悉并采用这种方式。无论你是创建自己的第一个键盘项目,还是为现有项目贡献代码,都应该经常关注QMK文档和社区动态,掌握最新的开发实践。

希望本文能帮助你更好地理解QMK开发流程,创建出色的键盘固件!如有问题,欢迎在评论区交流讨论。


🔗 相关资源:

  • QMK官方文档
  • QMK GitHub仓库
  • QMK Discord社区

相关文章:

  • OCP开闭原则
  • Linux系列:聊一聊 SystemV 下的进程间共享内存
  • 第十八节:图像梯度与边缘检测-Scharr 算子
  • 【Pandas】pandas DataFrame corr
  • cv_area_center()
  • 【ESP32+vscode】问题记录
  • 抖音视频去水印怎么操作
  • Harness: 全流程 DevOps 解决方案,让持续集成如吃饭般简单
  • 图像处理篇---MJPEG视频流处理
  • springboot3+vue3融合项目实战-大事件文章管理系统获取用户详细信息-ThreadLocal优化
  • 使用定时器监视当前PID 如果当前程序关闭 UI_Core.exe 也随之自动关闭实现方法
  • 【数据结构】——栈
  • PDF转Excel工具推荐 小巧免费批量自动转换
  • 优选算法——前缀和
  • springCloud/Alibaba常用中间件之Nacos服务注册与发现
  • PyTorch API 10 - benchmark、data、批处理、命名张量
  • 1.stm32使用SSD1322 驱动3.12寸OLED
  • 101alpha第九
  • 第21天打卡
  • 关于Spring
  • 广西百色通报:极端强对流天气致墙体倒塌,3人遇难7人受伤
  • 卢正已任上海市司法局党委委员、副局长
  • 湖北宜昌:在青山绿水间解锁乡村振兴“密码”
  • 巴军事行动致印度70%电网瘫痪
  • 全国人大常委会启动食品安全法执法检查
  • 国家主席习近平同普京总统举行小范围会谈