如何解决 IAR 中的“链接器部分放置错误”

问题描述

我正在尝试在 M2S150 开发套件上的 ARM Cortex M3 上运行一些基本的以太网应用程序(通过 lwIP),但遇到了一个我不明白的问题:

错误[Lp011]:节放置失败,无法为中总估计最小大小为0x8dc8字节(最大对齐0x8)的节/块分配空间(总未提交空间0x8000) .

经过进一步研究,一些论坛提到问题可能是您的程序不适合闪存(考虑到我只是为了测试而调用一个函数,我对此表示怀疑)。其他来源提到修改链接器 icf 文件,但我不确定这是否是正确的方法,因为 Libero 在您创建 IAR 项目时会生成 icf 文件,并且会包含有关您正在使用的开发板的信息。

这是我正在尝试运行的当前代码

/* lwIP includes. */
#include "lwip/init.h"

int main(void)
{
  
  lwip_init();

  for(;;){}

  //Should never reach here.
  return 0;
}

谁能提供一些有关为什么会发生这种情况的见解?

编辑添加了 ESRAM ICF 文件

/******************************************************************************/
/*  (c) copyright 2015 Microsemi SoC Products Group. All rights reserved.     */
/*  SmartFusion2 scatter file for debugging code executing in internal eSRAM. */
/*                                                                            */
/*  SVN $Revision: 7419 $                                                     */
/*  SVN $Date: 2015-05-15 16:50:21 +0100 (Fri,15 May 2015) $                 */
/******************************************************************************/
/* 
 * Some current (April 2015) dev kit memory map possibilities are
 * --Type-------Device-----------address start---address end----size---Dbus--RAM IC-------SF2--Comment---------------
 * --eNVM-------M2S010-----------0x60000000------0x6007FFFF-----256KB---------------------010------------------------
 * --eNVM-------M2S090-----------0x60000000------0x6007FFFF-----512KB---------------------090------------------------
 * --eSRAM------M2Sxxx-----------0x20000000------0x2000FFFF-----64KB----------------------xxx--All have same amount--
 * --eSRAM------M2Sxxx-----------0x20000000------0x20013FFF-----80KB----------------------xxx--If ECC/SECDED not used
 * --Fabric-----M2S010-----------0x30000000------0x6007FFFF-----400Kb---------------------010--note-K bits-----------
 * --Fabric-----M2S090-----------0x30000000------0x6007FFFF-----2074Kb--------------------090--note-K bits-----------
 * --LPDDR------STARTER-KIT------0xA0000000------0xA3FFFFFF-----64MB---16--MT46H32M16-----050------------------------
 * --LPDDR------484-STARTER-KIT--0xA0000000------0xA3FFFFFF-----64MB---16--MT46H32M16-----010------------------------
 * --LPDDR------SEC-EVAL-KIT-----0xA0000000------0xA3FFFFFF-----64MB---16--MT46H32M16LF---090--Security eval kit-----
 * --DDR3-------ADevKit----------0xA0000000------0xBFFFFFFF-----1GB----32--MT41K256M8DA---150------------------------
 * --Some older physical memory map possibilities are
 * --Type-------location---------address start---address end----size---Dbus---RAM IC------SF2--Comment--------------
 * --LPDDR------EVAL KIT---------0xA0000000------0xA3FFFFFF-----64MB-=-16--MT46H32M16LF---025--Eval Kit--------------
 * --DDR3-------DevKit-----------0xA0000000------0xAFFFFFFF-----512MB--16--MT41K256M8DA---050------------------------
 */
/*###ICF### Section handled by ICF editor,don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x20000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x20000000;
define symbol __ICFEDIT_region_ROM_end__   = 0x20007FFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20008000;
define symbol __ICFEDIT_region_RAM_end__   = 0x2000FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__   = 0x800;
/**** End of ICF editor section. ###ICF###*/

define memory mem with size = 4G;
define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];

define block CSTACK    with alignment = 8,size = __ICFEDIT_size_cstack__   { };
define block HEAP      with alignment = 8,size = __ICFEDIT_size_heap__     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,block CSTACK,block HEAP };

解决方法

错误消息告诉您,您已指示链接器将 36296 字节的数据放入大小为 32768 的内存区域。通过将错误消息中的地址范围与 .icf 文件中的区域定义进行匹配,您可以看到这对应于 RAM_region

根据放置指令,该区域包含所有读写数据、预定义块 CSTACK 和预定义块 HEAP。由于堆栈和堆块很小,主要的罪魁祸首可能是读写数据的大小。 要了解每个模块需要多少读写数据,您可以使用链接器映射文件。地图文件包含一个类似于以下示例的模块摘要。本节列出了每个目标文件对生成的二进制文件的贡献(包括系统库中的文件)。例如,下面的 file1.o 贡献了 44 个字节的代码和 5 个字节的数据。

***************************************************************************
*** MODULE SUMMARY
***

    Module            ro code  ro data  rw data
    ------            -------  -------  -------
command line/config:
    -------------------------------------------
    Total:

/home/johanb/slask: [1]
    file1.o                44                 5
    file2.o                20
    file3.o                44                 1
    -------------------------------------------
    Total:                108                 6

dl7Sx_tln.a: [2]
    exit.o                  4
    low_level_init.o        4
    -------------------------------------------
    Total:                  8

m7Sx_tlv.a: [3]
    fpinit.o               40
    -------------------------------------------
    Total:                 40

rt7Sx_tl.a: [4]
    cexit.o                16
    cmain.o                48
    cstartup.o            148
    data_init.o            48
    vectortrap.o            4
    zero_init3.o           56
    -------------------------------------------
    Total:                320

sh7Sxs_l.a: [5]
    exit.o                 20
    unwind_debug.o                   1
    xreturnswi.o            4
    -------------------------------------------
    Total:                 24        1

    Linker created          8       16   32'768
-----------------------------------------------
    Grand Total:          508       17   32'774

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...