ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Keil 4 手动集成 GD32 芯片支持包:老工程也能跑国产芯

Keil 4 手动集成 GD32 芯片支持包:老工程也能跑国产芯 前段时间有人问我手上一堆老项目用的还是 Keil 4MDK-ARM 4.54想换 GD32F103 做主控结果打开 Keil 4 的设备列表翻遍了都找不到 GigaDevice。去网上搜“GD32 接入 Keil”出来的教程十有八九是 Keil 5 的 Pack Installer 操作对不上号。我当时也卡在这个地方后来把 GD32 官方固件库和 DFP 包都翻了一遍才算弄清楚手动集成 GD32 芯片支持包的正确姿势。这篇东西不是给 Keil 5 玩家看的就是给还在维护老工程、用老 IDE、又很想吃上 GD32 这颗国产芯片的人。你不需要把整个开发环境升到最新版只要把 GD32 相关的设备数据库、Flash 算法和启动文件按老规矩塞进 Keil 4就能像用 STM32 一样建工程、点灯、跑外设库。内容会覆盖从准备文件、三种安装路径到 J-Link 烧录、DFU 驱动以及芯片读保护解锁的完整链路适合刚转 GD32 的入门用户也适合给公司做内部工程模板的老手。1. 为什么还有人要在 Keil 4 里装 GD32 支持包1.1 不是所有老工程都能说迁就迁很多人会劝你“都什么年代了赶紧用 Keil 5 或者换 VSCode”。但这种建议对实际项目没什么用。公司里大量旧代码、旧库、内部封装模块都是基于 Keil 4 工程组织的升级 IDE 看起来是小事情一旦遇到编译器版本差异、ARMCC 版本不同导致的语法告警、旧库兼容性问题改起来就不是一两天的事。尤其是一些量产了好几年的产品线工具链冻结是常态谁也不想为了换芯片把整个编译环境推倒重来。我见过不少项目代码量几十万行用的就是 Keil 4 ARM Compiler 4.x。这套组合很旧但足够稳定团队也熟悉。在这种情况下引入 GD32最好的方式不是把环境换掉而是在现有 Keil 4 上把 GD32 的支持包补上去让它能识别芯片、能烧录、能调试其他开发习惯一概不变。1.2 Keil 4 支持 GD32 的方式和 Keil 5 不同Keil 5 的芯片支持包是 CMSIS Pack 体系所有厂商、器件、Flash 算法都通过在线 Pack Installer 安装统一放在安装目录下的 PACK 文件夹里。Keil 4 则不同它更像一个“传统 IDE 数据库”的维护方式。MDK 4.50 之后的版本虽然也带了一个简化版 Pack Installer可以装 .pack 文件但大部分人手里的 Keil 4 都是早期安装包未必开启了 Pack 功能而且 GD32 早期官方支持包主要面向 Keil 4 时代设计很多资料包是以“AddOn 程序”加“FLM 算法文件”的形式发布的并不是你后来在 Keil 5 商店里看到的那种在线包。所以“手动集成”这四个字不是客气话。它指的是你要自己确认 Keil 4 的安装目录结构、找到 GD32 的 FLM 文件放哪里、设备数据库怎么加载、工程选项里怎么指定 Flash 算法。这个过程比 Keil 5 一键安装多几步但一旦摸清楚老环境也照样能开发 GD32。2. 动手前的准备确认版本、找对文件2.1 判断 MDK4 支不支持 Pack 安装版本门槛首先要看 Keil 4 具体是哪个版本。点菜单栏的 Help - About UVision 能看到版本号。如果你用的是 4.50 及以上版本IDE 自带了 Pack Installer 功能那么“手动集成”可以省掉很多功夫直接让 .pack 文件注册进去就行。如果版本低于 4.50比如 4.12、4.20 这种老版本就要走 AddOn 程序或者工程级手动集成方案。这里插一句不建议用太老的 Keil 4。GD32 的固件库和启动文件虽然兼容很老的 ARMCC但个别外设库文件的语法在老编译器上会有告警尤其是一些结构体初始化写法。我的建议是如果公司允许统一用 4.54 版本这是 MDK4 系列最后也最稳定的版本对 GD32 支持最好。2.2 该从什么地方拿到 GD32 支持包GD32 官方支持包的获取渠道要分产品线说。最经典的是 GD32F10x 系列因为和 STM32F10x 的引脚兼容性很多人第一批转的就是这个系列。官方发布过两样关键东西GD32F10x 标准固件库里面包含了 CMSIS 设备支持文件、启动文件、标准外设库GD32F10x_AddOn 或者同期的 DFP 支持包用于 Keil 集成。这些资料在 GigaDevice 官网或者它的 GitHub 组织里都能找到搜索“GD32F10x Firmware Library”就能看到。如果你的项目用的是 GD32F3xx、GD32E23x 等其他系列同样找对应的固件库和 DFP集成原理完全一样。需要特别提醒一句不要拿 STM32F10x 的启动文件和 CMSIS 文件当成 GD32 的来用。GD32F10x 虽然内核同样是 Cortex-M3在电气和寄存器层面也大量借鉴了 STM32F10x 的设计但它的时钟树、Flash 控制器、部分外设寄存器地址跟 ST 有差异混用的结果是能编译、能下载但跑起来大概率死机。后面我会专门讲怎么选启动文件。2.3 支持包里到底装了哪些东西一个典型的 GD32 Keil 4 支持包解压后你会看到这几类文件文件/目录作用在 Keil 4 中归属.pack 文件CMSIS Pack 封装MDK4.50 可直接安装PACK 目录.pid 文件旧版设备数据库文件用来在 Device 列表里新增厂商UV4 设备数据库.FLM 文件Flash 编程算法Keil 下载程序时按这个算法擦写芯片ARM\Flashstartup_gd32f10x_*.s芯片启动文件包含中断向量表、堆栈初始化工程内system_gd32f10x.c系统时钟初始化代码工程内搞清楚这个结构你就知道手动集成到底要“动”哪里了。设备数据库解决的是“选芯片”的问题Flash 算法解决的是“烧写”的问题启动文件解决的是“运行环境”的问题。这三样对不上就会出现芯片列表里有 GD32 但下载报错或者下载成功但板子不跑的情况。3. 把 GD32 芯片支持包装进 Keil 4三种可行路径3.1 路径一双击 .pack 交给 Pack Installer如果你用的是 MDK 4.54并且安装的时候没有精简掉 Pack 支持这是最顺畅的方式。拿到 GD32F10x 对应的 .pack 文件后直接双击Keil 的 Pack Installer 会弹出来并提示安装。安装完成后在 UVision 中打开工程选项的 Device 页签左侧厂商列表里会出现 GigaDevice展开就能看到对应的 GD32F10x 系列型号。这里有一个坑老的 .pack 文件可能没有数字签名双击后系统直接弹一个 “Do you want to install this pack?” 的对话框你点 Yes 之后可能什么都没有发生。原因是 Pack Installer 装完后不会自动刷新设备列表你需要把 Keil 4 完全关掉重开或者新建工程时才能看到新芯片。我当时就被这个坑了十分钟以为没装上后来重启一次 UVision 就出现了。如果你下载到的是压缩包解压后里面有一个 Arm.GigaDevice.GD32F10x_DFP.x.x.x.pack同样可以直接双击。如果双击没反应也可以打开 Keil 4 菜单的 Project - Manage - Pack Installer用 File - Import 的方式手动选择 .pack 文件导入。3.2 路径二使用官方 AddOn 程序自动安装早期 GD32 的 Keil 4 支持通常以“AddOn”形式发布。你解压固件库之后会找到一个类似 GD32F10x_AddOn.exe 的安装程序。运行它之前先确认 Keil 4 已经关闭然后执行安装程序会自动检测 Keil 安装路径把 .pid 设备数据库写进 Keil 的数据库目录把 .FLM 算法文件复制到 Flash 目录。这种方式的好处是不用管文件细节坏处是太老的 AddOn 程序可能只认默认路径 C:\Keil。如果你的 Keil 4 装在 D 盘或者自定义目录安装程序找不到时会报错或者装到错误位置。遇到这种情况建议用路径一或者干脆用路径三的工程级手动集成。判断 AddOn 是否安装成功还是老办法打开 Keil 4在 Device 数据库里找 GigaDevice。如果找不到可以看看 Keil 安装目录下 Flash 文件夹里有没有 GD32F10x_128.FLM 这类文件以及 DeviceDatabase 目录里有没有 Gigadevice 相关文件。文件在但界面不显示多数是 .pid 数据库没有被正确注册重启软件或重新运行 AddOn 基本能解决。3.3 路径三工程级手动集成不依赖设备数据库也能干活如果你的 Keil 4 实在太老、PACK 功能不可用AddOn 程序又装不上还有一种最“笨”也最通用的办法不在设备列表里选派 GD32而是选一颗 Generic Cortex-M3 通用器件然后把 GD32 的启动文件、CMSIS 文件、Flash 算法文件手动加到工程里。具体来说新建工程时在 Device 页签选择 “Generic” 厂商下的 “Cortex-M3”不要在意它显示为通用 ARM 内核。后续需要做四件事把 GD32 官方固件库中的 startup_gd32f10x_hd.s 添加到工程的 Startup 组把 system_gd32f10x.c 和对应的头文件加到工程的 CMSIS 组在 C/C 编译选项里指定 Include 路径并定义 GD32F10X_HD、USE_STDPERIPH_DRIVER在 Debug 或 Utilities 页面选择 J-Link 仿真器进入 Flash Download 设置手动添加 GD32F10x 对应的 .FLM 文件。这种方式的本质是绕过“设备数据库”这一层把和芯片相关的所有信息都放到工程里。它不太好的一点是设备选型界面上没有具体型号工程名称里得自己写型号标识不然拿到同事那里容易搞混。但它的兼容性最好几乎所有 Keil 4 版本都能跑。3.4 确认芯片已经出现在 Device 列表不管走了哪条路最终都要做一次验证。最简单的验证方式是新建一个临时空工程在 Device 界面看左侧列表是否有 GigaDevice。如果出现了点开以后能看到具体芯片型号比如 GD32F103C8T6。选中它之后工程会自动带上对应的启动文件吗不会。Keil 4 没有那么智能GD32 的启动文件和系统文件通常还是要从固件库复制进工程目录这个和 Keil 5 里 Pack 自动帮你说好了一切不同。所以说就算设备数据库添加成功也不能省掉后面手动建工程模板的步骤。设备数据库解决的是“让编译器知道这颗芯片有多少 Flash、多少 RAM、支持哪些配置”但具体跑什么代码还是得靠工程文件。4. 从选芯片到点灯搭建一个 GD32 标准工程模板4.1 新建工程与器件选择我以 GD32F103C8T6 为例这颗芯片 64KB Flash、20KB RAM不同批次可能略有差异在 Keil 4 里新建工程时只要设备数据库已经装好直接选 GigaDevice - GD32F10x Series - GD32F103C8T6 就行。选完芯片后Keil 4 会弹一个对话框问你是否要复制标准启动文件到工程目录。因为 GD32 不在 Keil 默认的启动文件列表里这个对话框大概率给你一个空模板或者一份 ST 的启动文件。千万不能选默认的 ST 启动文件正确做法是取消自动复制之后手动添加 GD32 固件库里的启动文件。工程目录我建议按下面的结构搭Project_GD32F103C8T6/ ├── User/ │ ├── main.c │ ├── gd32f10x_it.c │ ├── gd32f10x_it.h │ └── system_gd32f10x.c ├── Libraries/ │ ├── CMSIS/ │ │ ├── core_cm3.c / core_cm3.h │ │ └── system_gd32f10x.c / system_gd32f10x.h │ ├── Device/ │ │ └── startup_gd32f10x_hd.s │ └── Peripheral/ │ ├── gd32f10x_adc.c/h │ ├── gd32f10x_gpio.c/h │ └── ... └── Project/ └── 工程文件所在目录别嫌目录多GD32 标准库本身区分外设库、CMSIS 和设备支持三层分好目录以后换工程、升级库都方便。4.2 启动文件、系统初始化与工程目录规划启动文件是 GD32 最容易踩坑的地方。GD32F10x 的启动文件通常有 low_density、medium_density、high_density 三个版本分别对应不同 Flash 容量的型号。GD32F103C8T6 是 64KB Flash属于 medium_density应该选 startup_gd32f10x_md.s如果用的是 GD32F103ZET6 这种 512KB 的芯片选 startup_gd32f10x_hd.s。启动文件放进工程之后还要确认系统初始化函数有没有被调用。Keil 4 的启动文件在 Reset_Handler 里会调用 SystemInit 函数这个函数在 system_gd32f10x.c 里实现作用是配置系统时钟到 108MHz 或者 72MHz。GD32F103 的内部时钟树和 STM32F103 不完全一样直接用 ST 的 system_stm32f10x.c 会得到错误时钟所以必须使用 GD 库中的 system_gd32f10x.c。这一步的检查方法是编译后在调试状态下看 SystemCoreClock 变量的值如果跑出来频率跟你在 SystemInit 里配置的不一致基本上就是文件版本混用了。4.3 C/C 编译选项那几个宏和内联能省心在工程选项的 C/C 页面需要关注两项一个是 Define一个是 Include Paths。GD32F10x 标准库头文件的逻辑和 STM32 标准库几乎一样通过预定义宏来选择芯片密度和驱动模式。我经常用的组合是GD32F10X_MD, USE_STDPERIPH_DRIVER如果是大容量芯片把 GD32F10X_MD 换成 GD32F10X_HD如果用到 USB 外设还要额外定义 GD32F10X_USB_FS。这里的宏名必须和你固件库版本匹配新版固件库可能改用 GD32F10X_HD 等定义打开 gd32f10x.h 文件能看到条件编译开关自己确认一下就好。Include Paths 则要把这些目录添加进去固件库根目录CMSIS 核心目录设备支持目录标准外设库头文件目录很多编译报错 “device.h: No such file or directory”基本都是 Include Paths 没加全。这个没有捷径只能一个个目录往里面加加到不报错为止。还有一个容易忽略的选项在 C/C 页面打开 “One ELF Section per Function” 或者使用 “--split_sections” 编译器选项这样就算某个外设驱动有未被调用的函数也不会全部塞进最终镜像。对 Keil 4 ARMCC 来说这个选项能明显减少固件体积尤其在 GD32F103 这种 Flash 只有 64KB 的芯片上很实用。4.4 Flash 下载算法配置必须单独处理工程能编译通过同也选对了芯片不代表下载就一定能成功。第一次下载时我遇到最多的问题就是 Keil 弹出No Algorithm found for: 08000000H - 0800FFFFH原因是 Flash 编程算法没有配。在工程选项的 Utilities 页面点击 Settings 进入 Flash Download 配置把下方的 Programming Algorithm 列表清空然后点击 Add找到 GD32F10x 对应的 FLM 文件。常见的 GD32F103 算法文件是 GD32F10x_128.FLM它适用于 128KB 或者更小 Flash 的型号。如果你的芯片是 512KB可能要用 GD32F10x_512.FLM。这个东西不能配错否则擦除地址范围对不上下载时会报加载算法失败。如果你是走路径三的通用 Cortex-M3 方式这里必须手动指定 Flash 算法不然烧录根本没法进行。用路径一安装 DFP 之后Keil 4 有时候会自动带出算法但如果工程是从 STM32 改过来的算法列表里可能残留着 STM32F10x 的 FLM同样会导致下载异常所以要记得清掉旧的再添加 GD32 的。5. 烧录调试环节最容易踩的坑5.1 J-Link 连不上或烧一半报错用 J-Link 烧录 GD32 是很多人第一选择因为它调试速度快、断点功能正常。风险也出在 J-Link 驱动上。老版本 J-Link 驱动对 GD32 的支持不好最典型的现象是能识别 Cortex-M3 内核但读不到芯片 ID或者一连接就报Cannot connect to target.这个问题的排查思路是这样的先确认接线SWDIO、SWCLK、GND 三根线是必须的3.3V 供电最好也从板子引不要依赖下载器供电。排除接线后再确认 GD32 是不是进入了异常模式比如程序里开了读保护或者把时钟配置错了导致调试端口失效。最后才考虑升级 SEGGER 的 J-Link 驱动到新版本新驱动已经能正确识别 GD32F10x 的 ID Code。如果连接上了但烧到一半报错比如Failed to flash: Data mismatch at address ...这种大概率是 Flash 算法选错了或者时钟频率设定太高。J-Link 连接时默认的 SWD 频率可能在几 MHz如果板子布线质量一般高速下载很容易出错。在 J-Link 设置里把速度从 5MHz 降到 1MHz 甚至 400kHz通常就能稳定烧录。还有一个细节Keil 4 的 Debug 设置里如果你选的是 J-LINK/J-TRACE Cortex右侧会有电源选项不要勾选 “Connect under Reset”。GD32F103 的复位引脚在大部分孔板应用里接了上拉电阻靠硬复位连接不一定稳定默认的 normal connect 反而更容易成功。总之下载不稳定时分三步走降速、换接线、换算法。5.2 换用 DFU/串口 ISP 下载时驱动识别不是所有人都有 J-LinkGD32 官方也提供 DFUDevice Firmware Upgrade下载方式通过 USB 进入 bootloader 后使用官方工具烧写。GD32 板卡如果带了 USB 口并且芯片烧录了官方出厂 bootloader插上 USB 后电脑会提示安装驱动。这个 DFU 驱动值得单独说一句。Windows 10 以上系统经常自动把设备识别为未知设备或者识别成 ST 的 DFU 设备因为 GD32F10x 的 USB VID/PID 和 ST 某些产品非常接近。解决办法是手动指定驱动在设备管理器中点击“更新驱动”选择“从计算机查找驱动”路径定位到你解压的 DFU 驱动目录安装之后设备会显示为 GD32 DFU Device 或者类似的名称。如果不想折腾 USB DFU用串口 ISP 下载也是一种非常稳定的方式。GD32F103 的 BOOT0 引脚拉高BOOT1 拉低复位后进入 bootloader然后用官方 GD32 MCU ISP Programmer 或者第三方串口工具选择对应的串口和波特率就能擦除、下载。这里的坑是很多板子的 BOOT0 和 BOOT1 拨码开关容易被人忽略一旦没有正确设置串口工具会一直报“连接失败”其实芯片就没进 bootloader。5.3 读保护导致的“锁死”与解锁操作GD32 单片机用久了之后迟早会遇到“锁死”问题。我自己的经历是项目里启用了读保护RDP功能然后又用 J-Link 反复下载了几次突然有一天 Keil 报错误代码 0xFE、0x??目标地址无法擦除。那块板子看上去就像芯片锁死了一样。GD32 的读保护分等级大多数情况下只是 Level 1 保护芯片可以通过全片擦除来解除。解锁方法有几个用 J-Link Commander 命令行工具输入 unlock GD32F103具体命令看版本或者用 erase 全片擦除用 GD32 MCU ISP Programmer 通过串口 ISP 连接选择“全片擦除”擦除后读保护自动解除如果读保护被设成了 Level 2调试接口和串口 ISP 都无法再操作只能换一片芯片。这个在设计阶段就要注意不要在量产固件里随便设 Level 2。我个人的建议是开发板上尽量不要开启读保护等量产前再根据产品需求决定是否打开。否则每次调试遇到擦除失败都要走一遍 “串口 ISP 全片擦除”的流程非常浪费精力。6. 集成完成之后还有几条路可以走6.1 这套手动集成方法留给后续项目的“模板价值”在 Keil 4 里手动集成一次 GD32 支持包得到的其实不止是“能识别芯片”这一个结果。更重要的是一整套可复用的工程模板。整理好后的工程模板包含正确启动文件、系统时钟配置、外设库和 Flash 算法以后同事新开项目时直接复制这个模板再改目录名不需要再走一遍装 Pack、添加算法、配置宏定义的流程。模板建立后建议把关键信息写成一个 README 文件放在工程根目录里记录下 Keil 4 版本、GD32 固件库版本、芯片型号、启动文件名字和 Flash 算法名字。这个习惯能解决很多“过三个月回来不知道当时怎么搞的”的问题。嵌入式项目最怕的就是环境信息不透明一个能跑的老工程被反复折腾到不能编译往往就是缺少了这些记录。6.2 什么时候可以考虑迁到 Keil 5 或 VSCode EIDE如果你是新项目、新团队那说实话我不建议再用 Keil 4。Keil 5 的 Pack 生态确实方便GD32 的 DFP 在线安装一次就完成兼容性和调试体验也更好。但如果你在维护老产品这套手动集成方式足够用完全没必要为了“新”而乱动工具链。另外一个值得关注的方向是 VSCode 加 EIDE 插件开发 GD32。EIDE 本质上帮你管理工程文件、编译器、烧录器配置底层用的还是 ARMCC 或者 GCC 的工具链。很多人在 Keil 4 里做了支持以后再用 EIDE 建一个同样源码的 GCC 工程两者共用 Libraries 和 User 目录这样即便有一天 Keil 4 在 64 位新系统上跑不了你还有另一个备份环境。GD32 的官方库和启动文件本来就是跨编译器的只要头文件宏定义和启动文件选对移植到 GCC 并不难。老实说我在把 GD32 接进 Keil 4 的过程中踩了不少坑但回头看核心问题就三类数据库没装上、Flash 算法没换、启动文件用错。把这三件事吃透其他都只是工程配置里的重复劳动。这篇东西最初是为了给自己留一份踩坑记录后来顺手做成模板分享给了团队同事希望能给同样被 Keil 4 绑住手脚的人一点参考。
返回列表