IAR编译错误

1 错误提示:

Error[e104]: Failed to fit all segments into specified ranges. Problem discovered in segment XDATA_N. Unable to place 2 block(s) (0xc02 byte(s) total) in 0xbdf byte(s) of memory. The problem occurred while processing the segment placement command "-P(XDATA)XDATA_N=_XDATA_START-_XDATA_END", where at the moment of placement the available memory ranges were "XDATA:1321-1eff"

cc2540有8K的XDATA,我们定义一些数组时可能超过可它的大小,编译器就会报错。

解决方案:减小堆的大小空间。(堆太小可能会导致有些功能缺陷,所以要找一个最适合程序的值)

修改方式:在预编译选项里面(c/c++ compiler)中的INT_HEAP_LEN,TI默认值是3072,可以修改为为1000.

参考出处:

http://www.deyisupport.com/question_answer/wireless_connectivity/f/45/t/16467.aspx


2 错误提示:

Fatal Error[e72]: Segment IMAGE_HEADER must be defined in a segment definition option (-Z, -b or -P)

查看文件的路径中是否有中文,有的话,最好改路径选项。


3 错误提示:

Error[e104]: Failed to fit all segments into specified ranges. Problem discovered in segment BANKED_CODE. Unable to place 78 block(s) (0x1e36a byte(s) total) in 0x1b408 byte(s) of memory. The problem occurred while processing the segment placement command "-P(CODE)BANKED_CODE=_CODE_BEG-_CODE_END,_BANK4_BEG-_BANK4_END,_BANK5_BEG-_BANK5_END,_BANK6_BEG-_BANK6_END,_BANK7_BEG-_BANK7_END", where at the moment of placement the available memory ranges were "CODE:30f0-3ff7,CODE:4b000-4ffff,CODE:591c2-591c3,CODE:59302-5ffff,CODE:68000-6ffff,CODE:78000-7e7ff"

说明:cc2540 XDATA内存不足


一般就需要优化代码,减少冗余数组

解决办法:

在预编译里面有一个INT_HEAP_LEN属性,默认的值为3027,将他改小到1000或者更小,这个问题就可以解决。

 

###############################################################################

为什么会这样子呢?我们可以来分析一下。

 

首先,我们得了解CC2540的存储器的情况。

 

CC2540里的四种存储空间(结构上划分的存储空间,并不是实际的存储器,是一种理论上的概念)
     
 1.  CODE   程序存储器   用处存放程序代码和一些常量
           
16根地址总线,所以CODE的寻址范围是 0000H~FFFFH64KB

    
  2.  DATA   数据存储器   用于存放程序运行过程中的数据
           
8根地址总线,所以DATA的寻址空间为 00H~FFH256 byte.128位可以直接寻址,高128位只能间接寻址。

      
3.  XDATA  外部数据存储器(只能间接寻址,访问速度比较慢) DMA是在XDATA上寻址的,这一点很重要
           
16根地址总线,所以 XDATA的寻址空间为 0000H ~ FFFFH64K

      
4.  SFR  特殊功能寄存器  就是那些T1CTL, EA, P0等配置寄存器存储的地方128K。因为CC2530的配置寄存器比较多,所以一些多余的寄存器就放到了XREG 里面。XREG的大小为1K XREG的访问速度比 SFR慢。

 


从图中可以看出,XDATA中包含了所有存储器的映射,包括256kbFLASH存储器,8KSRAM存储器,还有 SFR , XREG, INFORMATION FAGE。这里看出来,其实CC2530DATA, XDATA,都是用SRAM作为物理存储媒介的,但是它们的寻址方式不一样,所以访问DATA,比访问XDATA要快。至于SFR,XREG,INFORMATION PAGE,我不知道它们用了什么物理存储媒介,但是它们都被映射到XDATA上,可以被DMA访问。

这里要搞清楚一个概念,映射到XDATA上,不代表就只能用XDATA的寻址方式访问。比如SFR,它虽然被映射到了XDATA上,只能说明,DMA可以通过访问XDATA来操作SFR,但是CPU还是可以通过单周期访问SRF.打个比方,我们平时坐的公交车上都有一把逃生应急锤,在紧急情况下可以敲破窗子逃生。我们平时不会使用锤子敲碎窗子进出车厢,我们平时有车门可以走。但是在特殊情况下(比如DMA要操作某个存储器中的数据时),我们可以用特殊的方法(从XDATA上的映射来得到我们想要的数据)。

*************************************************************************

虽然上面说了这么多,其实我们只需要了解到:DATAXDATA存在SRAM上,而CODE存在Flash上就可以了。哪一段的代码溢出我们就处理哪一段。CC2540256KBFlash8KBSRAM

 

我们在Output文件夹的.map文件中的最后可以看到

166 159 bytes of CODE  memory

      26 bytes of DATA  memory (+ 81 absolute )

   6 396 bytes of XDATA memory

     192 bytes of IDATA memory

       8 bits  of BIT   memory

   4 478 bytes of CONST memory

也就是我们比较关心的DATA+XDATA所占的内存不能SRAM8KB,这就是我们处理问题的关键。那么,我们知道DATA是用于存放程序运行过程中的数据。XDATA中包括堆的定义,也就是堆数组包括在XDATA

**********************************************************************

那么我们把INT_HEAP_LEN的值改小以后,程序有什么影响呢?

正如前面所说的INT_HEAP_LEN位于XDATA,它是一个堆,是为了动态内存分配的,BLE协议栈使用动态分配了几个功能,主要用于执行加密和存储安全密钥。如果你减少INT_HEAP_LEN的值太多,加密就会失败。现在设想一个主机可以可以用加密的方式同时连接到三个从机。这里的堆大小就需要特别大,如果没有充足的空间,程序将无法执行。但是如果INT_HEAP_LEN值改的太大,又影响了运行中的数据处理。所以一个合适的INT_HEAP_LEN值,是比较难找的。

Heap size is reserved for dynamic memory allocation in the stack. Reduced

heap size may reduce the performance and may reject packets in the heavily

loaded system especially for Coordinator. 1K heap would be enough for some

small demo i.e. LIGHT – SWITCH demo, it depends on the application and how

much data to send.

 

*************************************************************************

那么为什么我们把INT_HEAP_LEN的值改小以后,程序就能正常执行了呢?

OSAL_Memory.c中我们找到了

{

static __no_init osalMemHdr_t theHeap[MAXMEMHEAP / OSALMEM_HDRSZ];

}

其中MAXMEMHEAP的定义,我们在Onboard.h中可以找到

{

// Memory Allocation Heap

#if defined( EXTERNAL_RAM )

  #define MAXMEMHEAP EXT_RAM_LEN   // Typically, 32K

#else

  #define MAXMEMHEAP INT_HEAP_LEN  // Typically, 0.70-1.50K

#endif

}

 

上面的代码就是定义了一个堆,大小为(MAXMEMHEAP / OSALMEM_HDRSZ)

 

所以,INT_HEAP_LEN的大小就决定了整个堆的大小,我们可以适当的减小INT_HEAP_LEN的值来达到减少程序大小的目的。


参考:

Referencehttp://e2e.ti.com/support/low_power_rf/f/538/t/95098.aspx

http://blog.sina.com.cn/s/blog_4c8287230100d5hx.html

http://e2e.ti.com/support/low_power_rf/f/538/t/163680.aspx

http://www.deyisupport.com/question_answer/analog/wireless_connectivity/f/45/t/16467.aspx

http://blog.csdn.net/bailyzheng/article/details/7541422






  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值