打印
[研电赛技术支持]

分析GD32H759 用vscode+eide开发的一些问题

[复制链接]
235|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
丙丁先生|  楼主 | 2025-4-25 19:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
GD32H759IMK6 芯片,野火的开发板用VSCode + EIDE + Arm GNU Toolchain 工具 11.3.Rell版编译  xpack+openocd + fireDAP仿真器下载运行用VSCode带的 Cortex-Debug插件进行debug时,内存变量值经常取不到,都显示是个0。先怀疑是缓存的问题,使用SCB_InvalidateDCache_by_Addr命令先对要看的内存进行“Invalidate”操作后,可以看到断点时该变量的值。但只能对专门这样分配的全局内存数据起效果,对于局部变量没有用。只能进行一些简单的调试判断。今天又增加了LWIP功能,结果用gcc编译的在启动使用netconn api写的网络数据进程时,直接死掉了。调试因为变量无论怎么断点看都是个0值,没法调试看问题出在哪里。同样的工程在IAR上编译调度时,没有这个问题。都能正常运行。我是一份代码做了两个调试环境。IAR就没这些问题。另外,GD自己的模板生成系统生成的示例代码工程中,对GD32H7xx系列的*.ld文件过于简单,1024kB+16+ 16KB的RAM,ld文件里面只给定义了512kB。这个LD文件 有人扩写调试好的版本有没?除了Keil和IAR两个收费的开发工具外,开源的IDE工具还有哪些能用的?  这些说的是什么?


以下是对您所描述问题的分析及解决方案建议:

一、内存变量调试显示为0的问题
1. 局部变量无法显示值的原因
栈溢出或内存分配问题:GCC编译时栈消耗较大,可能引发栈溢出。虽然已尝试将`__stack_size`设为4K,但实际栈需求可能更高(尤其加入LWIP后)。建议进一步增大栈尺寸(如尝试8K或更大),并检查任务栈是否足够。
编译器优化导致变量未初始化:GCC的优化选项(如`-O2`或`-O3`)可能将未使用的局部变量优化掉,或在初始化前跳过赋值。可以尝试以下措施:
   在变量声明后立即赋值(如`ip_addr_t server_ip = {0};`)。
   编译时关闭优化(如使用`-O0`)以验证是否为优化问题。
   检查是否有其他代码路径导致变量未正确初始化。

2. 缓存问题的影响
手动缓存失效的局限性:`SCB_InvalidateDCache_by_Addr`仅对全局变量有效,因为全局变量的地址是固定的,而局部变量的地址在栈中动态变化,难以手动失效。建议在调试时禁用缓存(通过链接器脚本或启动代码配置`SPECULATE_DISABLE`),或者在关键代码段前手动执行`__builtin_dsb()`和`__builtin_isb()`确保内存屏障。

二、增加LWIP后进程崩溃的分析
1. 可能的原因
内存分配冲突:LWIP需要大量RAM(如PBUF、TCP控制块等),如果堆栈与堆空间重叠或不足,可能导致内存破坏。需检查`ld`文件中`.bss`和`.heap`段的定义是否合理。
任务优先级或资源竞争**:LWIP的TCP/IP任务可能与其他任务竞争资源。建议参考第8条回复,调整LWIP任务优先级,并确保网络处理任务优先级较高。
初始化顺序问题**:LWIP初始化需在网络硬件(如以太网MAC)初始化之后。检查`NetComm_ClientProcess`调用前是否完成LWIP和硬件的初始化。

2. 调试建议
单步跟踪:在`Task_NetCommunate`中逐步执行,观察`server_ip.addr`何时被覆盖为0。
检查LWIP配置:确认LWIP的内存堆(`mem_init`)和线程安全配置是否正确。
对比IAR编译差异:比较GCC与IAR的编译选项(如优化等级、栈对齐方式),以及生成的映射文件(`.map`)是否一致。

三、GD32H7xx系列LD文件扩展问题
1. 默认LD文件的局限性
GD官方模板的`.ld`文件可能仅定义了部分RAM区域(如512KB),而实际芯片有1024KB RAM。需手动扩展`.ld`文件中的`RAM`段:
```ld
MEMORY
{
  FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 3840K
  RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 1024K /* 扩展为1024KB */
}
SECTIONS
{
  .bss :
  {
    __bss_start__ = .;
    *(.bss)
    *(COMMON)
    __bss_end__ = .;
  } > RAM
}
```
2. 野火开发板适配
若野火开发板的硬件设计支持完整1024KB RAM,可直接修改`.ld`文件。否则需检查是否存在内存分区冲突(如外设映射到高地址RAM)。

四、开源IDE工具推荐
除了Keil和IAR,以下开源工具可替代商业IDE:
1. VSCode + PlatformIO:
    优势:跨平台、支持多种框架(如Arduino、STM32Cube)、集成库管理。
    配置:安装`PlatformIO IDE`扩展,通过`platformio.ini`配置GD32编译工具链。
2. Eclipse + CDT(C/C++ Development Tooling):
    优势:成熟稳定,支持GCC、OpenOCD调试。
    配置:安装`CDT`插件,集成Arm GNU Toolchain和OpenOCD。
3. Zephyr RTOS IDE:
    优势:专为嵌入式开发设计,支持GD32等架构,内置编译和调试工具。
    官网:Zephyr Project
4. SEGGER Embedded Studio:
    优势:免费版支持GCC,界面类似Keil,适合快速上手。

五、其他建议
1. 验证硬件连接:确保野火开发板的JTAG/SWD接口与fireDAP仿真器兼容,排除硬件故障。
2. 最小化测试:创建一个仅包含LWIP核心功能的空白工程,逐步添加代码以定位崩溃点。
3. 社区支持:参考GD32社区(如CSDN、GitHub)的类似问题,或联系野火科技获取技术支持。

通过以上步骤,您应能定位内存变量异常和LWIP崩溃的问题,并扩展`.ld`文件以充分利用芯片资源。如需进一步协助,可提供具体代码片段或编译日志。

使用特权

评论回复
沙发
shuwei1984| | 2025-4-25 20:57 | 只看该作者
关闭SCB_EnableDCache() 这个之后,再将栈调整到6kB,可以运行了,也有崩溃的时候。再调整栈大小到8K,不崩溃了。

但是只要打开了  SCB_EnableDCache(),就必崩溃。

IAR中打开SCB_EnableDCache(),不会崩溃,检查了两个编译环境的宏,关于SCB_EnableDCache() 中两个是一样的,不存在IAR与GCC编译的源码不一样的情况。

两个程序map,再对比看看。

使用特权

评论回复
板凳
shuwei1984| | 2025-4-25 22:10 | 只看该作者
经过对比IAR与GCC的map文件

发现是0x30000000处这个SRAM0区域,在ld文件中没有定义,而在gd32h7xx_enet.c这个驱动文件中,

又是用

#elif defined (__GNUC__)        /* GNU Compiler */
enet_descriptors_struct  rxdesc_tab[ENET_RXBUF_NUM] __attribute__((section(".ARM.__at_0x30000000")));          /*!< ENET RxDMA descriptor */
enet_descriptors_struct  txdesc_tab[ENET_TXBUF_NUM] __attribute__((section(".ARM.__at_0x30000160")));          /*!< ENET TxDMA descriptor */
uint8_t rx_buff[ENET_RXBUF_NUM][ENET_RXBUF_SIZE] __attribute__((section(".ARM.__at_0x30000300")));             /*!< ENET receive buffer */
uint8_t tx_buff[ENET_TXBUF_NUM][ENET_TXBUF_SIZE] __attribute__((section(".ARM.__at_0x30002100")));             /*!< ENET transmit buffer */

#endif /* __CC_ARM */

造成了内存分配区的混乱

于是,将LD文件修改如下:


增加:

MEMORY
{
  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 3840K
  RAM (xrw)       : ORIGIN = 0x24000000, LENGTH = 768K
  SRAM0 (xrw)      : ORIGIN = 0x30000000, LENGTH = 16K
  SRAM1 (xrw)      : ORIGIN = 0x30040000, LENGTH = 16K
}

增加
  .enetram :
  {
    . = ALIGN(4);
    _senetram = .;
    __enetram_start__ = _senetram;
    *(.ARM.__at_0x3*)
    *(.ARM.__at_0x3)
   
    . = ALIGN(4);
    _eenetram = .;
    __enetram_end__ = _eenetram;
  } >SRAM0 AT> FLASH

再次打开DCache就没有问题了。



现在还有两个小问题,不得其解,上面的RAM如果把大小修改为1024K,同样会崩溃。

下面的内存分配段描述中,如果不加 AT>FLASH,下载到芯片时,会提示:
** Verify Started **
Error: checksum mismatch - attempting binary compare
embedded:startup.tcl:1136: Error: ** Verify Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 1197
at file "embedded:startup.tcl", line 1136

*  终端进程“cmd.exe /C ""C:\Program Files (x86)\openocd\bin\openocd.exe" -s "c:\Users\*******\Documents\MCUProjects\GD32H7TestSample\xTUCoreBoardPrj" -f interface/cmsis-dap.cfg -f gd32h7xx.cfg -c "program \"c:/Users/********/Documents/MCUProjects/GD32H7TestSample/xTUCoreBoardPrj/GccBuild/Debug/xTUCoreBoardPrj.hex\" verify" -c "reset run" -c "exit""”已终止,退出代码: 1。
*  终端将被任务重用,按任意键关闭。

这两个小问题暂时不知道如何解决

使用特权

评论回复
地板
丙丁先生|  楼主 | 2025-4-25 22:40 | 只看该作者
shuwei1984 发表于 2025-4-25 22:10
经过对比IAR与GCC的map文件

发现是0x30000000处这个SRAM0区域,在ld文件中没有定义,而在gd32h7xx_enet.c ...

我们同龄,年相近也,道相似也,
在AI浪潮下,
一个问题的价值高于答案,
问题指明了答案。

我估计是容量小了不行,未论证。

手上也没有你的开发板,

不过我相信你的能力,

相信一觉醒来,

你会给我答案。

使用特权

评论回复
5
cooldog123pp| | 2025-4-26 13:35 | 只看该作者
丙丁先生 发表于 2025-4-25 22:40
我们同龄,年相近也,道相似也,
在AI浪潮下,
一个问题的价值高于答案,

老哥我很怀疑你是ai自动回复啊,不过我看了这个帖子我也没看明白是啥,可能是我GD的板子用的少的缘故吧。

使用特权

评论回复
6
丙丁先生|  楼主 | 2025-4-26 14:17 | 只看该作者
cooldog123pp 发表于 2025-4-26 13:35
老哥我很怀疑你是ai自动回复啊,不过我看了这个帖子我也没看明白是啥,可能是我GD的板子用的少的缘故吧。 ...

GD32F427我有一块,没有深入研究,主要是没有例程和博文,我这就用起来,点灯/UART/PWM呼吸灯/舵机/上ST7735,IIC,温度值UART,好像别的我不会什么了,又好像可以用AI调试程序。其实上文的方法是通行的解决方法,解决问题的不是我,而是楼主自己,是更高级的调试,我也不懂,但是我相信AI给出的答案是对的,因为我有十几次以上运行AI的例程+自己的想法完成简单场景。是可靠的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

966

主题

3508

帖子

5

粉丝