QMK Firmware 下的 1K 单键机械键盘移植指南:ATtiny85 + WS2812 + Micronucleus 全流程解析
QMK Firmware 下的 1K 单键机械键盘移植指南ATtiny85 WS2812 Micronucleus 全流程解析【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware导读1k1%是一款仅含1 颗按键的极简自定义机械键盘它由ATtiny85主控驱动板载1 颗 WS2812 RGB LED并预装micronucleus 引导程序。由于 ATtiny85 仅有 8KB Flash 与 512B SRAM要在其上跑通 QMK 固件必须大刀阔斧地裁减功能——这正是本仓库中1k键盘目录存在的意义。本文以 keyboards/1k/readme.md 为主线结合 keyboard.json、config.h、默认键映射 keymap.c 等源码系统讲解该键盘的硬件配置、空间节约策略、构建、烧录与恢复流程读者读完可完整掌握在资源受限 AVR 平台上移植 QMK 的实战方法。仓库说明1k键盘由 MakotoKurauchi 设计维护硬件可在 boothninep.booth.pm购买软件维护信息见 keyboards/1k/readme.md。硬件与固件基线1% 键盘的硬件构成主控 MCUATtiny85AVR 8 位单片机8KB Flash / 512B SRAM / 512B EEPROMLED1 颗 WS2812 可寻址 RGB LED引导程序micronucleusDigiSpark 系常用的 USB 引导程序支持通过 USB 直接烧录按键矩阵单键直连矩阵direct matrix从 keyboard.json 可以看到官方定义的设备信息{ keyboard_name: 1K, manufacturer: MakotoKurauchi, maintainer: MakotoKurauchi, usb: { vid: 0x0009, pid: 0x0001, device_version: 0.0.1 }, processor: attiny85, bootloader: custom, build: { lto: true }, features: { grave_esc: false, magic: false, space_cadet: false }, rgblight: { led_count: 1 }, ws2812: { pin: B2 }, matrix_pins: { direct: [ [B0] ] }, layouts: { LAYOUT_ortho_1x1: { layout: [ {x: 0, y: 0, matrix: [0, 0]} ] } } }关键配置一览配置项值说明processorattiny85声明目标 MCU触发 AVR 平台对应编译规则bootloadercustom不使用 QMK 内置烧录流程改由rules.mk自定义烧录命令build.ltotrue开启链接时优化显著压缩固件体积ws2812.pinB2WS2812 数据引脚接在 PB2matrix_pins.direct[[B0]]单键直连矩阵按键接在 PB0layouts.LAYOUT_ortho_1x1单键布局1×1 正交布局矩阵坐标[0,0]ATtiny85 在 QMK 平台中的定位在 QMK 的 AVR 平台定义文件 platforms/avr/mcu_selection.mk 中attiny85被单独列出ifneq (,$(filter $(MCU),attiny85)) PROTOCOL VUSB # Processor frequency. # This will define a symbol, F_CPU, in all source code files equal to the # processor frequency in Hz. You can then use this symbol in your source code to # calculate timings. Do NOT tack on a UL at the end, this will be done # automatically to create a 32-bit value in your source code. F_CPU ? 16500000 endif可以推断QMK 为 ATtiny85 选择的是V-USB软件 USB协议栈区别于 ATmega 系列常用的 LUFA 硬件 USB并且以16.5 MHz作为默认主频DigiSpark 板通常外置 16.5MHz 晶振以精确匹配 USB 时序。这也解释了为何 1k 的config.h里会出现大量针对 V-USB 的usbconfig.h覆盖宏。空间节约在 8KB Flash 里塞进 QMKreadme.md开篇特别强调Note: Due to limited firmware space, alotof features have to be disabled to get a functioning QMK based keyboard.由于固件空间极为有限要获得一个可运行的 QMK 键盘必须禁用大量功能。config.h 中的空间节约宏config.h 顶部集中定义了空间节约宏// Save as much space as we can... #define LAYER_STATE_8BIT #define NO_ACTION_LAYER #define NO_ACTION_TAPPING #define NO_ACTION_ONESHOT #define NO_RESET逐个解读宏作用节省空间的方式LAYER_STATE_8BIT将图层状态位宽从 32 位压缩为 8 位仅保留 8 个图层所需状态缩小layer_state_tNO_ACTION_LAYER禁用图层切换动作LT、MO等移除整个图层处理代码路径NO_ACTION_TAPPING禁用按键点按动作LT、MT等 Tap-Hold 功能移除点按/长按判断逻辑NO_ACTION_ONESHOT禁用一键动作OSM、OSL移除 one-shot 模块NO_RESET移除RESET键码及其复位逻辑减少复位相关代码这些宏与 QMK 顶层quantum/quantum.h及disable_features.mk中的条件编译机制配合定义后相关功能代码不再被编译从而把固件压缩到 ATtiny85 的 Flash 极限之内。keyboard.json 中显式关闭的功能在 keyboard.json 中features部分再次显式关闭features: { grave_esc: false, magic: false, space_cadet: false }即关闭GRAVE_ESC组合键、MAGIC启动命令处理、SPACE_CADET括号输入功能。加上build.lto: true开启 LTO链接时优化可跨编译单元做内联/裁剪共同构成 1k 的固件瘦身方案。空间预算引导程序留下的残垣keyboards/1k/rules.mk 中有一行不起眼却至关重要的声明BOOTLOADER_SIZE 1862它表示 micronucleus 引导程序占用1862 字节Flash应用固件实际可用空间为8192 - 1862 6330字节约 6.2KB。这也正是文档“必须禁用大量功能”的最直接量化原因。BOOTLOADER_SIZE会被链接脚本用于把引导程序保护区段保留出来避免应用固件覆盖引导程序。默认键映射单键 RGB 调色keymap.c 的实现default/keymap.c 展示了这颗唯一按键的功能——调节 WS2812 灯珠的色相#include QMK_KEYBOARD_H #include rgblite.h const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] { [0] LAYOUT_ortho_1x1( UG_HUEU ) }; bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (record-event.pressed) { switch (keycode) { case QK_UNDERGLOW_HUE_UP: rgblite_increase_hue(); break; } } return true; } void keyboard_post_init_user(void) { rgblite_init(); rgblite_increase_hue(); }可以看到默认键位绑定的是UG_HUEURGB 色相按下按键即切换灯珠颜色。同时keyboard_post_init_user()在固件启动时调用rgblite_init()完成 WS2812 初始化并立即执行一次rgblite_increase_hue()让灯珠亮起初始颜色process_record_user()拦截QK_UNDERGLOW_HUE_UP键码手动调用底层调色函数——之所以要手动处理是因为完整的 RGB 灯效模块体积过大已被裁剪。rgblite为 1k 定制的轻量 RGB 驱动由于标准RGBLIGHT功能太重1k 的键映射目录自带一个极简驱动 rgblite.h仅实现三件事static inline void rgblite_init(void) { ws2812_init(); } static inline void rgblite_setrgb(rgb_t rgb) { ws2812_set_color_all(rgb.r, rgb.g, rgb.b); ws2812_flush(); } static void rgblite_increase_hue(void) { static uint8_t state 0; hsv_t hsv { 255, 255, 255 }; hsv.h state; state (state 8) % 256; rgblite_setrgb(hsv_to_rgb(hsv)); }其工作流程为ws2812_init()初始化 WS2812 数据引脚对应 keyboard.json 中的ws2812.pin: B2构建一个 HSV 色彩饱和度/亮度固定 255色相为当前state通过hsv_to_rgb()转为 RGBws2812_set_color_all()设置唯一灯珠颜色并ws2812_flush()刷新输出每次调用色相步进8共 32 级0, 8, ..., 248循环取色。对应的 default/rules.mk 声明依赖WS2812_DRIVER_REQUIRED yes SRC color.c即启用仓库自带的 WS2812 驱动并把color.c包含hsv_to_rgb颜色转换实现加入编译。这套“手工 RGB”方案绕开了完整的RGBLIGHT框架是空间受限平台上的典型替代思路。构建固件前置准备按照 QMK 官方流程先搭建构建环境安装qmk_firmware依赖与工具链新用户可从 getting_started_build_tools 与 getting_started_make_guide 开始或直接参考 newbs 新手指南。编译命令构建 1k 默认键映射make 1k:default编译产物.hex文件会输出到build/目录。得益于build.lto: true与上述裁剪宏固件才能压缩进 ATtiny85 剩余约 6.2KB 的空间。若想自定义按键行为可在 keyboards/1k/keymaps/ 下新建键映射目录如keymaps/mykeymap/参考default目录的 keymap.c 与 rules.mk 组织文件后用make 1k:mykeymap编译。烧录固件前置条件安装 micronucleus 工具1k 使用micronucleus引导程序烧录前需先安装命令行工具git clone https://github.com/micronucleus/micronucleus.git cd micronucleus/commandline/ sudo make installLinux 下的设备权限Linux 下访问 MCU 需要合适权限两种方式任选其一每次烧录时使用sudo将 micronucleus 官方提供的 udev 规则文件49-micronucleus.rules放入/etc/udev/rules.d/然后重载规则sudo udevadm control --reload-rules sudo udevadm trigger完成后普通用户即可直接访问设备节点。烧录指令两种方式等价make 1k:default:flash # 或直接使用 micronucleus 烧录 micronucleus --run firmware.hex第二种方式的含义是micronucleus --run会等待设备复位进入引导程序通常插入/重新插拔即可触发随后把firmware.hex写入芯片并自动运行。需要说明的是make 1k:default:flash之所以能直接调用 micronucleus正是由于 rules.mk 中自定义了烧录命令PROGRAM_CMD micronucleus --run $(BUILD_DIR)/$(TARGET).hexQMK 的 AVR 平台烧录脚本 platforms/avr/flash.mk 会检查该变量并执行ifneq ($(strip $(PROGRAM_CMD)),) $(UNSYNC_OUTPUT_CMD) $(PROGRAM_CMD)同时 keyboard.json 中将bootloader声明为custom正是为了跳过 QMK 内置的 AVR ISP/DFU 烧录流程改走 micronucleus 通道。烧录时序提示micronucleus 引导程序只在芯片复位后短暂驻留。实际操作时建议先运行上述烧录命令待终端出现等待提示后再插入或重新插拔键盘触发复位即可进入烧录状态。ATtiny85 的 V-USB 软件 USB 由 config.h 中的usbconfig.h覆盖宏配置例如USB_CFG_IOPORTNAME B、USB_CFG_DMINUS_BIT 3、USB_CFG_DPLUS_BIT 4表明 D- 与 D 分别接在 PB3、PB4。恢复与救砖若固件刷坏或引导程序被破坏readme.md给出了两条恢复路径原始固件参考可参考 Attiny85 V-USB 单键键盘测试固件Attiny85_vusb_pad_test用于确认硬件与 V-USB 配置的正确性引导程序修复使用 DigiSpark 官方的proisp教程基于 AVR ISP 编程器重新烧写 micronucleus 引导程序。恢复流程一般涉及用 USBasp 或其他 ISP 编程器连接 ATtiny85 的 ISP 引脚MOSI/MISO/SCK/RESET烧写 1862 字节的 micronucleus 引导程序与 rules.mk 中BOOTLOADER_SIZE 1862对应之后即可恢复正常 USB 烧录。提示上述恢复方式依赖外部 ISP 编程器硬件属于通用 AVR 操作具体接线请以对应教程及 ATtiny85 数据手册为准。移植要点总结将 1k 的经验推广到其他资源受限平台可总结如下移植清单量化空间预算先确认引导程序占用如 micronucleus 的 1862B算出剩余 Flash开启 LTO在keyboard.json中设置build: {lto: true}裁剪核心功能在config.h定义NO_ACTION_LAYER、NO_ACTION_TAPPING、NO_ACTION_ONESHOT、NO_RESET、LAYER_STATE_8BIT等宏关闭可选功能在keyboard.json的features中显式关闭magic、grave_esc、space_cadet等轻量化外设驱动对 WS2812 等外设可仿照rgblite.h手写极简驱动绕过重量级框架自定义烧录流程在rules.mk中通过BOOTLOADER_SIZE与PROGRAM_CMD对接目标引导程序如 micronucleus并在keyboard.json中声明bootloader: custom。1k是 QMK 生态中“极限压缩”的代表作它证明了即便在只有约 6KB 可用 Flash 的 ATtiny85 上通过系统性的功能裁剪与轻量化外设驱动依然能跑通一套完整的、可编译、可烧录、可交互的 QMK 固件。对于任何希望把 QMK 移植到低成本、低资源 MCU 上的开发者keyboards/1k/ 目录都是一份难得的参考样板。【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考