2012-04-09 5 views
2

내 펌웨어에 malloc 지원을 추가하고 있는데 뭔가 빠졌다고 생각합니다!arm7에 gcc가있는 malloc 구현 문제 : malloc이 NULL을 반환 함

가 나는 ARM7TDMI 프로세서에 대한 코드 소서리의 g ++ 라이트 라이브러리를 사용하여 내 코드는이 링크에있는 예제를 기반으로 : 내 _sbrk의 버전에 추가

http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/t/44452.aspx#539503 :

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)

을 I 단계 모드에서이 프로그램을 실행

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/무료 통화를했던 곳

은 여기 내 주를합니다. malloc을 호출하면 결국 _sbrk 구현을 호출하고 반환 값 (prev_heap_end)은 예상 값을 갖지만 프로그램이 주값으로 돌아 오면 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이 될 수 있습니다. 너 그거 해봤 니? –

+1

@SB는 정적 변수가 0으로 초기화되는 BSS로 들어가지만 포인트를 가질 수도 있지만 검사할만한 가치가 있습니다. 또 다른 문제는 heap_end를 HEAP_BEND가 아니라 HEAP_END로 초기화해야한다는 것입니다. 그렇지 않으면 메모리 외부에서 힙을 시작할 것입니다. – ams

+0

heap_end가 BSS에 있습니다. 당신은 heap_end에 맞습니다. HEAP_BASE에 있어야합니다. 이제는 잘 작동합니다! 내가 이것을 표시 할 수 있도록 대답에서 이것을 반복 할 수 있습니다! 감사합니다. –

답변

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

이 읽어야합니다

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

그래서 당신은 당신의 힙의 끝에서 힙을 시작하지 마십시오 ... 당신은 그 변수가 다음에 heap_end 더 나은 이름을 생각 할 수 있습니다 이 혼란을 피하십시오.

또한 인라인 어셈블리를 올바르게 작동시키기 위해 레지스터 한정자를 사용할 필요가 없습니다. 컴파일러는 당신을 위해서 그렇게 똑똑합니다.

관련 문제