Katapult 源码导读:从 bootentry 到 sched 任务循环,看懂 ARM Bootloader 启动全流程
2026/8/22 13:20:32 网站建设 项目流程

Katapult 源码导读:从 bootentry 到 sched 任务循环,看懂 ARM Bootloader 启动全流程

【免费下载链接】katapultConfigurable bootloader for Klipper项目地址: https://gitcode.com/gh_mirrors/ka/katapult

🎯Katapult(前身为 CanBoot)是一款为Klipper3D 打印机主板设计的可配置 ARM Bootloader(引导加载器),支持 CAN、USB、UART 三种通信接口,覆盖 STM32F0/F1/F4/G0/G4/H7、LPC176x、RP2040/RP2350 等主流 MCU。本文带你从 bootentry.c 到 sched.c 任务循环,用最小代码量看懂 ARM Bootloader 启动全流程。

一、为什么需要 Katapult?

在 3D 打印主控板(如 STM32、RP2040 小板)上刷 Klipper 固件,传统方式需要 ST-Link 等烧录器。Katapult 的做法是:把引导程序常驻在 Flash 起始位置,应用固件(Klipper)放在其后的偏移地址。当需要升级时,电脑端通过 CAN/USB/UART 直接向板子写入新固件——无需任何硬件烧录器。

💡 快速上手:克隆代码后执行make menuconfig选择芯片和接口,再make即可编译:

git clone https://gitcode.com/gh_mirrors/ka/katapult cd katapult make menuconfig make

项目结构一览:

目录作用
src/generic/与芯片无关的通用逻辑(命令、串口/CAN 协议栈)
src/stm32/STM32 各系列的芯片适配代码
src/rp2040/RP2040/RP2350 芯片适配代码
src/lpc176x/LPC176x 芯片适配代码
lib/芯片头文件库、构建工具(kconfig 等)
scripts/构建与烧录脚本,核心是 flashtool.py

二、启动第一步:ResetHandler 与平台初始化

MCU 上电后,硬件从 Flash 地址 0 取第一条指令。Katapult 位于 Flash 最前端,因此第一个跑起来的 C 函数就是 armcm_boot.c 中的ResetHandler

  1. stage_one:关中断、用内联汇编显式设置栈指针(因为此时 C 环境尚未就绪);
  2. stage_tworeset_handler_stage_two):清 NVIC 中断、复位中断优先级、把.data段从 Flash 拷贝到 RAM、清零.bss段;
  3. 调用平台相关的armcm_main(),完成后永远不返回。

以 RP2040 为例,main.c 中的armcm_main做了三件事:

void noinline armcm_main(void) { enable_ram_vectortable(); // 中断向量表搬进 RAM clock_setup(); // 配置 XOSC/PLL,125MHz 主频 sched_main(); // 进入调度主循环 }

STM32 各系列(stm32f1.c、stm32f4.c、stm32h7.c 等)结构类似:向量表、时钟、外设复位各不同,但最终都汇聚到同一个入口——sched_main()

三、核心决策点:bootentry_check 该跑谁?

sched_main在 sched.c 中,它是整个 Bootloader 的"总调度":

void sched_main(void) { timer_setup(); if (!bootentry_check()) // 关键判断:进 Bootloader 还是跳应用? application_jump(); // 有有效应用 → 直接跳转 Klipper ctr_run_initfuncs(); // 执行所有 DECL_INIT 注册函数 for (;;) ctr_run_taskfuncs(); // 死循环,周期性执行所有任务 }

判断逻辑全部在 bootentry.c 的bootentry_check()中,满足任一条件就进入 Bootloader:

  1. 内存中有请求签名bootup_code == REQUEST_CANBOOT)——例如 Klipper 收到BOOT命令后通过 armcm_reset.c 写入签名再复位;
  2. Flash 应用区为空或校验失败application_check_valid()为假)——所以首次烧录 Katapult 前建议整片擦除,它会自动进入引导模式;
  3. 按钮被按住(配置了Enable bootloader entry on button时)。

若以上都不满足,还会检查双击 RESET 键(500ms 内连按两次):check_double_reset()会先写入请求签名并延时,如果用户在窗口内再按一次 RESET,签名保留、复位后自然进入 Bootloader。

🔍 应用合法性校验、跳转地址(application_jump)等实现在各芯片的 flash.c、bootentry 相关的 board/misc.h 中,canboot.h 里定义了魔数签名CANBOOT_SIGNATURE与请求码REQUEST_CANBOOT

四、零配置注册机制:ctr.h 让模块自动"报到"

Katapult 没有中央init.c来挨个调用初始化函数,而是靠 ctr.h(compile time request,编译期请求)这套精巧机制:

  • 模块只需写一行DECL_INIT(func),宏会把函数名以字符串形式放进.compile_time_request链接段
  • 构建时 buildcommands.py 从链接输出中提取这些字符串,自动生成调用代码out/compile_time_request.c
  • 最终ctr_run_initfuncs()/ctr_run_taskfuncs()就是按序调用所有注册函数。

sched.h 定义了三种注册宏:

执行时机典型用途
DECL_INIT启动时一次性执行初始化 CAN/USB/UART、LED
DECL_TASK主循环中周期性执行轮询串口、喂狗、状态灯闪烁
DECL_SHUTDOWN紧急停止时执行安全停机清理

这就是为什么每个芯片目录都有同名serial.cgpio.c:它们各自注册自己的任务,上层逻辑完全无需修改——典型的硬件抽象层(HAL)设计,与 Klipper 本体一脉相承。

五、主循环在忙什么?

进入for(;;) ctr_run_taskfuncs()后,各模块的任务函数依次轮询:

  • 协议任务(canbus.c、usb_cdc.c、canserial.c):从接口收帧、拆包,交给 command.c 的command_dispatch()
  • 命令分发CMD_CONNECT(握手)、CMD_RX_BLOCK(接收固件块)、CMD_REQ_BLOCK(回读校验)、CMD_RX_EOF(结束)等,帧格式与 CRC16 校验细节见 protocol.md;
  • Flash 写入:flashcmd.c 配合各芯片 flash.c 完成擦除/写入,写完校验后由 Klipper 请求重启进入应用;
  • 唤醒机制:中断里只做sched_wake_task()置位一个字节,主循环用sched_check_wake()读清——极简的"中断只打标记,任务里干活"模式,避免在中断上下文中做重活。

六、进阶:Deployer 免烧录器升级 Bootloader 本身

Bootloader 坏了还能救吗?Katapult 提供了 deployer.c:通过现有引导程序把新版 Katapult 刷进自己的地址区间。在 menuconfig 中勾选Build Katapult deployment application,烧录生成的deployer.bin,设备重启即完成自举升级。

⚠️ 官方提醒:升级前务必确认新配置正确,并保留 ST-Link/DFU 等备用恢复手段,否则可能变砖。

七、源码导读路线总结

按以下顺序阅读,半天即可吃透核心流程:

  1. armcm_boot.c —— 复位、建栈、清 bss(100 行内)
  2. 对应芯片main.c(如 rp2040/main.c)—— 时钟与向量表
  3. sched.c + ctr.h —— 调度与注册机制
  4. bootentry.c —— 三条件判断 + 双击 RESET
  5. command.c + protocol.md —— 通信协议
  6. flashcmd.c —— 刷写与校验

整个核心路径代码量极小、无 C 库初始化依赖,是学习裸机 ARM Bootloader 结构(向量表 → 时钟 → 启动判断 → 任务循环 → 协议栈)的绝佳教材。配合 test/configs/ 下现成的芯片配置文件(如 stm32f1.config),动手跑一遍make menuconfig && make,你就能真正"看懂 + 用会" Katapult 这套 ARM Bootloader 启动全流程了。🚀

【免费下载链接】katapultConfigurable bootloader for Klipper项目地址: https://gitcode.com/gh_mirrors/ka/katapult

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询