打印
[研电赛技术支持]

借助人工智能提出问题并解决问题是怎样的过程?GD32H759 用vscode+eide开发的一些问题

[复制链接]
1176|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
丙丁先生|  楼主 | 2025-4-25 21:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
GD32H759 用vscode+eide开发的一些问题
[color=rgb(153, 153, 153) !important][color=rgb(153, 153, 153) !important][复制链接]
243|17

手机看帖
电梯直达[url=][/url]
楼主
shuwei1984|   楼主 | 2025-4-24 19:12 | 只看该作者


EIDE, 开发, GD32H759, vscode, 调试, ar
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工具还有哪些能用的?







续篇:其他问题的追问与解答:


关闭SCB_EnableDCache() 这个之后,再将栈调整到6kB,可以运行了,也有崩溃的时候。再调整栈大小到8K,不崩溃了。但是只要打开了  SCB_EnableDCache(),就必崩溃。IAR中打开SCB_EnableDCache(),不会崩溃,检查了两个编译环境的宏,关于SCB_EnableDCache() 中两个是一样的,不存在IAR与GCC编译的源码不一样的情况。两个程序map,再对比看看。这说明什么?

根据你描述的情况,结合搜索结果中的信息,可以得出以下结论和建议:

问题分析
1. 栈大小与缓存冲突  
   在关闭 `SCB_EnableDCache()` 时,栈调整到 6kB 仍可能偶尔崩溃,而调整到 8kB 后稳定,说明栈空间不足可能导致数据溢出或覆盖。  
   启用数据缓存(D-Cache)后必崩溃,可能是因为缓存机制改变了内存访问的一致性或对齐要求,导致栈操作出现异常。

2. 编译环境差异  
    虽然 IAR 和 GCC 的宏定义一致,但两者的编译优化策略、栈布局、中断处理方式可能存在差异。例如:  
    GCC 可能对栈对齐或中断处理有更严格的要求,导致启用 D-Cache 后栈操作异常。  
    IAR 可能默认启用了某些保护机制(如栈溢出检测),而 GCC 未配置相关选项。

3. 缓存一致性问题  
    启用 D-Cache 后,栈内存可能被缓存,而缓存的读写策略(如 Write-Back 或 Write-Through)可能影响数据的一致性。如果栈写操作未正确刷新到内存,可能导致数据错误或崩溃。  
    例如,在中断处理函数中修改栈变量时,若缓存未及时刷新,主程序可能读取到旧数据(参考 [例说STM32F7高速缓存——Cache一致性问题])。

4. 程序映射(Map)差异  
    对比 IAR 和 GCC 生成的程序映射文件(Map),需重点检查以下内容:  
    栈和堆的起始地址:确保栈空间未与其他内存区域(如代码段、全局变量)重叠。  
    中断向量表位置:启用 D-Cache 后,若中断向量表被缓存,可能导致中断响应异常。  
    内存对齐:GCC 可能对栈指针或数据变量有更严格的对齐要求,导致缓存行(Cache Line)未对齐,引发访问错误。

解决方案建议
1. 增加栈大小  
    将栈调整为 8kB 可暂时规避问题,但需进一步分析栈使用情况,确保没有动态分配过大的局部变量或递归调用。

2. 手动管理缓存一致性  
    在关键位置(如中断处理函数)手动清理或无效化缓存,确保栈操作的内存可见性。例如:  
     ```c
     SCB_CleanDCache();  // 清理缓存,将脏数据写回内存
     SCB_InvalidateDCache();  // 无效化缓存,确保后续访问从内存重新加载
     ```
    参考 CMSIS 库的缓存管理函数([^2^]),在栈操作前后添加缓存维护代码。

3. 检查编译选项
    对比 IAR 和 GCC 的编译选项,重点关注以下参数:  
    栈对齐:确保 GCC 的栈对齐设置与硬件要求一致(如 8 字节对齐)。  
    优化级别:尝试关闭 GCC 的优化(如 `-O0`),观察是否仍崩溃。  
    中断处理模型:检查 GCC 是否启用了特定的中断处理机制(如 `-mfloat-abi=hard` 可能影响栈布局)。

4. 分析程序映射文件  
    对比 IAR 和 GCC 的 Map 文件,重点检查:  
    栈的起始地址和大小是否一致。  
    是否有全局变量或堆内存与栈重叠。  
    中断向量表是否被正确放置(建议放在非缓存区域,如外设寄存器区)。

5. 禁用缓存的特定区域  
    如果仅需对部分内存区域启用缓存,可通过 MPU(内存保护单元)配置缓存区域,避免栈被缓存。例如:  
     ```c
     // 配置 MPU,禁止缓存栈所在的 SRAM 区域
     SCB->MPU_RBAR = 0x20000000;  // 栈起始地址
     SCB->MPU_RASR = (0x1 << 8) |  // 禁止缓存
                     (0x1 << 1) |  // 启用 MPU
                     (0x0 << 2);   // 读/写权限
     ```

总结
启用 D-Cache 后崩溃的根本原因可能是  缓存一致性问题 或 栈布局与硬件缓存机制不兼容。通过以下步骤可逐步排查:  
1. 增加栈大小并检查 Map 文件,确保栈空间充足且无重叠。  
2. 在关键位置手动维护缓存(清理或无效化)。  
3. 对比 IAR 和 GCC 的编译选项,调整栈对齐和优化设置。  
4. 通过 MPU 限制缓存区域,避免栈被缓存影响。

如果问题仍存在,建议在启用 D-Cache 后通过调试工具(如内存监视、缓存状态检查)进一步定位崩溃点。

使用特权

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

本版积分规则

999

主题

3632

帖子

5

粉丝