2.6.2. スキャッタローディング記述ファイルでのスタックとヒープの配置

多くの場合、スタックとヒープの位置は記述ファイルで指定することをお勧めします。これには、主に以下の 2 つの利点があります。

このセクションでは、この実装方法について説明します。

シンボルの明示的な配置

スタックポインタの初期化では、シンボル stack_base および heap_base を、記述ファイル内に配置できる参照シンボルとして使用しています。これを行うには、stackheap.s という名前のアセンブラモジュール内に、stack_base および heap_base という名前のシンボルを作成します。この方法は、2 つの領域によるメモリモデルのスタックリミットとヒープリミットにも使用できます。

Example 2.15 に示すように、各シンボルは記述ファイル内のそれぞれの実行領域内に配置できます。

Example 2.15. stackheap.s 内でのシンボルの明示的な配置

        AREA   stacks, DATA, NOINIT
        EXPORT stack_base

stack_base        SPACE   1

        AREA   heap, DATA, NOINIT
        EXPORT heap_base
 
heap_base         SPACE   1
	    END

Figure 2.14 および Example 2.16 は、ヒープベースを 0x20000 に配置し、スタックベースを 0x40000 に配置する方法を示しています。スタックベースとヒープベースの位置は、それぞれの実行領域のアドレスを編集することによって変更できます。

この方法の欠点は、SPACE (stack_base) の 1 ワードがスタック領域を越えて使用されることです。

Figure 2.14. シンボルの明示的な配置

シンボルの明示的な配置

Example 2.16. スキャッタローディング記述ファイルでのシンボルの明示的な配置

LOAD_FLASH 0x24000000 0x04000000
{
    ; ...
    HEAP 0x20000 UNINIT
    {
        stackheap.o (heap)
    }

    STACKS 0x40000 UNINIT
    {
        stackheap.o (stacks)
    }
    ; ...
}

リンカ生成シンボルの使用

この方法では、スタックとヒープのサイズをオブジェクトファイルで指定する必要があります。

まず、Example 2.17 に示すように、stackheap.s などのアセンブラソースファイルで、スタックとヒープに適切なサイズのエリアを定義します。

SPACE ディレクティブを使用して、ゼロ初期化されるメモリブロックを予約します。NOINIT エリア属性を設定して、このゼロ初期化を無効にします。

開発時には、スタックを最大限に使用できるように、スタックをゼロ初期化することもできます。このソースファイルでは、ラベルは必要ありません。

Example 2.17. スタックとヒープのセクションの配置

        AREA stack, DATA, NOINIT
    SPACE   0x3000 ; Reserve stack space

        AREA heap, DATA, NOINIT
    SPACE   0x3000 ; Reserve heap space

        END

次に、Example 2.18 に示すように、これらのセクションをスキャッタローディング記述ファイルの各実行領域に配置します。

Example 2.18. スタックとヒープのセクションの配置

LOAD_FLASH 0x24000000 0x04000000
{
    :
    STACKS 0x1000 UNINIT     ; length = 0x3000
    {
        stackheap.o (stack)  ; stack = 0x4000 to 0x1000
    }

    HEAP 0x15000 UNINIT      ; length = 0x3000
    {
        stackheap.o (heap)   ; heap = 0x15000 to 0x18000
    }
}

リンカによって、各実行領域のベースとリミットを指すシンボルが生成されます。これらのシンボルは、__user_initial_stackheap() で使用するターゲット変更コードにインポートできます。

Image$$STACKS$$ZI$$Limit = 0x4000
Image$$STACKS$$ZI$$Base  = 0x1000
Image$$HEAP$$ZI$$Base   = 0x15000
Image$$HEAP$$ZI$$Limit  = 0x18000

Example 2.19 に示すように、DCD ディレクティブを使用してこれらの値に意味のある名前を指定することにより、このコードを読みやすくすることができます。

Example 2.19. DCD ディレクティブの使用

        IMPORT          ||Image$$STACKS$$ZI$$Base||
        IMPORT          ||Image$$STACKS$$ZI$$Limit||
        IMPORT          ||Image$$HEAP$$ZI$$Base||
        IMPORT          ||Image$$HEAP$$ZI$$Limit||

    stack_base  DCD     ||Image$$STACKS$$ZI$$Limit||      ; = 0x4000
    stack_limit DCD     ||Image$$STACKS$$ZI$$Base||       ; = 0x1000

    heap_base   DCD     ||Image$$HEAP$$ZI$$Base||         ; = 0x15000
    heap_limit  DCD     ||Image$$HEAP$$ZI$$Limit||        ; = 0x18000

これらの例を使用して、ヒープベースを 0x15000 に、スタックベースを 0x1000 に配置できます。その後、スタックベースとヒープベースの位置は、それぞれの実行領域のアドレスを編集することによって簡単に変更できます。

スキャッタローディング記述ファイルの EMPTY 属性の使用

この方法では、リンカのスキャッタローディング記述ファイルの EMPTY 属性を使用します。この属性を使用すると、オブジェクトコードやデータを保持しない領域を定義できます。この方法は、スタックまたはヒープを定義する便利な方法です。この領域の長さは、EMPTY 属性の後に指定されます。メモリ内で上方に拡大するヒープの場合、領域の長さは正の値になります。スタックの場合は、メモリ内で下方に拡大することを示すように、領域の長さが負の数としてマークされます。Example 2.20 は、EMPTY 属性の使用方法を示しています。

この方法の利点は、スタックとヒープのサイズおよび位置を 1 つの場所、つまり、スキャッタローディング記述ファイルで定義できることです。stackheap.s ファイルを作成する必要はありません。

Example 2.20. EMPTY を使用したスタック領域とヒープ領域の配置

ROM_LOAD 0x24000000 0x04000000
{
    ...
    HEAP 0x30000 EMPTY 0x3000
    {
    }

    STACKS 0x40000 EMPTY -0x3000
    {
    }
    ...
}

リンク時に、リンカによって、これらの EMPTY 領域を表すシンボルが生成されます。

Image$$HEAP$$ZI$$Base      = 0x30000
Image$$HEAP$$ZI$$Limit     = 0x33000
Image$$STACKS$$ZI$$Base    = 0x3D000
Image$$STACKS$$ZI$$Limit   = 0x40000

その後、Example 2.21 に示すように、アプリケーションコードでこれらのシンボルを処理できます。

Example 2.21. EMPTY 領域を表すリンカ生成シンボル

                IMPORT      ||Image$$HEAP$$ZI$$Base||
                IMPORT      ||Image$$HEAP$$ZI$$Limit||

heap_base       DCD         ||Image$$HEAP$$ZI$$Base||
heap_limit      DCD         ||Image$$HEAP$$ZI$$Limit||

                IMPORT      ||Image$$STACKS$$ZI$$Base||
                IMPORT      ||Image$$STACKS$$ZI$$Limit||

stack_base      DCD         ||Image$$STACKS$$ZI$$Limit||
stack_limit     DCD         ||Image$$STACKS$$ZI$$Base||
Copyright © 2002-2006 ARM Limited. All rights reserved.ARM DUI 0203GJ
Non-Confidential