野火指南者F103开发板之一: 刷入 stm32duino-bootloader 实现 DFU

为啥有这篇文章

最近我业余时间给自己的键盘刷上了 qmk 固件, 其中主控代码和 RGB 跑起来了, 但是不太理解硬件原理, 于是想到买了几年一直吃灰的野火开发版, 正好可以用来了解stm32的开发细节。

这里根据开发板的资料,一步步搭建起了专用的 qmk 固件.

这是第一篇文章,讲讲给开发板加上 bootloader。

接下来的文章内容中, 将一步一步讲解给指南者开发板修改了编译 stm32duino-bootloader 用于实现用户态 DFU 功能。

开发板基本参数和关键引脚信息。

野火指南者开发板,是一块比较老的开发板,虽然能搜到不少资料,但是内容一般。好在官方提供wiki和公开资料

基本的原理图和开发板材料我已经上传到这里了。

https://github.com/hitsmaxft/docs-yehuo-znz

由于 bootloader 提供了 usb 相关功能, 首先看下 znz 的 usb 相关电路.

usb slave原理图

它提供了常规的 mini usb规格的 usb slave,, 引脚是常规的 PA12(D+)PA11(D-)。 但它在 PA12 上加了个开关电路, 通过 PD6 控制 PA12 输出电平, 所以当 PD6 高电平时,usb 是不工作的.

stm32duino 最早是从 maple 开发板项目中 fork 出来的,它上面也有相同的设计,USB_DISC 引脚控制 usb 的断开。

剩下需要注意的是 led 指示灯和 按钮配置。

led 灯用来观察 bootloader 的工作情况, 是否在 dfu 模式。 以下是不同闪烁表示的状态

  • 启动快速闪烁:进入 bootloader
  • led 每秒闪一次: DFU 模式,等待工具写入和重置。
  • led 从闪烁到熄灭:开始引导用户代码。

一旦从 bootloader 转向用户的固件代码, 则保持LED常亮, 后面led的控制就交给用户刷入的固件了.

led原理图

野火指南者上有 3 一颗RGB led 由三个引脚控制,当引脚低电平的时候会亮起颜色, 所以不用的颜色需要将引脚设置为高电平.
这里选择绿灯 PB0, bootloader 也支持选择 0(低电平) 或者 1 表示开启.

另外还可以配置一个按钮, 用来强制进入 dfu 用的,毕竟平时拔插设备老要等 dfu 模式退出挺麻烦的,毕竟默认是 30s,一般改成 0.
需要再按住 dfu 引导按钮。

按钮原理图

这里我选择了 PA0 作为 强制进入 DFU 的按钮。

以上就是准备工作,选好合适的引脚和作用。接下来就是改写 bootloader 源码。

bootloader 选型

为什么需要bootloader?因为qmk 需要经常重新编译和更新固件,老用串口或者swd 更新很不方便,最佳选择自然是通过usb口直接更新。

比如我现在在用的 annepro2 ,按住esc上电,它就会进入固件更新 dfu 模式,这样子就算固件写错了,也没关系,重新刷就行了。

这里就需要借助 bootloader 了。 bootloader 类似电脑上装bios 或者grub,它在用户代码之前加载,可以提供诸如诊断或者代码更新等功能。很多俗称刷不死的固件,就是用到了 bootloader 实现的。比如说路由器上的 breed 。

qmk 文档中推荐基于stm32f1 的键盘使用 STM32duino-bootloader,这样可以通过 dfu-tool 或者 qmk cli 更新 主控中的 qmk 固件。

接下来介绍一下,将给指南者用的 stm32f103 添加用户态实现的 DFU 烧录支持.

什么是 DFU: DFU 是 Device Firmware update 的缩写, 也就是 “设备固件更新” 的意思。将 stm32 启动进去 dfu 模式, 可以通过 usb 接口直接更新 MCU flash 中的固件, 省去了插 stlink 写入固件的麻烦.

后续的板子, 比如我手里的 STM32F4 的开发版, 已经在板子内置了 DFU bootloader, 所以当 boot1 高电位,连着 vcc,插 usb 就直接进入 DFU 模式.
但是, 像比较古老的 STM32F1 是没有的, 也就需要借助 STM32duino 这个项目来实现了.

STM32duino-bootloader 定制和修改

STM32duino-bootloader 默认的定制构建目标里, 虽然有很多默认选项, 但是指南者的默认 PIN 比较特殊, 需要指定大部分选项才能让 bootloader 正常工作跑起来了, 我在这里给它完整重写了个一个构建目标.

Makefile 文件只是用来增加板子专用的编译选项, 不解释了.

1
2
3
4
5
6
7
8
9
10
build_yehuo-znz: TARGETFLAGS= -DTARGET_YEHUO_F103_ZNZ $(DEFINES)
# Set the linker script
build_yehuo-znz: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld
build_yehuo-znz: elf bin lss sym
copy_yehuo-znz:
@echo
@echo "Copying to binaries folder"
@echo
cp $(TARGET).bin bootloader_only_binaries/yehuo_boot20_znz.bin
@echo

接下来还需要在头文件中判断编译目标,定义宏常量。
这部分变量都是关于引脚和启动进入 dfu 的按钮或者默认模式。

板子的编译选项代码如下

title "conf.h"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#elif defined TARGET_YEHUO_F103_ZNZ

#define HAS_MAPLE_HARDWARE 1
#define BOOTLOADER_WAIT 0

#define LED_BANK GPIOB
#define LED_PIN 0
#define LED_ON_STATE 0

#define FASTBOOT 1

/* USER BUTTON is PA0 (pull down) */
#define BUTTON_BANK GPIOA
#define BUTTON_PIN 0
#define BUTTON_PRESSED_STATE 1

/* USB Disc Pin Setup. USB DISC is PD6 */
/* PD6 拉高会断开 USB, 原因见 USB 原理图 */
#define USB_DISC_BANK GPIOD
#define USB_DISC_PIN 6

  • 开启 fastboot 跳过启动默认进入dfu,需要强制时进入 DFU 按住 k1 再按 reset
  • 按一次 RESET 默认进入 DFU, 再按一次 reset 恢复正常启动。

最后, 运行 make 指令, 就能得到固件文件了

1
make  yehuo-znz

相关代码