2012-04-09 53 views
2

我在我的固件中添加了malloc支持,我想我錯過了一些東西!在arm7中使用gcc實現malloc問題:malloc返回NULL

我使用代碼的Sourcery克++精簡版庫的ARM7TDMI處理器和我的代碼是基於在此鏈路中發現的例如:http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/t/44452.aspx#539503

我加入我的版本_sbrk的:

char * _sbrk(int incr) 
{ 
    //extern char _end; /* Defined by the linker */ 
    static char *heap_end; 
    char *prev_heap_end; 
    register char* stackPtr; 

    if (heap_end == 0) 
    { 
     // first allocation 
     heap_end =HEAP_END; 
    } 

    prev_heap_end = heap_end; 

    // get current stack pointer 
    asm ("mov %0, sp\n\t" : "=r" (stackPtr)); 



    if (heap_end + incr > stackPtr) { 
     return NULL;// error - no more memory 
     //write (1, "Heap and stack collision\n", 25); 
     //abort(); 
    } 
    heap_end += incr; 
    return (char*) prev_heap_end; 
} 

一些定義了用於通過SBRK:

#define SDRAM_SIZE 16*1024*1024   
#define HEAP_BASE _ebss 
#define HEAP_END ((_stext + SDRAM_SIZE) -1) 
#define HEAP_SIZE HEAP_END - HEAP_BASE 

(_ebss和_stext來自我的連接文件)

這裏是我的主,我做了一個簡單的malloc /免費電話:

void C_main (void) 
{ 
    char * testmalloc=0; 
    /* Initialize "Heap Descriptor" pointer */ 
    pHeapDescriptor = __rt_embeddedalloc_init ((void*)HEAP_BASE,HEAP_SIZE); 
    testmalloc = malloc(2048); 
    free(testmalloc); 
} 

我運行這個程序步驟模式。當我調用malloc時,它最終會調用我的_sbrk實現,返回值(prev_heap_end)具有期望值,但是當程序返回到main時,testmalloc值爲NULL(gcc庫中的某處,prev_heap_end丟失)。

有人知道我做錯了什麼嗎?

不知道這是否會幫助,但這是我的gcc編譯參數:

arm-none-eabi-gcc -march=armv4t -mcpu=arm7tdmi -dp -c 
-Wa,-adhlns="../../Base/Lib/Pa/main.o.lst" -fmessage-length=0 
-fno-zero-initialized-in-bss -MMD -MP -MF"../../Base/Lib/Pa/main.d" 
-MT"../../Base/Lib/Pa/main.d" -fpic -mlittle-endian -Wall -g3 -gdwarf-2 
../../Base/Hardintrf/Mezzanine/main.c -o"../../Base/Lib/Pa/main.o" 

在此先感謝您的幫助!

+0

您的第一個全局變量沒有初始化,所以它們可能不會像最初假設的那樣保證爲NULL。你嘗試過嗎? – 2012-04-09 22:12:25

+1

@SB可能有一點,雖然靜態變量應該進入BSS,它將被初始化爲零,但是值得檢查。另一個問題是我認爲你應該將heap_end初始化爲HEAP_BASE而不是HEAP_END,否則它會在內存之外啓動堆,不是嗎? – ams 2012-04-10 10:43:13

+0

heap_end在BSS中。你對heap_end是正確的,它必須是HEAP_BASE,現在它工作的很棒!你可以在答案中重複這個,所以我可以標記它! 謝謝! – 2012-04-10 14:40:02

回答

1
if (heap_end == 0) 
{ 
    // first allocation 
    heap_end = HEAP_END; 
} 

這應該閱讀:

if (heap_end == 0) 
{ 
    // first allocation 
    heap_end = HEAP_BASE; 
} 

所以你不要在你的堆月底開始你的堆...你可能要考慮一個更好的名字爲變量,然後heap_end到首先避免這種混淆。

此外,您不需要使用寄存器修飾符使內聯彙編正常工作。編譯器足夠聰明,可以爲你做到這一點。