首页 / 资讯中心 / 文章详情

国产MCU替代STM32一年实测:GD32与CH32V103的兼容性、RTOS与踩坑总结

国产MCU替代STM32一年实测:GD32与CH32V103的兼容性、RTOS与踩坑总结 ★ FEATURED ARTICLE
1. 从一块GD32换掉STM32说起我为什么要做这个长期测试去年年初我手上有个小批量的工控板项目原本用的是STM32F103C8T6结果采购那边反馈交期拉长、价格浮动大问我能不能看看国产替代。说实话当时我心里是打鼓的。早些年用过几款国产MCU踩过不少坑——有引脚兼容但时序对不上的有库函数缺胳膊少腿的还有号称Pin-to-Pin结果连复位电路都要改的。但架不住成本压力和供货压力我还是决定认真做一轮长期测试而不是像以前那样点个灯就跑。这一测就是一年多。期间我陆续把GD32、CH32V103、还有几款RISC-V内核的芯片用在了不同的项目里有跑FreeRTOS的物联网网关、有带ILI9341屏的HMI小终端、有控制五线四相步进电机的运动控制板、也有简单的ADC采集加串口上报的传感器节点。这篇文章不是厂商软文也不是情绪化的国产崛起或国产不行就是一个一线工程师用了一年之后把真实感受、踩过的坑、以及什么场景下我会推荐用、什么场景下我仍然坚持用STM32原原本本讲清楚。如果你正在做选型或者被供货和成本逼着想试试国产替代又或者你只是好奇国产芯片到底行不行那这篇内容应该能帮你省下不少试错时间。我会从最核心的兼容性、工具链、外设差异、RTOS与协议栈支持、以及长期运行稳定性这几个维度展开每个结论都尽量给出我实际测试的场景和依据而不是空泛地讲能用或不能用。2. 引脚兼容不等于代码兼容GD32替换STM32的真实体验2.1 表面上的Pin-to-Pin藏着一堆时序细节GD32F103系列和STM32F103在引脚上基本是Pin-to-Pin的这也是很多人选择它的第一理由。我最初也是这么想的板子不用改直接把STM32焊下来换GD32烧进去应该就能跑。实际测试下来简单的GPIO点灯、串口打印确实没问题但一旦涉及到Flash读写、ADC采样时序、以及USB通信差异就出来了。最典型的是Flash。GD32F103的Flash访问速度比STM32快官方标称零等待周期可以跑到更高主频但这意味着如果你代码里有依赖Flash等待周期的延时逻辑换芯片后时序会变。我当时有个项目用Flash模拟EEPROM写入后靠固定延时等待完成换GD32后延时偏短偶发写入失败。后来改成读状态寄存器判断问题才解决。这件事给我的教训是引脚兼容只是硬件层面的软件层面的时序假设必须重新验证。另一个坑是ADC。STM32F103的ADC在切换通道后需要一定的采样稳定时间GD32的ADC建立时间特性不同。我在一个多通道采集的项目里发现换GD32后通道间串扰明显变大后来在通道切换后加了更长的采样延时并调整了采样周期寄存器才把精度拉回来。这类问题在数据手册里往往写得比较隐晦需要你实际用示波器或者高精度源去测。2.2 标准库和HAL库的迁移成本如果你用的是STM32标准库迁移到GD32相对容易因为GD32官方提供了高度相似的固件库函数名和结构体基本一致改改头文件路径和少量寄存器定义就能编译通过。但如果你用的是STM32 HAL库那就麻烦一些。GD32有自己的HAL风格库但API命名和回调机制跟ST的HAL不完全一样尤其是中断处理和DMA配置部分需要逐个外设对照移植。我当时的做法是先把底层驱动抽象成一层薄薄的接口比如bsp_uart_init、bsp_adc_read上层业务代码不直接调库。这样换芯片时只改BSP层业务逻辑几乎不动。这个习惯后来帮了我大忙因为CH32V103的库又是另一套风格没有这层抽象迁移成本会成倍增加。提示如果你计划在项目里保留随时换芯片的可能性从第一天起就把外设驱动隔离成独立层别让业务代码直接碰寄存器或库函数。2.3 中断向量表和启动文件的差异热词里有人搜gd32 app程序 vector table base offset这其实是个很实际的问题。GD32在做IAP升级或者带Bootloader的应用时APP程序的向量表偏移设置和STM32类似但寄存器名称和库函数可能不同。STM32里常用NVIC_SetVectorTable或者直接改SCB-VTORGD32也有对应的机制但如果你直接照搬STM32的代码可能编译不过或者运行异常。我的做法是在APP启动的最开始用GD32库提供的函数设置向量表偏移并且确保链接脚本里的Flash起始地址和偏移量一致。这里有个细节GD32的启动文件里默认的中断向量表位置和STM32的启动文件结构不完全一样如果你用的是自己写的启动文件一定要对照GD32的参考手册确认向量表大小和排列顺序。我见过有人因为启动文件没换导致中断一进就HardFault查了半天才发现是向量表对不上。3. CH32V103与RISC-V内核另一条路的手感3.1 RISC-V带来的新鲜感和新麻烦CH32V103用的是RISC-V内核这和ARM Cortex-M完全是两套东西。第一次用的时候最直观的感受是工具链变了。你需要用RISC-V的GCC调试器配置也不同如果你习惯了Keil或者IAR的一键下载转到CH32V103需要重新搭环境。我当时用的是MounRiver Studio它是基于Eclipse的上手需要一点时间但用顺了也还行。RISC-V的好处是指令集精简、授权开放长远看有生态潜力。但短期内的麻烦是很多ARM上现成的中间件不能直接拿来用。比如某些RTOS的移植层、某些DSP库、某些USB协议栈都是针对Cortex-M写的移植到RISC-V需要改汇编部分和中断控制器配置。我在CH32V103上跑FreeRTOS时就花了整整两天调移植层主要是中断嵌套和上下文切换的汇编代码需要对着RISC-V的规范重写。3.2 外设丰富度与文档质量CH32V103的外设不算少USB、CAN、ADC、串口这些都有但文档的详细程度和ST相比还有差距。有些寄存器的行为描述比较简略遇到问题时需要靠实验去推断。比如它的USB设备模式枚举过程在某些主机上会偶发失败后来发现是描述符返回的时序需要微调。这类问题在ST的芯片上通常有成熟的应用笔记和社区讨论但在国产芯片上你往往得自己当第一个吃螃蟹的人。不过话说回来CH32V103的价格和供货确实有优势对于一些对成本敏感、功能要求不极致的场景它是可用的。我在一个简单的串口转无线的网关上用了它跑了大半年没出过死机。但前提是你得接受它的生态不如STM32成熟遇到问题更多靠自己解决。3.3 开发环境搭建的坑热词里有人搜vscode 搭建stm32开发环境及j-link下载环境其实国产芯片也有类似需求。CH32V103可以用MounRiver Studio也可以自己用VSCode加RISC-V工具链加OpenOCD来搭。我试过后者配置起来比较繁琐尤其是调试器的配置文件需要根据芯片的Flash算法和RAM地址来改。如果你不是特别喜欢折腾环境建议直接用官方IDE省下来的时间用来调业务逻辑更划算。另外国产芯片的烧录器生态也在完善中。GD32可以用J-Link、DAP-LinkCH32V103有官方的WCH-Link。我实测下来WCH-Link的稳定性还可以但在Linux下的驱动支持不如J-Link完善。如果你团队里有人用Mac或者Linux选烧录器时要把这个因素考虑进去。4. 跑RTOS和协议栈国产芯片能不能扛住复杂项目4.1 FreeRTOS在GD32上的实际表现我在GD32F103上跑过FreeRTOS任务包括串口收发、ADC采集、Modbus解析、以及一个简单的TCP通信通过外挂以太网芯片。整体跑下来稳定性是可以接受的连续运行一个月没有死机。但有几个细节需要注意第一系统节拍中断的优先级配置。GD32的中断优先级分组和STM32类似但如果你从STM32工程直接搬过来要确认configPRIO_BITS和实际芯片的优先级位数一致。我见过有人设错了导致任务切换异常。第二Flash写入与RTOS的冲突。热词里有人搜stm32 freertos flash写入被打断这在GD32上同样存在。Flash写入或擦除时如果中断还在跑可能导致写入失败甚至锁死。我的做法是在Flash操作前挂起调度器关掉相关中断写完再恢复。这个操作在STM32和GD32上逻辑一样但GD32的Flash操作时间可能略有不同挂起时间要留够余量。第三内存管理。GD32F103的RAM和STM32F103一样都是20KB左右C8T6跑FreeRTOS加TCP协议栈会比较紧张。我用的是heap_4并且把任务栈调得比较小才勉强够用。如果你要跑LwIP建议选RAM更大的型号或者用GD32F303系列。4.2 LwIP和物联网网关场景热词里有stm32网关lwip协议栈和freertos stm32物联网网关我在GD32上也搭过类似的网关。LwIP移植到GD32的主要工作是网卡驱动和sys_arch层。网卡驱动取决于你用的以太网芯片比如ENC28J60或者W5500这部分和MCU关系不大主要是SPI时序。sys_arch层需要实现信号量、邮箱、互斥量如果你用FreeRTOS可以直接用它的API封装。实测下来GD32跑LwIP的吞吐量比STM32略低一点但差距不大对于一般的传感器数据上报、Modbus TCP转发这类场景完全够用。真正需要注意的是中断优先级和DMA配置如果网卡中断优先级设得太低高负载时可能丢包设得太高又可能影响其他实时任务。我一般把网卡中断设为中等优先级DMA接收用轮询加中断结合的方式平衡实时性和吞吐。4.3 国产RISC-V芯片跑RTOS的现状CH32V103跑FreeRTOS的体验前面提过移植层需要自己调。另外RISC-V的中断控制器和ARM的NVIC不一样它的中断入口和优先级管理方式不同如果你用了一些依赖NVIC的中间件需要改。我建议在RISC-V芯片上先从裸机或者简单的调度器开始等熟悉了再上完整的RTOS。不过RISC-V生态在快速发展一些主流的RTOS已经开始提供RISC-V的官方移植未来会越来越方便。如果你现在就要用做好自己填坑的准备。5. 那些年我踩过的具体坑从ADC到CAN再到USB5.1 ADC多通道切换的精度问题前面提过GD32的ADC通道切换需要更长的建立时间。具体来说我在一个项目里用ADC1的通道0和通道1交替采集STM32上直接切换没问题GD32上发现通道1的读数总是偏高。后来用示波器看发现通道切换后采样电容的电荷没有完全建立。解决办法是在切换通道后先做一次丢弃的采样再采第二次作为有效值。这个技巧在STM32上也有用但GD32上更必要。另外ADC的参考电压和温度漂移也需要注意。国产芯片的ADC精度在常温下和ST差距不大但在高低温环境下某些批次的漂移会大一些。如果你的产品要过工业级温度范围建议留出校准环节或者选带外部基准的型号。5.2 CAN通信突然连不上热词里有stm32 can通信突然连不上我在GD32上也遇到过类似情况。现象是CAN总线跑一段时间后某个节点突然离线重启后恢复。排查下来原因有几个一是CAN收发器的供电不稳二是波特率配置在国产芯片上需要更精确的时钟校准三是总线终端电阻不匹配。我的解决步骤是先用示波器看CAN_H和CAN_L的差分波形确认信号质量然后检查波特率寄存器的配置确保和总线时钟匹配最后检查终端电阻和线缆长度。在GD32上我还发现它的CAN过滤器配置和STM32略有不同如果直接照搬STM32的过滤器代码可能过滤不掉不需要的帧导致接收缓冲区溢出。这个细节在数据手册里有写但容易被忽略。5.3 USB枚举的偶发失败USB是另一个容易出问题的地方。我在GD32F103上做USB HID设备时发现某些主机尤其是某些品牌的工控机枚举会失败换一台电脑又正常。后来用USB分析仪抓包发现是描述符返回的时序问题GD32的USB外设在某些情况下响应稍慢导致主机超时。解决办法是优化USB中断的优先级并确保描述符数据在发送前已经准备好不要在中断里做耗时操作。CH32V103的USB也有类似情况但它的官方库更新比较频繁建议用最新版的库很多时序问题在新版里已经修复。6. 一年用下来我的选型建议和适用边界6.1 什么场景我会优先用国产芯片经过这一年的测试我现在会在以下场景优先考虑国产芯片成本敏感、功能固定的量产产品比如简单的传感器节点、电机驱动板、LED控制器。这些场景外设用得少代码量小国产芯片完全能胜任而且成本优势明显。供货紧张时的替代方案当STM32交期不可控时GD32作为Pin-to-Pin替代可以快速切换前提是你做好了软件层的兼容性验证。教学和入门项目CH32V103这类RISC-V芯片价格低适合学生学习底层原理而且能接触到不同于ARM的架构。对国产化有要求的项目有些行业客户明确要求国产化率这时候国产芯片是必选项提前熟悉它们的特性有好处。6.2 什么场景我仍然坚持用STM32反过来以下场景我目前还是倾向用STM32复杂的USB协议栈或高速通信STM32的USB库成熟度更高遇到问题资料多国产芯片在这块还需要时间积累。对ADC精度和稳定性要求极高的场合比如精密测量STM32的ADC一致性和温漂表现更可控。需要大量中间件和生态支持的项目比如文件系统、图形库、复杂的TCP/IP应用STM32的生态更完善能省很多移植时间。团队不熟悉国产工具链如果团队没有精力去踩坑用STM32可以降低项目风险。6.3 给准备尝试国产芯片的人几条实在建议第一先做兼容性验证别直接上量产。拿几块样片把关键外设都跑一遍尤其是ADC、USB、CAN这些容易出问题的地方。第二把驱动层抽象好。不管你现在用不用国产芯片把BSP层独立出来未来换芯片时你会感谢自己。第三关注官方库的更新。国产芯片的库更新频率不低很多早期的问题在新版里已经修复别抱着旧版本不放。第四加入社区。国产芯片的社区虽然不如ST庞大但活跃度在上升很多坑别人已经踩过搜一搜能省时间。第五保持理性。国产芯片在进步但也不是所有场景都适合。根据项目需求选型而不是根据情绪选型。7. 关于工具链和开发环境的一些补充7.1 Keil、IAR和GCC的选择STM32时代很多人习惯用Keil或者IAR。国产芯片方面GD32对Keil的支持比较好装个器件包就能用。CH32V103则主要用MounRiver Studio或者GCC。如果你团队里有人习惯VSCode也可以自己搭GCC加OpenOCD的环境但调试体验不如商业IDE顺滑。我个人的做法是量产项目用商业IDE保证效率学习和小项目用GCC加VSCode练手。这样既能保证项目进度又能保持对开源工具链的熟悉。7.2 烧录器和调试器的兼容性J-Link对GD32的支持不错但需要更新到较新的固件和器件包。DAP-Link便宜但稳定性参差不齐建议买口碑好的。CH32V103用WCH-Link最省事但如果你已经有J-Link也可以试试能不能识别部分型号需要手动配置。注意有些国产芯片的调试接口默认是关闭的或者需要特定的上电时序才能进入调试模式。如果你遇到连不上的情况先查手册里的调试接口配置别急着怀疑硬件坏了。7.3 时钟配置的坑国产芯片的时钟树和STM32类似但PLL配置参数可能不同。我遇到过用STM32的时钟配置代码直接跑在GD32上结果主频不对导致串口波特率偏差。解决办法是对照GD32的手册重新算PLL参数或者用官方提供的时钟配置工具生成代码。这个步骤不能省否则后面所有依赖时钟的外设都会出问题。8. 最后聊聊心态国产芯片需要的是真实反馈不是捧杀或棒杀用了一年国产芯片我最大的感受是它们已经过了不能用的阶段正在往好用的方向走。GD32在Pin-to-Pin替代上做得不错CH32V103在RISC-V路线上有自己的特色其他几家国产厂商也在快速迭代。但差距仍然存在尤其是在生态、文档、以及高端外设的成熟度上。我觉得对国产芯片最好的支持不是无脑吹也不是一棍子打死而是像对待任何工程问题一样用数据说话用场景验证把真实的坑和真实的进步都讲出来。厂商需要真实反馈来改进产品工程师需要真实信息来做选型。我写这篇内容就是希望给正在做选择的人一个参考让你知道哪些地方可以放心用哪些地方需要多留个心眼。如果你也在用国产芯片欢迎交流你的经验。踩过的坑越多这个生态就会越成熟。
阅读完成 · 觉得有帮助?
咨询建站