chunxx 发表于 2022-10-18 18:25:36

GD32F103VET6替换STM32遇到的奇怪问题

一个STM32F103VET6的产品,已经好多年,现在还有一些小量出货。因为STM32涨价的原因,今年用GD32F103VET6替换,移植没什么难度,也已经成功出了几批货,但最近这一批,突然出现了问题。程序写入后,板怎么也调不出来,晶振根本就不起振,换晶振,换MCU也不行。
巧在这个产品同一个硬件平台,支持A、B两份程序,简单讲这两个程序是Master和Slave关系,调不出来的是B程序的板。这两个在STM32和GD32两者环境下都是使用过没问题的,尝试写入A程序,能工作,一切正常,这证明了硬件没有问题。当前的环境是MDK 5.17,JLinkV8,反复烧写程序没问题,可以排除工具的原因;A程序的代码量(code 176K)比B程序(code 119K)大,因此也不可能是用小容量芯片冒充大容量芯片的问题。
调整GD32移植时在stm32f10x.h,stm32f10x_flash.c程序中的修改部分,没有用。晶振不起振,不是硬件,而是程序停在HardFault_Handler,死机。Debug看到R14=0xfffffff9, MSP指向的memory是0xacacacac这样的空值,网上关于HardFault调试的技巧没什么用。在startup文件中调整stack/heap大小,也没有用。
想找出B程序是否存在野指针之类的Bug,用削减的方法减少B程序实际的工作,但写入后都是死机。无奈之下另起一个project,重构B程序,将序底层和中间层逐步加入,在main()中,基本的GPIO/RCC初始化后while(1)输出LED on/off,是可以工作的,串口printf也有输出。逐渐增加main()中调用的程序,到一定程度就不行了;追踪这些新加的程序,是一些根本没有被调用到的函数,以及一些A程序、B程序共用的函数。AB两个程序底层和中间层代码是共用的。走不下去,从源程序上无法找出问题。
这个新建的测试project,用的是default的编译配置:Use MicroLib, Optimization=default(无),One ELF Section per Function=true。Optimization改成Level3/optimize for time,也能运行;但去掉"One ELF Section per Function"就不行,这时程序量大得多,从66K code变到119K;去掉MicroLib,启用"#pragma import(__use_no_semihosting) ",也可以运行,但工作程序一增加,还是死机。
回头再用A程序测,启用"One ELF Section per Function",或者去掉Use MicroLib两个配置,都能编译通过,写入STM32的板工作没有问题,但写入GD32的就死机。
感觉和源程序无关,和code size无关,而是与不同程序模块在flash中的定位有关,要分析map文件。这也太困难了,毕竟已经好多年没做 stm32了,现在对单片机也兴趣缺缺。还是选择放弃,产品上退回stm32,好在stm32的价格已经差不多降回来了。
不过还是希望找到原因。不想简单的用国产芯片质量来推脱,但确实这些个替代还有许多诡异的问题。

三年模拟 发表于 2022-10-18 18:27:44

程序的库有换吗,gd32很稳定的。

罗小蘑菇 发表于 2022-10-18 18:36:31

1、堆栈设置大些试试,可能堆栈溢出导致。
2、gd32f103的flash跟stm32f103的结构不一样,好像是上来先把256k还是128k导入到ram里跑,如果跨越了256k还是128k,会导致操作延时很大,从而导致一些工作异常。

wye11083 发表于 2022-10-18 18:54:04

lz你这个可能调了gd不支持的外设配置,比如flash控制。这种需要汇编单步进去,看看到哪一步出错。

akey3000 发表于 2022-10-18 20:35:37

应该不是芯片质量问题

qwe2231695 发表于 2022-10-18 21:32:49

本帖最后由 qwe2231695 于 2022-10-18 21:34 编辑

已经成功出了几批货,拿老的对比一下,排除芯片批次问题。 新的芯片可能碰巧改动了一个外设。拿勘误手册看下,芯片版本是不是不一样。

有B程序源码的话,在线debug一下就能找到原因

追加: 你说“逐渐增加main()中调用的程序,到一定程度就不行了“ ,那估计还是要继续找。耐心找到问题根本原因。

初音之恋 发表于 2022-10-18 21:42:43

现在都用GD32了,稳定性还可以,推荐直接使用GD的库,一步步替换认证

Himem 发表于 2022-10-18 22:03:50

gd32用jlink总会遇到奇奇怪怪的问题,换daplink试试

liao-ljj 发表于 2022-10-18 22:23:42

我都是烧STM的HEX啊....我觉得GD不好用,这个是我个人初步研究的结果!后面换了一部分GD....后面主力STM32+STC....{:lol:}

chunxx 发表于 2022-10-19 09:47:10

三年模拟 发表于 2022-10-18 18:27
程序的库有换吗,gd32很稳定的。
(引用自2楼)

库和源程序都没有改动。这是产品化了的东西。

chunxx 发表于 2022-10-19 09:51:51

罗小蘑菇 发表于 2022-10-18 18:36
1、堆栈设置大些试试,可能堆栈溢出导致。
2、gd32f103的flash跟stm32f103的结构不一样,好像是上来先把256 ...
(引用自3楼)

1。stack/heap修改过,不起作用、
2。这个正是我怀疑的,因为A、B两个程序一个小于128K,一个大于128K。但是从flash加载到ram中的机制不知道怎么调它,自己搞个bootloader ?,那也太高难度了。

whatcanitbe 发表于 2022-10-19 10:53:31

把晶振起振等待时间加长,改成10倍试试

chunxx 发表于 2022-10-19 10:58:44

whatcanitbe 发表于 2022-10-19 10:53
把晶振起振等待时间加长,改成10倍试试
(引用自12楼)

HSE_STARTUP_TIMEOUT,在移植GD32时就改成了0xffff, STM32的0x0500也试过,没用。不会是这么简单的原因

zjykwym 发表于 2022-10-19 12:41:02

chunxx 发表于 2022-10-19 09:51
1。stack/heap修改过,不起作用、
2。这个正是我怀疑的,因为A、B两个程序一个小于128K,一个大于128K。 ...
(引用自11楼)

大小128k的部分其实没啥问题,这2块flash是一样的flash,只是大于128k的部分没有缓存,可以理解为直接在flash上运行的,而前128k的部分是在sram中运行的。不影响功能,速度不一样而已。

罗小蘑菇 发表于 2022-10-19 13:08:35

chunxx 发表于 2022-10-19 09:51
1。stack/heap修改过,不起作用、
2。这个正是我怀疑的,因为A、B两个程序一个小于128K,一个大于128K。 ...
(引用自11楼)

第2个问题,是芯片自己加载的,我们控制不了。

还想到一个问题,有的时候KEIL会出些莫名其妙的问题,也有可能keil的工程文件乱了,你可以试试把你跑不起来B程序的源代码导入到你能跑起来的A程序的工程里,重新编译下试试。

chunxx 发表于 2022-10-19 16:47:48

罗小蘑菇 发表于 2022-10-19 13:08
第2个问题,是芯片自己加载的,我们控制不了。

还想到一个问题,有的时候KEIL会出些莫名其妙的问题,也 ...
(引用自15楼)

您注意看我做过的工作。我建一个新project,逐步导入源程序,就是按这个思路做的,失败了,定位不到源程序上。

tomzbj 发表于 2022-10-19 16:58:05

先打开Usage/memmgr/bus fault, 然后再试试, 看能不能缩小问题范围?

应该是加个这个
SCB->SHCSR |= (7UL << 16);    // enablememmanage/bus/usage error
然后在stm32f10x_it.c里加上
void MemManage_Handler(void)
{
    while(1);
}               // MPU Fault Handler
void BusFault_Handler(void)
{
    while(1);
}                  // Bus Fault Handler
void UsageFault_Handler(void)
{
    while(1);
}         // Usage Fault Handler

foric 发表于 2022-10-20 07:48:53

本帖最后由 foric 于 2022-10-20 07:50 编辑

我也在用103VE,对比发现APM32不用做任何改动直接兼容STM32
GD和雅特力还是需要改代码,差点意思。
极海APM32F103VET6 已陆续在几款产品上用了6000片,好评

chunxx 发表于 2022-10-20 15:52:41

tomzbj 发表于 2022-10-19 16:58
先打开Usage/memmgr/bus fault, 然后再试试, 看能不能缩小问题范围?

应该是加个这个
(引用自17楼)

SCB这个方法我没试过,按这个意见折腾了一个上午,还是一上来就锁死在hardfault。
不过受到启发,在memory watch中检测0xe000ed28这一块,这个应该就是SCB的fault状态寄存器,正常工作的程序是0,死机的程序,这个的值是0x00001400;第2个byte就是Busfault,应该就是这个。但是再查下去,到bit一级就搞不懂什么意思了,虽然每个字都认识.

页: [1]
查看完整版本: GD32F103VET6替换STM32遇到的奇怪问题