3

次の問題に対処する方法を知っている人はいますか。IAREmbedded
ワークベンチがあります。プロジェクトは、コードとフラッシュROMの実行にもSDRAMを使用しています。SDRAMのコードはSDカードからロードされます。ただし、SDRAMには、グローバル変数や静的変数など、いくつかのデータも格納されています。それらのいくつかは初期化する必要があります。初期化ステップであるiar_data_init3関数呼び出しは、low_level_init関数の後に続きます。したがって、問題は、SDRAMの一部の変数の初期化では、初期化関数がから呼び出されiar_data_init3、そのコードがSDRAM自体の内部にあることです。SDカードからのSDRAMコードのロードがまだ行われていないため、これは間違っています。

C / C ++開発ガイドで説明されているように手動で初期化を試みましたが、これは役に立ちませんでした。

呼び出される関数は__sti__routine、変数の初期化を提供するです。これらの関数はすべてIARによって生成されます。初期化機能をフラッシュROMに配置するようにリンカに指示する方法はありますか?

編集1: これはC /C++のIARマニュアルからの情報です。これは、手動初期化の使用方法の例です。

リンカ設定ファイル:

initialize manually { section MYSECTION };

次に、IARのドキュメントには次のように書かれています。

このソースコードの例を使用して、セクションを初期化できます。

#pragma section = "MYSECTION"
#pragma section = "MYSECTION_init"
void DoInit()
{
char * from = __section_begin("MYSECTION_init");
char * to = __section_begin("MYSECTION");
memcpy(to, from, __section_size("MYSECTION"));
}

しかし、まず、MYSECTION_initとMYSECTIONの違いがわかりません。また、グローバル変数がある場合:

SomeClass myclass;

そして、それをSDRAMに配置する必要があります。それでは、初期化はどのように行われますか?変数を手動で初期化し、その初期化関数をフラッシュROMに配置したいと思います。(問題は、SDRAMに変数を配置することにより、その初期化関数もSDRAMに配置されることです)。

4

1 に答える 1

4

pragmaプリプロセッサディレクティブを使用して、変数と関数の場所を指定できます。事前定義されたセクションのいずれかを使用するか、独自のセクションを定義する必要があります。

使用しているIARの特定のフレーバーについては言及していません。以下はルネサスIARコンパイラリファレンスガイドからのものですが、適切なリファレンスガイドをチェックして、構文が完全に同じであることを確認し、事前定義されたセクションが何であるかを確認する必要があります。

@演算子またはlocationディレクティブを使用して#pragma、各オブジェクトを明示的に制御せずに、関数のグループまたはグローバル変数と静的変数を名前付きセグメントに配置します。__no_init変数は、またはのいずれかで宣言する必要がありますconst。セグメントは、たとえば、メモリの特定の領域に配置したり、セグメントの開始演算子と終了演算子を使用して制御された方法で初期化またはコピーしたりできます。これは、アプリケーションプロジェクトとブートローダープロジェクトなど、別々にリンクされたユニット間のインターフェイスが必要な場合にも役立ちます。個々の変数の配置を完全に制御する必要がない場合、または役に立たない場合は、名前付きセグメントを使用します。

名前付きセグメントに関数を配置する例

void f(void) @ "FUNCTIONS";

void g(void) @ "FUNCTIONS"
{
}

#pragma location="FUNCTIONS"
void h(void);

デフォルトのセグメント割り当てを上書きするには、デフォルト以外のメモリ属性を明示的に指定できます。

__code32 void f(void) @ "FUNCTIONS";

編集

コメントに基づいてgeneric_cortex.icf、メモリ領域を定義するという名前のリンカーファイルが必要です。その中には、次のような指示が含まれているはずです。

/* Define the addressable memory */
define memory Mem with size = 4G;

/* Define a region named SDCARD with start address 0xA0000000 and to be 256 Mbytes large */
define region SDCARD = Mem:[from 0xA0000000 size 0xFFFFFFF ];

/* Define a region named SDRAM with start address 0xB0000000 and to be 256 Mbytes large */
define region SDRAM = Mem:[from 0xB0000000 size 0xFFFFFFF ];

/* Place sections named MyCardStuff in the SDCARD region */
place in SDCARD {section MyCardStuff };

/* Place sections named MyRAMStuff in the SDRAM region */
place in SDRAM {section MyRAMStuff };

/* Override default copy initialization for named section */
initialize manually { section MyRAMStuff };

実際の名前、住所、サイズは異なりますが、似ているはずです。データシートの最初の2つの動的メモリ領域のフルサイズを使用しています。ここで起こっていることは、コンパイル中に名前が付けられたセクションがリンカーによって正しい場所に配置されるように、さまざまなタイプのメモリ(つまり、SDカードとSDRAM)のアドレス空間に名前を割り当てていることです。

define memoryしたがって、最初にアドレス空間を次のように定義する必要があります。

アドレス可能なメモリの最大サイズ

ディレクティブは、指定されたサイズのメモリスペースを定義します。define memoryこれは、アドレス指定可能なメモリの可能な最大量であり、必ずしも物理的に使用可能である必要はありません。

次に、どのチップがどこに行くかを教えてくださいdefine region

利用可能な物理メモリ

define regionディレクティブは、アプリケーションコードの特定のセクションとアプリケーションデータのセクションを配置できる、使用可能なメモリ内の領域を定義します。

次に、リンカは、名前をregion付けて配置する場所を知る必要があります。sectionplace in

リージョンにセクションを配置する

place atandディレクティブはplace into、同様の属性を持つセクションのセットを以前に定義された領域に配置します。

そして、初期化の一部をオーバーライドするリンカーに次のように伝えますinitialize manually

アプリケーションの初期化

ディレクティブinitializedo not initializeは、アプリケーションの起動方法を制御します。これらのディレクティブを使用すると、アプリケーションは起動時にグローバルシンボルを初期化し、コードの一部をコピーできます。

最後に、Cファイルで、どのセクションに何が入るのか、宣言されたセクションを初期化する方法をコンパイラーに指示しますmanually

SomeClass myClass @ "MyCardStuff";

#pragma section = "MyCardStuff"
#pragma section = "MySDRAMStuff"
void DoInit()
{
    /* Copy your code and variables from your SD Card into SDRAM */
    char * from = __section_begin("MyCardStuff");
    char * to = __section_begin("MySDRAMStuff");
    memcpy(to, from, __section_size("MySDRAMStuff"));

    /* Initialize your variables */
    myClass.init();
}

複数の異なるメモリデバイス間で起動初期化をカスタマイズするには、ARM用IAR開発ガイドを注意深く検討する必要があります。また、オプションをオンにして--log initialization、ログとマップファイルを調べて、必要なものが得られていることを確認してください。

于 2012-12-07T12:47:35.013 に答える