2

ファームウェアに malloc サポートを追加していますが、何か足りないと思います!

私は arm7tdmi プロセッサ用のコード ソース g++ lite ライブラリを使用しています。私のコードは、次のリンクにある例に基づいています。 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/free 呼び出しを行ったメインは次のとおりです。

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) には期待値がありますが、プログラムがメインに戻ると、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"

助けてくれてありがとう!

4

1 に答える 1

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

これは次のようになります。

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

したがって、ヒープの最後でヒープを開始しないでください...最初にこの混乱を避けるために、その変数のより良い名前を考えてから heap_end を使用することをお勧めします。

また、インライン アセンブリを正しく機能させるために register 修飾子を使用する必要はありません。コンパイラは、それを行うのに十分スマートです。

于 2012-06-30T04:14:41.490 に答える