给嵌入式工程增加一个大数组,链接时提示空间不足;调整程序起始地址后,下载成功却进不了主函数。这两类问题看起来不同,都可能与链接布局有关。Green Hills MULTI通过.ld链接指令文件安排代码、变量和栈等内容的存放位置。配置时既要考虑芯片有哪些存储资源,也要顾及启动代码怎样使用这些资源。已有工程中的链接文件可以作为修改起点,改动后的地址则需要通过映射文件和板上运行结果来确认。
一、Green Hills怎么设置链接脚本
下面以MULTI裸机工程为例。处理器型号不同,段名称和启动约定也会变化,示例工程中的地址不能直接套到另一块板子上。
1、确认当前工程引用的文件
同一个工程目录中可能同时保存RAM运行、ROM运行等多份链接文件。文件存在于目录中,并不代表本次构建会使用它。
①在工程树中查找.ld文件;使用工程向导创建的项目,还可以查看【Target Resources】中的目标资源。
②打开构建日志,找到链接阶段传入的.ld路径,与准备编辑的文件对应起来。
③保留原文件副本。另建文件进行修改时,同步更改工程引用,随后重新构建确认路径。
2、选择与启动方式相符的布局
①查看工程当前的程序布局,确认代码是在RAM中运行、直接从ROM运行,还是启动后复制到RAM运行。
②需要更换布局时,在程序项目上右键选择【Configure】,使用目标板支持的配置,再查看工程引用是否随之更新。
调试器直接加载RAM与设备断电后自行启动,对程序存放位置的要求不同。如果工程只在调试下载后能运行,脱离调试器就失败,应把启动方式也纳入排查范围。
3、填写可用存储区域
①在.ld文件的MEMORY定义中找到各个存储区域,查看ORIGIN指定的起始地址和LENGTH指定的长度。
②对照芯片手册和板级设计,填写当前应用可使用的Flash、RAM范围。
③为引导程序、共享数据等已有内容保留空间,避免应用区域与它们重叠。
④重新计算区域结束位置,确认没有跨入保留地址或芯片未实现的空间。
4、安排代码和数据段
①在SECTIONS定义中,查看.text、.rodata、.data、.bss等段被分配到了哪个区域,再调整需要迁移的部分。
②核对栈、堆及自定义段的预留空间,保留启动代码依赖的符号和初始化信息。
带初值的可写变量,运行位置和初始值的保存位置可能不同。例如变量在RAM中使用,初始内容却要随程序保存在Flash中,由启动代码完成复制。因此,把.data移到另一段RAM后,还应确认原有复制机制能够覆盖新位置。
二、Green Hills链接脚本配置不正确如何定位
定位时可以沿着故障出现的位置往下查。链接器报错就先看诊断和空间分配;已经生成程序但无法启动,则要把链接布局与启动过程对照起来。
1、修改没有生效,追查实际输入
①保存链接文件后重新构建,从日志中确认当前使用的构建配置和.ld完整路径。
②工程使用多份链接文件时,查看文件传入顺序。内存定义与段定义分开保存的,应先传入内存定义文件。
③对比新旧.map文件中相关段的地址,判断布局是否发生变化。
④下载前确认可执行文件来自本次输出目录,排除仍在加载旧程序的情况。
如果地址始终没有变化,先解决文件引用问题。继续修改同一份未被使用的脚本,只会让工程里出现更多难以区分的版本。
2、链接时报错,查看段和符号
映射文件可以帮助判断空间究竟用在了哪里。报错中的段名、符号名也应完整保留,方便追查来源。
①在构建选项中打开【Linker】→【Linker Output Analysis】→【Map File Generation】,启用.map文件生成;需要在链接失败时保留结果,可将【Map File Retention】设为【On】。
②遇到空间不足提示,在.map文件中找到报错段,查看大小、分配地址及所属区域。
③查看大数组、栈和堆的预留量,同时留意固定地址和对齐填充造成的空隙,不要直接扩大LENGTH来绕过错误。
④遇到未定义符号,搜索它在启动文件、源文件及.ld文件中的定义;属于函数或库的符号,还要确认对应文件是否参与链接。
⑤从较早出现的有效错误开始修正,重新构建后再看剩余诊断,避免被后续连带错误带偏。
3、链接通过,程序却运行异常
①从复位入口开始调试,在主函数入口设置断点,观察程序是否在初始化阶段就已经进入异常。
②对照.map文件查看入口、中断向量和栈的位置,确认它们符合目标处理器及启动代码的要求。
③在.data复制和.bss清零前后观察相关地址,查看复制来源、目标范围和清零边界是否正确。
④如果程序在访问某段RAM时停止,继续检查硬件初始化、访问权限,以及芯片要求的ECC初始化。
链接器能够分配地址,不代表那段存储器已经具备运行条件。外部RAM尚未初始化,或者某个核心无法访问指定区域,都可能表现为下载成功、运行失败。
三、Green Hills链接布局改动后怎么验证
改动范围越大,出现异常后越难判断原因。验证可以围绕本次修改展开,不必每次都重新调整整份脚本。
1、验证刚刚移动的内容
①打开本次生成的.map文件,找到调整过的段,确认其起始地址、大小和存储区域符合预期。
②下载新程序,观察启动过程,并查看带初值的全局变量及应清零变量的实际内容。
③如果迁移了函数,查看其运行地址;需要从ROM复制到RAM执行的,同时确认复制已经完成。
④运行会使用这些代码或数据的功能,避免只停在主函数入口就结束验证。
2、保留能对照的工程版本
①每轮集中修改一类内容,例如先调整区域边界,再改变段归属,分别构建和验证。
②保存修改前后的.ld文件及.map文件,记录地址变化和板上测试结果。
③验证通过后,将链接文件、启动文件与工程配置一并纳入版本管理。
后续增加功能再次发生溢出时,这些记录能帮助区分是代码体积增长,还是布局规则被改变。接手人员也能查到某段空间为什么预留,避免把有用途的空白重新分配出去。
总结
Green Hills链接脚本是工程适配目标硬件时需要了解的一部分。更换芯片、调整程序存储位置或为应用预留空间,都可能涉及链接布局的修改。熟悉这些配置,有助于读懂代码与数据的存放方式,也方便在接手旧项目时判断哪些设置可以沿用、哪些需要重新核对。希望以上内容能帮助大家理清配置思路,遇到链接错误或启动异常时,少一些反复试改。如果有相关需求,欢迎联系我们咨询。
