GD32这块我断断续续接触了几年,最早是给一个客户做替换方案,后来自己项目里也在用。期间踩过不少坑,也发现网上关于GD32官方资料体系的系统性梳理其实很少,多数人都是零散地在论坛里问一句答一句。这篇文章想把GD32从选型到硬件设计、再到软件开发、最后落到手册查阅和问题排查的整个资料学习路径讲清楚,尤其适合刚入门GD32、或者准备从其他MCU平台迁过来的工程师参考。整个体系捋顺之后,你会发现遇到问题不再两眼一抹黑,而是知道该翻哪份文档、该查哪个寄存器、该去哪找例程。
1. 资料堆里的主线:GD32官方资料全景与获取路径
1.1 官方资料到底有哪些
我最早接触GD32的时候,第一反应是去官网把资料全部下载下来,结果发现光是一个F1系列就有几十个文件,看文件名又长又接近,很容易卡在"面对资料不知道从哪本开始看"的困境里。后来花了两三个月反复查阅,才把GD32官方资料体系的脉络摸清。给新手一个全局观非常重要,GD32官网的产品资料下载区,按MCU系列分类,每个系列下通常会出现以下几类文档:
- 选型手册(Product Selection Guide):覆盖整个GD32 MCU产品线,用来了解有什么型号、主频多高、Flash多大、有什么外设。
- 数据手册(Datasheet):面向具体型号,包含引脚定义、电气特性、封装信息、供电范围、时钟频率上限等。
- 用户手册(User Manual):这就是大家常说的参考手册,描述芯片内部外设的功能、工作模式和寄存器配置,是写驱动时的核心文档。
- 固件库(Firmware Library):标准外设库和CMSIS文件,配合用户手册使用,是软件开发的主战场。
- 应用笔记(Application Note):针对特定场景的深度说明,比如IAP升级、USB DFU、以太网使用等。
- 勘误表(Errata):芯片硅片级别的已知问题说明,这个很容易被忽略,但做产品前必须看。
其中最容易混淆的是数据手册和用户手册。通俗讲,数据手册告诉你"这个芯片的脚能接几伏电、能跑多快、引脚叫什么名字",用户手册告诉你"这个芯片内部的外设怎么工作、怎么配寄存器"。做硬件设计查数据手册更多,做软件驱动查用户手册更多,两者配合才完整。
1.2 从哪下载、怎么找对应型号的资料
下载资料的路径是:GD32官网 → 产品 → MCU产品系列 → 选具体型号或系列 → 资料下载。页面上会有"技术资料""软件开发""工具与支持"等分类,不同系列之间资料归档位置稍有差异,但大体一致。需要注意的一点是,GD32官网对不同系列清晰分成了F1/F2/F3/F4/F5以及E系列等,下载时不要下错系列,比如GD32F103和GD32F303资料不能混用。
另外,官网的"开发工具"栏目下会有烧录工具、IDE插件包、Embedded Builder工具等。其中IAR和Keil的插件包建议顺手下载,后面开发会用到。搜索的时候建议精确到具体型号,比如直接搜"GD32F303CBT6 datasheet",比在网站里一级级点更快。GD32的资料也经常被第三方平台转载,但版本可能滞后,我做项目时遇到过官网已经出新版用户手册而第三方还是老版本的情况,所以尽量以官网为准。
1.3 资料阅读顺序与使用节奏
我自己的经验是把这套资料当成一条流水线来用,顺序是:先选型手册确立方向,再数据手册搞定硬件,然后固件库例程配合用户手册跑通软件,最后勘误表和应用笔记来规避深坑。
千万不要拿到用户手册就从头开始读,几百页PDF没人扛得住。正确做法是先跑通一个官方例程,然后按需去用户手册里查对应外设的寄存器描述。比如你做串口,就找到USART章节,看功能框图和寄存器表,不需要把TIM、ADC、DMA全部读完。这个"按需查阅"的策略,后面章节我会单独展开讲。
2. 选型不只是看主频:从型号命名到外设取舍
2.1 型号命名规则拆解
GD32的型号命名规则和STM32高度相似,这也是很多人觉得迁移容易的原因之一。以GD32F303CBT6为例拆开看:
- GD32:品牌前缀
- F:通用型MCU产品线
- 303:产品系列号,与F1/F2/F3/F4/F5的定位差异有关
- C:引脚数,C代表48引脚,R代表64引脚,V代表100引脚,Z代表144引脚
- B:Flash容量,B代表128KB,C代表256KB,D代表384KB,E代表512KB等
- T:封装类型,T是LQFP,H是BGA,U是QFN等
- 6:温度等级,6是工业级-40℃到85℃,7是-40℃到105℃
把这套规则记下来之后,看型号就能大概猜到芯片的资源定位。比如GD32F303CBT6就是一颗48脚、128KB Flash、LQFP封装、工业级的F3系列芯片。实际选型阶段对着型号表就能快速筛选候选,然后再去数据手册确认细节。
2.2 选型前先画外设资源清单
很多人选芯片的习惯是先把主频和Flash定下来,再看外设够不够。这个顺序容易出问题。我见过不止一次,有人选完芯片后发现需要的UART数量不够,或者ADC通道数不足,导致整块板子重新设计。正确做法是先画一张外设资源清单:
- 列出所有用到的通信接口,比如几路USART、几路SPI、几路I2C、是否需要CAN、USB、以太网。
- 列出所有ADC通道数量和分辨率要求、DAC数量、定时器数量与高级定时器需求。
- 列出GPIO需求,考虑引脚功能复用冲突,尤其是一颗芯片引脚多路复用时,某些外设可能无法同时使用。
- 估算Flash占用,不用精确,但固件超过80KB时128KB的芯片会很紧张,尤其是加了协议栈或GUI后。
- 估算RAM占用,跑RTOS或者带较大协议缓冲时要格外注意,GD32的SRAM一般分为多个块,注意连续使用限制。
2.3 各系列定位差异
GD32的产品线跨度很大,选型手册里看起来眼花缭乱,但实际定位清晰:
| 系列 | 定位 | 典型主频 | 代表性资源 |
|---|---|---|---|
| GD32F1系列 | 通用入门,主打成本 | 72MHz-108MHz | 资源均衡,替代经典F103类应用 |
| GD32F2系列 | 高性能互联 | 120MHz | 大Flash大RAM,以太网MAC |
| GD32F3系列 | 主流增强 | 120MHz | 丰富模拟外设与定时器,适合电机控制 |
| GD32F4系列 | 高性能浮点运算 | 200MHz+ | 硬件FPU、DSP指令,适合算法类 |
| GD32F5系列 | 高性能安全 | 200MHz+ | 增强安全特性 |
| GD32E系列 | 超低功耗 | 较低 | 低功耗场景,电池供电设备 |
选型时千万不要只看表格里的"典型主频",因为同一个系列内部不同子型号差异也很大,比如GD32F103就有标准型和增强型之分,Flash和SRAM容量、外设数量都不完全一致。最终还是得回到对应型号的数据手册去核对。
2.4 和STM32同封装替换的兼容空间
GD32很多型号在引脚和封装上与STM32同型号兼容,这确实给硬件替换带来很大便利。但"硬件pin-to-pin"不等于"软件直接copy"。我实际替换过程中发现几个隐性差异:
- 内部RC精度和时钟树不完全一致,换芯片后调用的时钟初始化配置需要重新确认。
- 部分外设寄存器地址一致、库函数风格相似,但个别外设行为有差异,比如USART、定时器的边界条件。
- 芯片ID位置、选项字节、读保护机制不同,涉及IAP和固件加密时要单独适配。
- 调试接口的行为差异,这个问题比较常见,后面第6章专门讲。
所以选型阶段的兼容性评估,建议把"硬件兼容"和"软件可移植性"分开打分。硬件兼容高不代表软件迁移零成本,心态上要有预期。
3. 硬件设计环节:原理图参考与PCB布局布线的实际注意点
3.1 最小系统电路设计
GD32的最小系统电路和大多数ARM Cortex-M MCU类似,包含电源、晶振、复位、启动选择、下载调试接口这几个部分,但每个部分都有些细节值得留意。
电源方面,GD32通常有VDD/VSS主电源和VDDA/VSSA模拟电源,部分型号还有VCAP引脚需要外接LDO输出电容。新手容易犯的错误是只接一组VDD/VSS,忽略模拟电源引脚的去耦,导致ADC采样噪声大。原理设计时,每个电源引脚附近都要放100nF去耦电容,靠近引脚放置,模拟电源建议加磁珠隔离。
晶振方面,GD32主晶振(HXTAL)范围一般是4MHz到32MHz,具体看数据手册。很多人直接用8MHz晶振,这个最常见。需要注意晶振两端要接负载电容,容值按晶振规格书计算,常规是18pF到22pF。内部RC(IRC)可以用来跑一些对时钟精度要求不高的场景,但通信波特率、USB等对时钟精度敏感的场景务必使用外部晶振。
复位电路,NRST引脚接100nF电容到地即可,不需要太复杂的复位芯片,除非系统对电源跌落有严格要求。
启动配置,GD32有BOOT0引脚,拉低从主Flash启动,拉高进入Bootloader模式(通过串口或USB等方式烧录)。我之前遇到过客户把BOOT0悬空,上电后程序偶尔能跑偶尔不能跑,就是悬空引脚的噪声导致启动模式不稳定,处理办法是直接接10k下拉电阻。
3.2 下载与调试接口的电路处理
下载调试接口几乎是每个项目都需要的,GD32支持SWD和JTAG两种调试方式,实际开发中用SWD居多,占用引脚少且稳定。SWD电路通常是4根线:SWDIO、SWCLK、GND,外加一个供电脚(由调试器给目标板供电时使用)。
原理图上建议加一个简单的ESD保护,或者在SWDIO/SWCLK上串联33Ω电阻。这两个引脚对噪声敏感,尤其是SWCLK,走线过长或受干扰会导致调试器连接不稳定。
另外要特别注意的是,GD32的SWD引脚默认是调试功能,但如果程序里把这两个引脚重映射成普通GPIO,调试器就会连不上。这不是芯片坏了,而是调试口被复用掉了。遇到这种情况,最简单的恢复办法是使用BOOT0拉高进入Bootloader模式,或者用官方工具执行全片擦除。
3.3 PCB布局布线的几个实际注意点
硬件设计中PCB Layout决定了板子能否稳定工作,尤其对GD32这类高频MCU来说,几个细节不注意后期会很痛苦:
- 去耦电容的位置:每个VDD引脚旁边的100nF电容要尽量靠近引脚,过孔都尽量靠近电容焊盘,否则电容等效串联电感变大,高频噪声滤不掉。
- 晶振走线:晶振信号走线要短,尽量避免打过孔,周围铺地隔离。晶振下面最好不要走其他信号线,否则容易耦合噪声导致频率抖动。
- 模拟地与数字地:GD32有VDDA/VSSA独立引脚,模拟地和数字地可以在芯片附近单点连接,或者用0Ω电阻/磁珠隔离。ADC采样精度要求高时尤其要注意。
- 电源走线宽度:MCU瞬时电流不大,但尽量加宽电源走线,至少20mil以上,保证压降小。
- 复位引脚:100nF复位电容靠近NRST引脚,引线不要走太长。
3.4 参考官方评估板原理图
做硬件设计最快的路径是参考官方评估板原理图。GD32官方评估板的资料通常包含完整原理图PDF和PCB文件,这些文件在官网的资料下载区可以找到。初次设计不必自己凭空画最小系统,直接照抄官方评估板的最小系统部分,再根据项目需求增加外设电路即可。这个做法可以大幅降低第一版打样失败的概率,我做过多个项目都是用这种方式起步的。
4. 软件开发入门:从IDE选择到官方固件库的组织逻辑
4.1 开发工具链选择
GD32软件开发的主流选择有这么几种:Keil MDK、IAR EWARM、GD32官方Embedded Builder、以及VS Code配合ARM GCC工具链。
Keil MDK是使用人群最多的,网上资料和例程也最丰富。用Keil开发GD32时,需要先安装对应的Device Pack,否则Device列表里找不到GD32芯片型号。GD32官网工具页提供了适用于Keil的pack文件或插件说明,安装完成后才能在Keil里正常识别芯片型号。
IAR和Keil类似,也是商用IDE,老工程师用IAR的很多,调试性能和代码优化方面各有拥趸。
GD32 Embedded Builder是官方推出的免费IDE,基于Eclipse结构,可以理解为GD32自己的全家桶工具。它对预算有限、或者使用Linux环境下开发的人来说很友好,不需要额外购买许可证。不过Embedded Builder的插件生态和调试体验相较于Keil还有差距,我一般建议Windows下做正式项目还是Keil顺手。
VS Code配合ARM GCC是比较极客的玩法,需要自己维护makefile或CMake工程,启动文件和链接脚本需要手动配置。好处是跨平台、可脚本化,适合做CI自动化构建。比如在Linux服务器上编译GD32项目,纯命令行方式反而最方便。
4.2 官方固件库目录结构解读
从官网下载固件库压缩包解压后,第一眼看到目录结构可能会有点懵。以GD32F1系列固件库为例,核心是以下几个部分:
- Firmware/CMSIS:CMSIS是ARM Cortex-M的软件接口标准,里面包含核心寄存器定义、系统初始化代码、启动文件。启动文件在CMSIS/Device路径下,扩展名是.s,汇编写的,负责初始化堆栈、中断向量表。
- Firmware/GD32F10x_standard_peripheral:这就是标准外设库,每个外设对应一对源文件和头文件,比如gd32f10x_gpio.c/h、gd32f10x_usart.c/h。这是写驱动主要用到的库。
- Firmware/GD32F10x_usb_driver:USB相关驱动,用不到USB的可以先忽略。
- Firmware/GD32F10x_libopt.h:这个头文件通过宏定义来控制编译哪些外设库模块,可以理解为总开关。没用到哪个外设就把对应宏注释掉,可以减少编译时间。
- Project:官方例程工程目录,不同IDE对应不同子目录,里面每个外设都有demo例程。
固件库的核心逻辑和ST标准外设库相似,都是外设初始化结构体配置加使能函数。比如GPIO初始化就是声明一个gpio_parameter_struct结构体,填端口、模式、速度,然后调用gpio_init函数。这套代码风格对熟悉STM32标准库的人几乎零门槛。
4.3 第一个工程:从LED闪烁到串口打印
我刚接触GD32时跑的第一个例程是GPIO点灯,整个过程走下来,开发流程就全部串起来了。这里给一个最小步骤参考:
- 复制官方Example_GPIO工程,或者新建一个空工程。
- 把固件库的CMSIS和标准外设库源文件加入工程。
- 配置全局宏定义,比如GD32F10X_HD表示大容量型号,具体按芯片定位选择。
- 在main函数里先调用system_clock_config配置时钟,然后使能GPIO时钟,配置引脚模式为输出,再循环翻转引脚电平。
一段精简的GPIO初始化代码如下(以GD32F303为例,GPIO端口略作示意):
#include "gd32f30x.h" void gpio_config(void) { rcu_periph_clock_enable(RCU_GPIOC); gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_13); gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); } int main(void) { system_clock_config(); gpio_config(); while (1) { gpio_bit_reset(GPIOC, GPIO_PIN_13); delay_1ms(500); gpio_bit_set(GPIOC, GPIO_PIN_13); delay_1ms(500); } }跑通LED之后,建议尽快做串口打印,因为后续所有调试几乎都依赖串口输出。串口初始化需要配置GPIO复用、USART波特率、数据位、停止位等,官方例程里有现成的usart_init函数可以借鉴。串口调通之后,printf重定向就可以实现日志输出,这一步是整个GD32软件调试的基石。
4.4 调试技巧与常用配置项
软件开发过程中有几个配置项和调试技巧值得单独说明:
- 宏定义选择:固件库里很多文件是"一套代码覆盖全系列",靠宏定义裁剪不同型号差异。新建工程时必须正确配置型号宏,否则可能出现启动文件选错、外设库报错或运行异常。
- Flash下载算法:Keil的Flash Download页面要选择对应的GD32 Flash算法文件,选错会导致下载后无法运行。
- 仿真器设置:如果是第三方的DAP或ST-Link调试器,连接速度建议从低开始尝试,比如1MHz或5MHz,连接稳定后再逐步提高。GD32连接ST-Link偶尔报错,后面单独讲。
- 串口打印:用MicroLIB可以简化printf重定向内存需求,但注意MicroLIB的浮点打印会占用较多资源,必要时自己实现整数打印函数。
- 逻辑分析仪:调试协议类外设时非常有用。比如I2C、SPI通信不正常时,用逻辑分析仪抓波形看时序,比只盯着代码排查快得多。
5. 用户手册的高效阅读:从几百页PDF中提取关键信息
5.1 数据手册与用户手册的分工
我接触过不少新手,手里拿着用户手册却找不到引脚定义,或者拿着数据手册翻外设寄存器,浪费时间不说,还会被误导。所以先把两者分工讲清楚:
- 数据手册(Datasheet):讲的是芯片的"静态属性",引脚号与引脚名对照、引脚功能复用表、绝对最大额定值、工作电压范围、温度的电气特性、封装尺寸。硬件工程师画原理图、打板前必查。
- 用户手册(User Manual):讲的是芯片的"动态行为",各外设模块的功能描述、时钟分配、中断事件、寄存器列表和位定义。软件工程师写驱动时重点查这份。
5.2 用户手册的章节地图
GD32的用户手册动辄数百页,但真正高频查看的章节其实不多。以F系列的通用结构来说,建议优先掌握这几个部分:
- 系统架构与存储器映射章节:搞清Flash、SRAM、外设寄存器的地址范围,尤其是0x08000000处的程序存储区、SRAM起始地址、外设总线基地址。
- 复位与时钟控制章节:RCU相关,包含各外设时钟使能位、分频器配置。几乎每个外设驱动第一步都是“使能它的时钟”,来源就在这里。
- GPIO章节:引脚模式、复用功能映射、输出速度等。
- 具体外设章节:用哪个外设就精读哪一章,重点关注功能框图和寄存器描述。
- 中断与异常章节:NVIC优先级配置、中断向量表、外设中断请求号和对应的库函数编号。
- Flash编程章节:在线编程、IAP升级、选项字节配置相关,做Bootloader时必须看。
5.3 用倒查法反推寄存器配置
新手读寄存器描述经常会被“一大堆位定义”淹没。我的习惯是先用官方例程跑通功能,再通过例程代码倒查用户手册,把每个寄存器字段的作用弄明白。
比如用串口发送一个字节,例程里调了usart_data_transmit函数,你顺着这个函数去看库源码,发现它操作了USART_DATA寄存器,于是翻用户手册USART章节,找到DATA寄存器的说明,确认这是一块发送数据缓冲区。这样一层层推导,不仅理解了外设工作机制,也把用户手册的阅读落到了实处。
反过来看,直接从头到尾啃寄存器列表是最低效的方式,因为很多位配置对外设正常工作影响微弱,记了也容易忘。
5.4 Code Flash、SRAM与地址映射的概念辨析
GD32相关的热搜词里有一个"gd32 code flash和flash的区别",这个问题很有意思。GD32语境下,Code Flash通常指的是存放程序代码的主Flash区,起始地址是0x08000000,上电后从该地址取指执行。而广义的Flash可能还包括信息区、选项字节区、OTP区域等。做IAP升级时,理解Code Flash这个概念非常关键,因为Bootloader和App都存放在这个区域,通过修改中断向量表偏移和链接脚本将程序放到不同位置。
SRAM则对应数据存储。GD32的RAM可能分为多个块。写程序时要注意默认的堆栈大小估计是否充足,跑RTOS或大量使用动态内存时,要按实际情况调整启动文件里的堆栈定义。
另外一个经常出现在热搜词里的是“mcu时间戳”,在GD32平台实现时间戳通常有两种方案:一是用SysTick基准定时器累积ms计数,二用RTC进行日历时间记录。逻辑都比较直接,但要注意SysTick的时钟源选择,GD32的SysTick可配置为内核时钟或外部时钟,搞错了时间基准会差很多。
6. 踩坑记录:调试器报错与外设异常的排查链路
6.1 GD32连接ST-Link报Internal command error的处理路径
GD32和ST-Link的组合经常导致烧录失败。一个热搜词就是"gd32连接stlink报internal command error",这个问题我遇到过几次,也从网上大量案例中做过对比。真实排查链路一般长这样:
- 先确认接线:SWDIO、SWCLK、GND三根线是否接对,目标板是否独立供电。ST-Link给目标板供电时,要确认电压匹配。
- 排除硬件复位问题:按一下板子上的复位键,如果复位瞬间能连上,说明程序跑飞或者启动异常,可以在连接时把Reset and Run选项关闭,先连接上再单独控制复位。
- 降低调试器连接速度:ST-Link的SWD时钟如果设置过高,GD32目标板走线较长或用了杜邦线时,误码率会上升,容易报Internal command error。把速度从默认降低到1MHz试试。
- 检查代码是否禁用调试口:如果工程里配置了SWD引脚复用为GPIO,把程序下载进去之后调试口就失效了。这是非常常见的隐性原因,尤其是用了官方例程但修改过GPIO复用配置的情况。
- 尝试全片擦除:ST-Link Utility或Keil里选择Full Chip Erase,把Flash清空再重新下载。
- 更换调试器固件版本:旧版本ST-Link固件对GD32的识别有坑,升级到最新固件通常能解决。
这六步做完,绝大多数报Internal command error的情况都能找到原因。注意不要一上来就去怀疑芯片坏了,GD32芯片没那么容易坏,大概率是配置或接线问题。
6.2 外设功能不正常的排查思路
外设工作异常是嵌入式开发的日常,GD32上也不例外。我自己遇到过的跑不通问题中,大部分出在下面几个环节,排查时建议按下面顺序逐层确认:
- 时钟有没有使能:GD32每个外设都有RCU时钟开关,漏掉会使能代码时,外设寄存器写进去也没反应。
- GPIO复用有没有配对:比如USART0的TX/RX引脚必须在对应的复用功能下才能工作,配置成通用输出模式则完全不通。查到用户手册的GPIO复用表,逐一核对引脚定义。
- 中断有没有配置好:外设本身工作正常,但中断不触发,通常涉及NVIC中断使能、优先级分组配置和中断服务函数名称是否正确。库函数的中断服务函数名字要跟启动文件里的中断向量表完全一致,否则编译器不报错但中断进不去。
- 外设标志位有没有正确清除:很多通信外设有“读事件标志、软件清除”的操作顺序要求,顺序反了就会卡死在中断里。这类细节用户手册每个外设章节都会说明,遇到卡死时回头仔细看状态寄存器的清除条件。
- 复用了同一个DMA通道:多个外设共用DMA通道的优先级和触发源容易冲突,查DMA章节的请求映射表。
按这个顺序排查,基本可以覆盖90%以上“外设不工作”的场景。核心逻辑就是遵循信号路径:时钟→引脚→外设寄存器→中断/DMA→应用逻辑。
6.3 在搜索引擎和社区中精准提问
GD32资料很多,但相对ST来说社区资源还是少一些,所以检索问题的能力很重要。我的经验是搜索关键词要带全型号、外设名和报错信息,比如“GD32F303 USART DMA 接收 空闲中断”就比“GD32串口接收”精准得多。搜索时优先看官网社区、国内几家大的电子论坛和芯片代理商的技术文章。代理商提供的应用笔记往往比通用文档更贴近实战。
另外,很多问题在官方例程里其实有答案。不要只搜“怎么实现”,还要学会搜索“官方例程+功能名”,比如“GD32F3 example DMA”,先看官方是怎么做的,再改到自己的工程里,比自己从头撸要稳。
6.4 Linux环境下编译GD32工程
最后顺带提一下Linux下编译GD32项目的方案,这个需求越来越常见,尤其在CI服务器和部分开发者的主力环境是Linux的情况下。核心方案是使用arm-none-eabi-gcc工具链加Makefile或CMake。关键点是启动文件和链接脚本要从官方固件库里拿,并且要根据具体型号调整Flash起始地址和大小、SRAM起始地址和大小。Embedded Builder本身是基于Eclipse的,也可以导出Makefile工程,然后在命令行下编译。第一次在Linux下编GD32工程时会遇到一些路径改动和宏定义问题,提前把Makefile里包含头文件路径和源文件列表理清楚,后续会很顺手。
我个人做GD32项目的习惯是,拿到一块新开发板或新芯片,先花半天时间把“点灯→串口→定时器→中断”这条链路完整跑一遍,确认整个工具链、烧录流程、最小系统都正常工作,再开始业务代码。这套基础动作虽然简单,却是后面排查问题时最可靠的参照物。另外建议工程师把每颗芯片用到的资料版本记录下来,包括数据手册版本、用户手册版本、固件库版本,方便后期问题回溯。版本不匹配导致的诡异问题在国产MCU上并不少见,留个记录能省掉不少重复排查的时间。