“Keil 4.72添加GD32F10x芯片”这事,看起来简单,实际操作起来坑真不少。很多人拿到一块GD32F103C8,第一反应是把它当STM32F103C8来用,结果新建工程时在Keil 4.72的芯片列表里翻了半天,压根找不到GigaDevice这个厂商,只能回退到STM32的型号勉强建工程。这篇文章想把这个流程从头到尾讲清楚,包括为什么要添加、添加的原理是什么、手动和自动两条添加路线,以及添加完成后新建工程最容易被忽略的配置项。适合正在用4.72做老项目维护、或者手头调试器还不支持MDK5的工程师参考。
1. 为什么要在Keil 4.72里折腾GD32F10x
先说个背景。GD32F10x是国产厂商兆易创新推出的Cortex-M3内核MCU,引脚排布、片上外设和ST的STM32F10x高度相似,价格上有明显优势。这几年很多产品从STM32换到GD32,硬件板子基本不用改,软件改动也不大。但有一个环节容易被卡住:旧的Keil MDK 4.72里没有GD32的芯片条目。
不是Keil官方不想支持,而是4.72这个版本发布时,GD32还没有像现在这样普及。Keil 5.0以后的版本通过Pack Installer装一个DFP包就能识别GD32,但Keil 4.72用的是老一套的器件数据库机制,默认只带了几个大厂家的型号,GigaDevice自然不在其中。所以想在4.72里用GD32F10x,就必须手动把芯片信息“塞”进IDE里。
很多人会问,既然Keil 5那么方便,为什么还在用4.72?我实际接触下来,原因五花八门:公司加密软件只绑定了4.72的IDE环境、老项目从十年前就一直用4.72维护、组内同事习惯了老界面的操作逻辑、以及部分旧调试器在MDK5下驱动不完善。说白了,工具不是越新越好,能把手头活干完才是核心。所以“4.72添加GD32F10x”这个需求一直存在,网上资料却大多只讲MDK5的做法,对4.72要么一笔带过,要么直接劝人升级。
这篇文章就是给那些没法立刻换MDK5的人准备的。看完你能明白Keil识别芯片的内部逻辑,能自己搞定设备数据库和Flash算法,还能避开几个网上很少有人提到的坑。
1.1 很多人搞不清的前提:MDK与C51的区别
动手之前,有一个前提必须先确认:你装的Keil 4.72是MDK-ARM版本,还是C51版本。这句话看起来像废话,但我见过太多人在这上面浪费了一下午。
Keil的安装包分成几类,C51版专门编译8051单片机,MDK-ARM版编译ARM内核芯片。GD32F10x是Cortex-M3内核,必须用MDK-ARM。如果你机器上装的是C51版本,软件打开后设备列表里全是Atmel 89C51、STC89C52这类老古董,再怎么折腾也不可能出现GigaDevice。
区分方法很简单。打开Keil,菜单栏Help -> About uVision,对话框里如果有ARM字样,说明是MDK版本;如果只有C51字样,那就是装错了。更直接的办法是看安装目录,MDK版本安装目录下会有一个ARM文件夹,C51版本没有。
如果你的电脑上同时装了C51和MDK两个版本,那还要注意启动的是哪个快捷方式。MDK4.72的安装程序默认会在桌面生成“Keil uVision4”快捷方式,但如果你后装了C51,快捷方式可能会被覆盖指向C51版本。我遇到过几次这种情况,点开软件发现是C51,还以为是MDK坏了,其实就是快捷方式指向错了。
1.2 添加芯片的实质:设备数据库与Flash算法
在Keil里看到一个芯片型号,背后实际上对应两套东西:设备数据库和Flash编程算法。
设备数据库(Device Database)是Keil用来描述芯片信息的文件,后缀一般是.pdb。里面记录了芯片型号名称、内核类型、片内Flash和RAM容量、默认的启动文件、分散加载文件等。新建工程时,你从列表里选中“GD32F103C8”,编译器就会根据这条数据库记录自动带出正确的ARM启动代码和内存布局。没有这条记录,Keil就不知道该怎么处理这颗芯片。
Flash编程算法对应的是烧录器下载程序时执行的擦写代码,文件后缀是.FLM(Flash Loader Module)。每款MCU的Flash控制器都有差异,哪怕GD32和STM32在寄存器层面再像,厂商还是会提供独立的一套FLM。烧录器下载程序时,通过这个FLM文件对目标芯片进行擦除、写入、校验。如果你在工程里选的是STM32的FLM,拿去烧GD32,运气好能烧进去,运气不好就报校验错误,或者烧进去后芯片跑飞。
所以,给Keil 4.72添加GD32F10x,说到底就两件事:把GD32的设备数据库注册进IDE,把GD32的FLM文件放到Keil的Flash算法目录里。理解了这两点,后面不管是自动安装还是手动配置,思路都会清楚很多。
2. 准备工作与材料清单
在正式开始操作之前,先把材料准备齐,不要装到一半才发现缺文件。
2.1 确认Keil安装路径和版本
先找到Keil 4.72的安装目录,默认一般是C:\Keil\。这个目录下面应该同时存在UV4和ARM两个子目录。UV4是IDE主程序所在目录,ARM目录下还有Flash、CMSIS、INC等子目录。
把安装路径记清楚,后面复制FLM、编辑TOOLS.INI都要用到。如果你的Keil安装到了D盘或者其他非默认路径,也没关系,操作逻辑一样,只是路径要跟着改。
建议顺手把C:\Keil\UV4\TOOLS.INI这个文件备份一份到桌面。TOOLS.INI是Keil启动时的核心配置文件,加载什么编译器、注册哪些设备数据库,全靠它。手动添加GD32设备数据库时需要编辑这个文件,备份一下,万一改坏了还能秒回滚。
2.2 下载GD32官方支持包
打开浏览器,去兆易创新官网找GD32F10x的Keil支持包。官网下载页一般会把文档、固件库、IDE支持包分门别类列出来,找名字里带“AddOn”“Keil”“MDK”字样的文件。
下载时注意看文件名后缀。如果是.exe结尾,这是MDK4时代的AddOn安装程序,双击后会自动帮我们把所有事情办完。如果是.pack结尾,那是MDK5的包格式,4.72不能直接双击安装,需要走后面的手动路线。
不管下载到哪种格式,我建议顺手把官方“GD32F10x Firmware Library”固件库也下了。这个固件库里有官方启动文件、系统初始化代码、外设驱动源码,后面的工程模板全靠它,省得自己从零敲寄存器。
2.3 解压后先看目录结构
拿到压缩包后先解压,不要急着双击运行。花一分钟看一下里面有什么,能避免很多奇怪的问题。
一个标准的GD32F10x支持包里,通常会有这几类东西:AddOn安装程序或.pack文件,一组.FLM后缀的Flash算法文件,可能还有一个.pdb后缀的设备数据库文件,另外就是Firmware固件库目录。
把.FLM文件和.pdb文件的路径记一下,后续手动配置时要用。有些精简版支持包可能不带.pdb文件,那也没关系,安装程序会在注册表里写信息或者直接修改TOOLS.INI;只有.FLM的话,说明设备数据库需要靠其他途径解决,最常见的方式是安装程序完成Pdb的写入。
3. 完整实操:一步步把GD32F10x装进Keil
接下来进入正题。我先讲自动安装,再讲手动配置。自动安装省事,但不是所有环境下都能成功,手动配置虽然多几个步骤,但胜在可控性好,出问题也能定位。
3.1 推荐路线:使用官方AddOn自动安装
如果支持包里带.exe安装程序,优先用这条路。双击运行安装程序后,它会要求你选择Keil安装目录,这里要选到C:\Keil这一级别,也就是UV4和ARM的上一级目录。
安装程序会自动完成三件事:把FLM文件复制到ARM\Flash目录,把设备数据库放到Keil指定位置,修改TOOLS.INI注册GD32条目。整个过程几乎是黑盒,不需要人工干预。
安装完成后启动Keil 4.72,打开Project -> New uVision Project,在弹出的芯片选择窗口左侧厂商列表里,应该能看到GigaDevice。展开之后,GD32F10x系列型号都在里面了。
这里有个容易被忽视的点:AddOn安装程序可能会默认装到C盘,哪怕你的Keil实际在D盘。如果安装时它找不到Keil路径,就会自动用默认路径,最后设备列表里依然没有GigaDevice。所以安装时一定要手动确认一下路径,不要一路Next到底。
3.2 手动添加设备数据库(AddOn失效时的备选)
自动安装失败也不代表没救了,手动添加完全可以解决。核心思路就是我前面说的两件事:放FLM,注册设备数据库。
第一步,找到解压出来的.FLM文件,把它们全部复制到Keil安装目录下的ARM\Flash文件夹里。这个文件夹里已经有很多其他厂商的FLM文件,直接把GD32的文件丢进去就行。
第二步,看支持包里有没有.pdb文件。如果有,把它复制到Keil安装目录下的UV4\DeviceDatabase目录。这个目录在部分精简版安装里可能不存在,不存在就自己新建一个。
第三步,用记事本打开C:\Keil\UV4\TOOLS.INI。在[ARM]段下面寻找形如DEVICE_DATABASE=的记录行,按同样的格式新增一行记录下来指向GD32的pdb文件。
保存后重启Keil,设备列表里就应该能看到GigaDevice了。
第三部操作务必慎重。TOOLS.INI是一个格式要求很严格的配置文件,路径分隔符、双引号、大小写都不能随意改。看到文件中已有其他设备的写法,就照抄那个格式,不要自由发挥。
3.3 校验是否添加成功
添加完了不能直接开工,先校验一下。
打开Keil,新建工程,在芯片选择窗口里找GigaDevice。如果找到了,随便选一个型号(比如GD32F103C8),点OK。Keil会弹窗问你是否复制启动文件到工程目录,选择“是”。然后看工程左边的Project窗格,应该会出现一个类似startup_gd32f10x_md.s的启动文件。
出现这个文件,说明设备数据库已经生效了,后面就可以正常写代码。如果没出现,按顺序排查:重启过Keil没有;确认是MDK版本不是C51版本;检查TOOLS.INI里新增那行路径是否正确;确认pdb文件确实在指定目录里。这一步排查完之后,95%的问题都能解决。
4. 新建工程与关键配置
芯片列表里能看到GD32,只是第一步。接下来新建工程时还有几个配置点,要是没设置对,编译和下载阶段照样会报一堆错。
4.1 选择GigaDevice芯片并搭建工程
新建工程时,在芯片选择窗口选中GigaDevice下的具体型号,比如GD32F103C8或GD32F103RCT6,注意选对Flash密度。
GD32F10x和STM32F10x一样,按Flash容量分成低密度、中密度、高密度、超高密度几个等级。Keil在创建工程时会根据设备数据库自动匹配对应的启动文件。比如GD32F103C8是64KB Flash,中密度,Keil会给你带出startup_gd32f10x_md.s;如果是256KB Flash的高密度型号,就应该用startup_gd32f10x_hd.s。
选错启动文件的后果很隐蔽。编译器不会报错,程序能正常编译,链接也能通过,但下载复位后程序常常跑不到main函数,或者某个外设中断永远不响应。这种问题排查起来非常费劲,因为不是报错,而是“玄学”故障。所以在工程搭建阶段就要确保启动文件跟芯片密度是匹配的。
4.2 启动文件与固件库:别直接用STM32的
很多做过STM32的人,拿到GD32后会习惯性把原来的STM32工程整个复制过来,只把芯片型号改成GD32。短时间点个灯、跑个串口可能没问题,但只要用到中断,就有隐患。
GD32F10x的中断向量表跟STM32F10x不是完全一样。个别中断源和寄存器名称有差异,如果用的是STM32的启动文件,链接器不会报错,但对应中断永远触发不了。这种Bug非常难查,因为它没有任何报错提示,就是功能不对。
我自己的做法是,从GD32官方固件库里复制一份标准模板工程出来,在模板的基础上改代码。官方模板的目录结构一般是Libraries\CMSIS、Libraries\Periph、Project\Templates。CMSIS里有启动文件和系统初始化代码,Periph里有外设驱动源码。把工程打开后,在C/C++选项卡的Define里加上USE_STDPERIPH_DRIVER,并按芯片密度加上GD32F10X_MD或GD32F10X_HD这类宏定义。Include Paths里要包含CMSIS和Periph的头文件目录,否则编译直接报找不到gd32f10x.h。
工程模板这块,不同版本的固件库宏定义细节略有不同,具体以你下载的固件库说明文档为准。但总的原则是:优先用官方模板和官方启动文件,别把STM32那套照搬过来。
4.3 下载算法与调试器设置
芯片选对了,编译也过了,很多人在下载这一步卡住。打开Options for Target -> Utilities,点Settings,切到Flash Download页面,Programming Algorithm列表里应该有一个和芯片容量匹配的GD32算法文件。
如果列表里只有STM32F10x的FLM,建议清掉换GD32的。因为GD32的FLM对Flash状态位、写保护的处理跟STM32有细微差别,用STM32的FLM烧GD32,偶尔会出现烧录成功但校验失败,或者第二次下载报错的奇怪现象。换成GD32自己的FLM后,这些现象基本消失。
调试器选择上,最常见的搭配是GD-Link,对应Keil里的CMSIS-DAP Debugger。用ST-Link连GD32也可以,在Debug选项卡右上角把调试器改成ST-Link Debugger。如果用的是J-Link,建议在J-Link的芯片选择界面里选Cortex-M3通用目标,能认出GD32的选项就优先选GD32。
最后,记得在Flash Download页面勾选Reset and Run。不勾的话,程序下载完不会自动复位运行,你还得手动按一下开发板上的复位键。
5. 常见问题与排错实录
下面把我在实际操作中遇到过的典型问题和排查思路整理成表格,方便你对照着快速定位。
| 现象 | 可能原因 | 处理方法 |
|---|---|---|
| 设备列表找不到GigaDevice | 设备数据库未注册 | 检查TOOLS.INI,重新运行AddOn |
| 编译报错cannot open source file "gd32f10x.h" | 固件库头文件路径没添加 | 在Include Paths里添加固件库目录 |
| Flash Download failed - "Cortex-M3" | Flash算法缺失或不匹配 | 添加对应的GD32 FLM文件 |
| 下载成功但程序不运行 | Reset and Run未勾选 / 启动文件选错 | 勾选Reset and Run,检查启动文件 |
| Debug提示No ULINK Device Found | 调试器类型选错 | 在Debug选项卡里改选实际使用的调试器 |
| Pack安装时报硬件错误 | 把MDK5的pack用在了MDK4上 | 改用AddOn安装,或手动解压配置 |
5.1 常见报错速查表
“No ULINK Device Found”这个报错,网上搜一下能出来一大堆,很多人以为是自己电脑或开发板出了问题,其实就是一个配置项的事。Keil工程默认的调试器可能被设置成了ULINK2/3,而你插的是ST-Link、GD-Link或者J-Link。打开Options for Target -> Debug,把右上角下拉框改成你实际用的调试器类型,错误立刻消失。
“Flash Download failed - Cortex-M3”这个报错,九成原因是Flash算法列表里没有GD32对应的FLM。有些工程是从STM32模板复制来的,算法列表里只有STM32F10x High-density Flash这种条目,把GD32板子接上去当然报错。处理方法就是在Flash Download页面里把STM32的算法删掉,添加GD32的FLM。
5.2 几个容易踩但搜不到的坑
有几个问题不是报错,而是行为异常,网上很难搜到标准答案,我在这里单独说一下。
第一个是GD32F10x跑高频时莫名其妙跑飞。GD32F103的最高主频比STM32F103更高,高频下Flash等待周期的设置跟STM32标准库的默认值不一定吻合。直接搬STM32的代码,在72MHz能跑,跑到108MHz或者更高时就开始复位或产生HardFault。解决办法是参考GD32固件库里的时钟初始化函数,在高频场景用官方推荐的方式设置等待周期。
第二个是外部晶振频率配置。GD32F10x的启动代码里,系统时钟默认从内部HSI启动,还是从外部HXTAL启动,不同版本的固件库行为不一样。如果你的板子上没有焊接外部晶振,但启动代码配置的是从外部晶振启动,程序就会卡在时钟初始化里。处理方式是检查system_gd32f10x.c里的时钟配置,按实际硬件情况选择晶振来源和频率。
第三个是SWD连接不稳定。降低调试器SWD时钟频率,比如从默认的4MHz降到2MHz或者1MHz,很多连接问题会自然消失。这个方法在飞线连接、杜邦线比较长、接触不良的情况下非常好用。
5.3 如果实在不行,还有一条退路
要是你花了一两个小时,4.72还是认不出GD32,或者TOOLS.INI改来改去把IDE弄崩了,我建议换个思路。
把当前工程备份一份,去官网下载Keil MDK5,在Pack Installer里搜索GD32F10x,安装对应DFP包,然后在MDK5里新建同款工程。虽然标题是4.72添加GD32F10x,但实际项目不等人。真有急事,先用MDK5把程序写出来验证完,再回头解决4.72的问题也不迟。
不过说实话,我遇到过个别“精简版”的4.72安装包,本身缺了不少组件,不管怎么改TOOLS.INI都没用。这种环境下,与其死磕,不如把MDK5当作临时方案,至少不耽误项目进度。
6. 实战中沉淀下来的一些习惯
前面把主流程讲完了,最后聊点我自己积累下来的小习惯,不算什么高深技术,但能省不少时间。
6.1 支持包离线备份与管理员权限
下载下来的GD32 AddOn支持包和固件库,我建议单独存一个离线目录,别放在浏览器的下载文件夹里让它吃灰。官网有时候会调整下载栏目,旧版本支持包可能过段时间就找不到入口了。手头留一份离线包,换电脑、帮同事配环境时都能直接拿出来用。
另外,在Windows下给Keil装AddOn时,尽量右键“以管理员身份运行”。我有一次在Win10上装AddOn,一直提示写入失败,设备列表里就是不出GigaDevice。后来发现是权限问题,安装程序往C:\Keil目录写文件时被系统拦了。换成管理员权限运行,一次成功。
6.2 用临时替换法快速验证板子
如果你只是手头有一块GD32F103C8的板子,想临时验证一下能不能跑,其实没必要专门建一个GD32工程。打开原来STM32F103C8的工程,在Options for Target -> Device里把芯片型号改成GD32F103C8(前提是设备数据库已经添加成功),再把Flash算法换成GD32的FLM,编译下载,板子基本就能跑起来。
这个方法适合“救急”,但不建议长期这么干。正式产品开发,一定要从官方模板起步,把启动文件、固件库、宏定义都切到GD32的标准上来。临时替换法只是省事,隐藏的坑可不少。
最后再分享一个小经验:遇到“Flashing失败”这类情况,别急着换硬件,先看一眼Keil左下角的Build Output窗口。很多时候提示信息已经写得非常直白了,只是我们习惯了英文报错就跳过。静下心,把报错原文逐字看懂,尤其是“not found”“failed”“missing”这几个关键词,基本都能定位到问题所在。