This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/CC2640:链接器失败,但RAM可用

Guru**** 2528470 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/567776/compiler-cc2640-linker-fails-but-there-is-ram-available

部件号:CC2640

工具/软件:TI C/C++编译器

您好,

我正在处理一个基于SimpleBLEPeripheral的项目,当增加我的一个任务的堆栈大小时,我遇到了这个错误。

cc26xx_ble_app_oad.cmd",第119行:错误#1.0099万-D:程序将不适合可用内存。 对".stack"区域大小0x258执行定位失败。  可用内存范围:
  SRAM        大小:0x44bf      未使用:0x553       最大孔:0x23b     


我发现这个错误的奇怪之处是,0x258 (600)字节的分配失败,有1363 (0x553)字节可用,最大的孔只有0x23b (571)字节长。 为什么会发生这种情况? 是否有任何方法可以使链接程序重新排列RAM,以便创建更大的孔,并且我可以使用剩余的RAM?

这是我的链接程序脚本:

#ifndef app_base
#define app_base 0x0万
#endif //app_base

#define flash_size 0x2万
#define page_size 0x1000
#define RAM_BASE 0x2000万
#define RAM_SIZE 0x5000


/*系统内存映射*/

内存
{
/*存储在中的应用程序,从0x0 */开始的内部闪存执行
/*闪存大小128 KB */
#ifdef ICALL_STACK0_ADDR
Flash (RX):Origin = app_base,length = ICALL_STACK0_ADDR - app_base -1
#else //默认
Flash (RX):origin = app_base,length = 0x0000CFFF
#endif

/*应用程序使用内部RAM存储数据*/
/* RAM大小16 KB */
#ifdef ICALL_ram0_ADDR
SRAM (rwx):origin = RAM_BASE,length = ICALL_RAM0_ADDR - RAM_BASE -1
#else //默认
SRAM (rwx):origin = RAM_BASE,length = 0x0.0002万CFF
#endif
}/*

内存中的节分配*/

节
{
intvecs :> app_base
文本 :>闪烁
。const :>闪烁
.constdata :>闪烁
.rodata :>闪烁
cinit :>闪烁
。销钉 :>闪烁
init_array :>闪烁
.EMB文本 :>闪烁

.vtable :> SRAM
.vtable_ram :> SRAM
vtable_ram :> SRAM
数据 :> SRAM
BSS :> SRAM
sysmem :> SRAM
堆栈 :> SRAM (高)
nonretenvar :> SRAM
}/*

创建指向堆栈顶部的全局常量*/*
CCS:在项目属性*/
__stack_top =__stack +__stack_size下更改堆栈大小; 

谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    向我们显示您的链接程序映射文件(链接程序选项--map_file =文件名)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    考古学家,您好!

    这是失败的版本的.map (上载为.txt)文件。 这是应用程序的.map文件,BLE堆栈和引导加载程序(基于BIMExtFlash)是单独构建的。

    e2e.ti.com/.../Bold.txt

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    SRAM中间有几个名为DMA(Rx/Tx) ControlTableEntry (0/1)的绑定段,对可用空间进行了分段。  是的,SRAM中还有很多空间,但是没有一个空间足以容纳.stack部分。  该linke将.bss和.data都放置在SRAM的高端,可能是因为它们不适合其它任何地方,因此没有空间放置.stack。

    最简单的修复方法是更改链接程序映射文件,如下所示:

    数据 :>> SRAM
    BSS :>> SRAM
    

    ">>"位置运算符允许链接器将.DATA和.BSS拆分为较小的块,由于绑定的部分,这些块更容易适应可用的间隙。

    如果这不起作用,我可以提出更多建议。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很好,解决了问题,谢谢! 我相信TI的SPI驱动程序使用DMA外设,但我不知道为什么这些表绑定到这些内存区域。
    是否有任何理由使用'>'而不使用'>>'(假设我不需要整个部分是连续的)?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当需要分区连续时,必须使用>而不是>>;例如.stack和.sysmem
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    考古学家,您好!


    昨天我开始想,.bss部分是否通常包含单个全局变量,而.ddata部分是否初始化了变量? 我一直认为低级初始化例程利用了这一点,例如,通过调用memset(BSS, BSS_length, 0)和memcpy(data, data_init_values, data_length)。 TI初始化代码是否执行类似步骤? 如果是这种情况,我是否会通过允许拆分.bss和.data来破坏此机制?


    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    与编译器中的许多内容一样,如果只是简单... 在EABI中,链接程序生成一个带有一系列初始化记录的.cinit表,这些记录通常是压缩的;此表可以轻松处理分割的.bss和.data节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    哈哈,也许我的理解过于简单化了。 再次感谢!