`.bss' will not fit in region `m_data' 內存越界

背景: 

Freescale(NXP)kinetis MCU在使用FreeRTOS時, 用armgcc gnu編譯鏈(KSD,CW等IDE均使用ARM GCC編譯鏈)時報錯:

section `.bss' will not fit in region `m_data'

錯誤提示其實是bss段超出了m_data的範圍,我的MCU內部SRAM大小是64KB, 怎麼可能不夠用呢?

問題分析:

上面也提到了這是由於.bss段所需內存大於了m_data段所能提供的內存。首先反應去google。找到一篇十分相符的文章:
這篇文章是說kinetis K系列MCU的內存是分兩段的,一般以0x2000’0000爲分界線分RAM爲SRAM_L, SRAM_U(SRAM_L由code bus訪問,SRAM_U由system bus訪問),而gcc的編譯鏈不夠智能,不能把內容分到兩段裏面,只能在一段裏面。事實上kinetis MCU K系列,KE系列都是以0x2000’0000爲分界線。

解決方法:

那麼問題來了,Erich Styger是因爲用的k20給個segment只有8kb,所以SRAM不夠,可以我的MCU每個segment有32kb。同時根據另一篇文章的解決方法https://community.freescale.com/thread/322318(文中提到的文章不需要看,此文可以解決你的問題),我在link file裏面改變了變量所在的位置, 比如我的link file裏是這樣的:
/* Specify the memory areas */
MEMORY
{
  m_interrupts          (RX)  : ORIGIN = 0x00000000, LENGTH = 0x00000400
  m_flash_config        (RX)  : ORIGIN = 0x00000400, LENGTH = 0x00000010
  m_text                (RX)  : ORIGIN = 0x00000410, LENGTH = 0x0007FBF0
  m_data                (RW)  : ORIGIN = 0x1FFF8000, LENGTH = 0x00008000
  m_data_2              (RW)  : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

可以看到,有兩段內存m_data,m_data_2,把.data段由初始的放到m_data段改到放到m_data_2也是提示同樣的問題。至於gcc工具鏈下link file的相關知識可以參考附件:http://download.csdn.net/detail/guo8113/9379185

  .data : AT(__DATA_ROM)
  {
    . = ALIGN(4);
    __DATA_RAM = .;
    __data_start__ = .;      /* create a global symbol at data start */
    *(.data)                 /* .data sections */
    *(.data*)                /* .data* sections */
    KEEP(*(.jcr*))
    . = ALIGN(4);
    __data_end__ = .;        /* define a global symbol at data end */
  } > m_data

我們知道.data字段放着程序中初始化的變量,.bss存放未初始化的變量。假如你的MCU RAM比較小,可以通過計算來合理分配他們在SRAM_L還是SRAM_U裏。

然而不要忘了一件事情,也是我遇到的問題,RTOS一般會聲明自己所用的棧的大小,這個棧用於任務以及動態內存的分配。如果這個大小配置不合理也同樣會導致stack overflow的情況。

比如FreeRTOS,在FreeRTOSConfig.h中定義了

#define configTOTAL_HEAP_SIZE ((size_t)(30 * 1024))

而這個宏超過了SRAM所能提供的大小,從而導致了我的問題。因此使用RTOS還是按需來設置,copy配置文件可能會存在潛在的問題。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章