背景:
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配置文件可能會存在潛在的問題。