QMK ChibiOS 早期硬件初始化深入解析:early_hardware_init_pre、early_hardware_init_post 与 board_init 三级 API

发布时间:2026/11/11 2:28:49

QMK ChibiOS 早期硬件初始化深入解析:early_hardware_init_pre、early_hardware_init_post 与 board_init 三级 API QMK ChibiOS 早期硬件初始化深入解析early_hardware_init_pre、early_hardware_init_post 与 board_init 三级 API【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware本文聚焦 QMK 中仅面向键盘硬件设计者的一个进阶概念——Arm/ChibiOS 平台的早期初始化Early Initialization。QMK 使用 ChibiOS 作为底层 RTOS 来支撑大量 Arm 系列 MCU每台 ChibiOS 键盘都有一份低层板级定义board definition负责时钟与 GPIO 等硬件外设的初始化。读完本文你将理解 QMK 如何用三个可覆盖的弱符号 API 替代“整份复制板级定义”的老做法知道每个初始化时点能做什么、不能做什么以及如何通过config.h配置在QK_BOOT按下时于最早时机跳转到 bootloader。背景为什么需要“早期初始化”API早期 QMK 版本中如果你需要在板级定义初始化时钟、GPIO 之前就执行自己的代码唯一办法是把你所用板级定义的整份文件复制进自己键盘的目录然后在副本里修改初始化点。这种做法代价高昂板级定义更新时你的副本会漂移维护负担极重。现在的做法是直接复用 ChibiOS 自带的官方板级定义官方定义位于 QMK 仓库中 ChibiOS 子模块的lib/chibios/os/hal/boards目录完整检出后可查阅仅在你确实需要在极早阶段执行额外初始化时提供键盘级别的 API 覆盖。这些 API 的定义与调用链都集中在 tmk_core/protocol/chibios/chibios.c 中。初始化总流程从源码看三个 API 的插入位置QMK 对 ChibiOS 的两个板级入口做了“包装式覆盖”。从 chibios.c 的源码可以直接看到完整调用顺序// This overrides whats normally in ChibiOS board definitions void __early_init(void) { early_hardware_init_pre(); // This is the renamed equivalent of __early_init in the board.c file void __chibios_override___early_init(void); __chibios_override___early_init(); early_hardware_init_post(); } // This overrides whats normally in ChibiOS board definitions void boardInit(void) { // This is the renamed equivalent of boardInit in the board.c file void __chibios_override_boardInit(void); __chibios_override_boardInit(); board_init(); }即__early_initChibiOS 上电后最早执行的函数负责清 RAM、配时钟/GPIO被拆成三段先调early_hardware_init_pre()再执行原板级定义的__early_init被重命名为__chibios_override___early_init以避免符号冲突最后调early_hardware_init_post()boardInitChibiOS RTOS 内核初始化完成后调用先执行原板级定义的boardInit重命名为__chibios_override_boardInit再调board_init()。三个 API 在 chibios.c 中均以__attribute__((weak))弱符号形式给出默认实现键盘可以在自己的源文件里定义同名函数完成覆盖无需改动 QMK 核心代码__attribute__((weak)) void early_hardware_init_pre(void) { /* ... */ } __attribute__((weak)) void early_hardware_init_post(void) {} __attribute__((weak)) void board_init(void) {}下面按时间先后逐一说明每个时点的能力边界。early_hardware_init_pre固件能执行的最早代码early_hardware_init_pre是键盘固件中最早可能执行的代码等价于在 ChibiOS 板级定义__early_init函数的开头执行。它的时序约束非常严格此时RAM 尚未被清零时钟与 GPIO 也尚未配置ChibiOS 的延时wait_ms等此时基本不可能工作函数返回后MCU 的 RAM 可能被清零——在这段代码里给变量赋的值可能被覆盖。因此官方建议若覆盖此 API把用途限制在直接写低层寄存器这一类操作上。默认实现可选的 QK_BOOT 早期 bootloader 跳转默认实现并非空函数而是提供了可配置的能力在检测到QK_BOOT键被按下时于最早的初始化阶段直接跳转 bootloader 刷写固件。相关宏均在键盘的config.h中配置config.h宏说明默认值#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP是否在 QMK 早期初始化代码中执行 bootloader 跳转逻辑FALSE#define STM32_BOOTLOADER_DUAL_BANK双 bank 的 STM32 MCU 专用进入 bootloader 模式时需要翻转一个 GPIO硬件方案FALSE#define STM32_BOOTLOADER_DUAL_BANK_GPIO双 bank STM32 专用要翻转的引脚例如B8未定义#define STM32_BOOTLOADER_DUAL_BANK_POLARITY双 bank STM32 专用触发 RC 电路充电时该引脚要设置的电平0或10#define STM32_BOOTLOADER_DUAL_BANK_DELAY双 bank STM32 专用复位前等待的任意时间度量值数值越大延时越长100Kinetis MCU 无可配置项。从源码看默认实现的开关逻辑在 chibios.c__attribute__((weak)) void early_hardware_init_pre(void) { #if EARLY_INIT_PERFORM_BOOTLOADER_JUMP void enter_bootloader_mode_if_requested(void); enter_bootloader_mode_if_requested(); #endif }注意EARLY_INIT_PERFORM_BOOTLOADER_JUMP未定义时默认为FALSE见 chibios.c 的条件编译其中源码注释也明确提醒修改默认值时须同步更新本文对应的文档页。深入STM32 DFU 的两种跳转机制enter_bootloader_mode_if_requested在 STM32 平台的具体实现在 platforms/chibios/bootloaders/stm32_dfu.c它按STM32_BOOTLOADER_DUAL_BANK分两套路径单 bank可直接跳转路径利用一块“RAM 标记”机制。bootloader_marker_enable()在STM32_BOOTLOADER_RAM_SYMBOL默认为__ram0_end__前 4 字节写入魔数0xDEADBEEFbootloader_jump()置标记后调用NVIC_SystemReset()复位处理例程检测到标记即跳转 bootloader。enter_bootloader_mode_if_requested()只在标记有效时执行跳转并先关闭 Cortex-M7 的 D-Cache/I-Cache如适用、禁用 MPU、清零 SysTick 与 NVIC 中断使能/挂起寄存器恢复 MSP 与入口点后跳入。双 bank硬件 GPIO 方案路径双 bank 的 STM32 复位后无条件先执行第一个有效 flash bank无法靠软件跳转进 ROM bootloader除非 BOOT0 拉高。QMK 的对策是用硬件 RC 电路模拟 BOOT0把配置引脚设为推挽输出并按STM32_BOOTLOADER_DUAL_BANK_POLARITY置位或清零wait_ms(STM32_BOOTLOADER_DUAL_BANK_DELAY)等电容充好电再NVIC_SystemReset()——复位瞬间 BOOT0 为高ROM bootloader 得以接管。若定义了DUAL_BANK却没给引脚编译会直接#error报错提示# ifndef STM32_BOOTLOADER_DUAL_BANK_GPIO # error No STM32_BOOTLOADER_DUAL_BANK_GPIO defined, dont know which pin to toggle # endif双 bank 分支中enter_bootloader_mode_if_requested被刻意实现为空函数见 stm32_dfu.c因为该硬件路径的触发时机由板级/键盘代码显式决定。仓库中 platforms/chibios/boards/GENERIC_STM32_G474XE/configs/config.h 就是一个启用双 bank 方案的真实配置示例。除 STM32 外platforms/chibios/bootloaders/ 目录下还有uf2boot.c、rp2040.c、at32_dfu.c、gd32v_dfu.c等各 MCU 家族的 bootloader 实现。自定义 pre 阶段代码在你键盘的源文件中直接定义即可覆盖弱符号void early_hardware_init_pre(void) { // do things with registers只操作寄存器 }early_hardware_init_postRAM 已清、时钟已配后的早期窗口early_hardware_init_post是次早可执行的代码等价于在板级定义__early_init函数的末尾执行。此时 RAM 已清零、时钟与 GPIO 已配置比 pre 阶段安全得多但 ChibiOS 本身仍未初始化所以延时与计时类 API 的限制与 pre 阶段相同。官方建议把此阶段的功能限制在寄存器写入、变量初始化、GPIO 翻转。默认实现为空函数。自定义写法void early_hardware_init_post(void) { // toggle GPIO pins and write to variables }board_initChibiOS 初始化完成后的“正常”初始化board_init在 ChibiOS 初始化例程完成之后立即执行。此时包括定时器、延时在内的全部常规底层功能都可用唯一的限制是USB 尚未连接USB 驱动要等到protocol_setup/protocol_pre_init阶段才启动见 chibios.c。它对应板级定义boardInit的末尾位置默认实现为空函数。需要用到 ChibiOS API 的初始化如编码器、OLED 外设驱动等应放在这里void board_init(void) { // initialize anything that requires ChibiOS }三个时点如何选择实践速查时点RAM 状态时钟/GPIOChibiOS APIUSB适合做什么early_hardware_init_pre未清零可能被清零未配置不可用未连接仅寄存器写入如早期 bootloader 跳转触发early_hardware_init_post已清零已配置不可用延时仍受限未连接寄存器写入、变量初始化、GPIO 翻转board_init可用可用可用未连接一切需要 ChibiOS 的外设初始化选择建议能用晚的时点就不要用早的时点——pre/post 阶段的代码在时钟未稳、RAM 未定的环境下运行调试困难且风险高只有“必须在时钟配置前完成”的需求典型如 BOOT0 硬件电路的 GPIO 翻转才值得占用early_hardware_init_pre。小结QMK 的 ChibiOS 早期初始化机制通过 tmk_core/protocol/chibios/chibios.c 中的弱符号三件套early_hardware_init_pre/early_hardware_init_post/board_init把“必须整份复制板级定义才能改初始化”升级为“按初始化时点精准覆盖”让键盘开发者可以直接复用 ChibiOS 官方板级定义。配套的EARLY_INIT_PERFORM_BOOTLOADER_JUMP及STM32_BOOTLOADER_DUAL_BANK*系列配置宏则为在最早时机进入 DFU/bootloader 提供了成熟的单 bank 魔数跳转与双 bank 硬件 RC 电路两种路径其完整实现可在 platforms/chibios/bootloaders/stm32_dfu.c 中逐行核对。【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/5 4:58:03

纯前端复刻QQ音乐界面:Web课程设计实战指南

简介:面向前端初学者的QQ音乐界面模仿型Web课程设计资源,适合完成HTMLCSS课程作业、学习页面布局与交互特效的学生参考。压缩包共102个文件,主要包含HTML页面、CSS样式、JavaScript脚本、大量截图与背景音乐,包体约16.16MB&#x…

2026/11/8 18:46:08

PyTorch UNet肝脏MRI分割实战:数据预处理、模型训练与推理后处理全解

简介:一套基于PyTorch与U-Net架构的MRI肝脏图像分割完整项目方案,面向计算机专业毕业设计、课程设计以及需要医学影像实战练习的初学者。项目包含可运行的Python源码、预处理后的肝脏MRI数据集与训练好的模型权重,覆盖数据增强、模型训练、评…

2026/11/11 2:27:34

徐工特种机械销售公司到期换证流程保姆级教程

徐工特种机械销售公司到期换证流程保姆级教程 证书过期了不知道怎么复审延期?别急,今天这波保姆级教程专门给徐工特种机械销售公司员工和相关从业人员准备,讲清楚怎么在河南省应急管理厅系统上操作,确保你的特种作业证不“掉链子”,别等到项目开工才发现…

2026/11/11 2:27:34

塔河县电工证怎么复审 电子证书怎么操作才不被坑

塔河县电工证怎么复审 电子证书怎么操作才不被坑 你是不是正愁不知道去哪报名复审电工证?担心被中介套路?别急,这篇文章帮你搞懂 塔河县电工证怎么复审 ,特别是电子证书的操作流程,看完你就明白怎么避开那些坑。 电工证复审的重要性…

2026/11/11 2:27:34

巨野低压电工证怎么考内部消息曝光:找工作的“通行证”怎么拿

巨野低压电工证怎么考内部消息曝光:找工作的“通行证”怎么拿 你是不是也遇到过这样的情况?工地开工在即,岗位空缺,可你手头却没有低压电工证,连面试机会都没得谈。这年头,特种作业证就是你的“通行证”,没有它,连进工地的门槛都跨不过去。…

2026/11/11 2:27:34

成都电工证样式在哪考?证书过期了不知道怎么复审延期怎么办

成都电工证样式在哪考?证书过期了不知道怎么复审延期怎么办 证书过期了不知道怎么复审延期?你不是一个人在战斗。成都电工证样式虽然看起来统一规范,但很多人在办理、复审时却一头雾水,特别是对于像你我这样在建筑工地常年工作的平顶山在职建筑工人,一不…

2026/11/11 2:27:34

2026河南最新政策下挂电工证安全吗?驻马店电工证报考避坑指南

2026河南最新政策下挂电工证安全吗?驻马店电工证报考避坑指南 怕考不过白交培训费?2026年河南最新政策明确,特种作业操作证考试不再“走过场”,挂证风险加大,实操和理论必须双达标。作为驻马店项目现场管理员,我深知电工证不仅是上岗门槛,更是…

2026/11/10 8:12:38

电工证丢失还能补吗?千万别踩坑,丢了证等于失业

电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。…

2026/11/11 0:02:26

考低压电工证通过率考试真题与备考技巧

低压电工证通过率高不高?学历不高也能考,值不值得考? 你是不是总听说电工证能帮你找高薪工作,但又担心自己学历不够,考不上?其实,低压电工证考试门槛并没有你想象中那么高,关键是方法对不对。这篇文章就告诉你, 考低压电工证通过率到底有多高 ,…

2026/11/11 0:02:26

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名

低压电工证学时千万别踩坑,濮阳毕业生怎么避坑报名 你是不是也和我一样,刚毕业就听说低压电工证学时必须达标才能上岗?可一打听,发现报名机构五花八门,价格参差不齐, 不知道去哪报名怕被中介坑…

2026/11/10 20:08:15

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/10 10:29:37

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑