IAR EWARMなら関数のRAM実行が超簡単!
魔法の呪文1つだけ。

RAM function is easy

ソフトウェアを開発していて、処理が遅い、パフォーマンスが足りない!と思うことがよくあります。
その度に、更にパフォーマンスが高いマイコンを選定していては、システムの部材コストがあがり青天井状態になります。


資材調達チームからは、厳しい価格目標があり、高い性能のマイコンを選ぶのにも限界があります。

そこで、プログラム実行の性能を上げる一つの手法として、コードをRAMから実行することで実行スピードを上げることが可能です。
ソフトウェア開発技術者の腕の見せ所です。

プログラムコードのRAM実行

プログラムコードを全てRAMから実行しようとすると、広大なRAM領域が必要となり、そもそも小さなRAM領域のマイコンでは無理なため、処理スピードが重要な関数だけをRAMで実行したいというケースがよくあります。(特定のモジュールfoo.cなどのRAM実行は、別の記事で取り上げます。)

しかしながら、通常はコンパイル、ビルドするとプログラムコードは、一旦フラッシュ領域のコードセグメントに配置されますので、フラッシュに配置された目的の関数をRAM領域にコピーする必要があります。

ある関数をRAMから実行するには、IAR社Embedded Workbench for ARM (EWARM) を使用すると、超簡単に関数をRAMに配置してRAMから実行することが可能です。

まずは、要点から。

要点

  • IAR EWARMを利用する
  • IAR社のEWARMでは、関数に__ramfuncという拡張キーワードをつける
  • __ramfunc指定の関数を自動的にEWARMがRAMに配置、コピーしてくれる

では、行ってみましょう。

サンプルコード

FRDM-K64F用のSDK内のHello Worldサンプルコードを使用します。SDKの生成については、以前の記事( MCUXpresso SDK 〜SDKの作り方〜 )を参考にしてください。
テスト用に適当な関数 test()を作成します。



volatile uint32_t cnt;

void test()
{
    
    cnt++;
}

int main(void)
{
    char ch;

    /* Init board hardware. */
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    PRINTF("hello world.\r\n");

    while (1)
    {
        test();
        ch = GETCHAR();
        PUTCHAR(ch);
    }
}

通常通りコンパイル

何にもせずに上記コードをビルドします。上記コードはフラッシュROMの領域に配置されるはずです。

早速、何もしない場合のビルド後のマップファイルを確認してみます。

mapfile-pic1

test()関数は、0x13e1に配置されています。

今回使用しているKinetis K64Fのメモリ構成は、以下のようになっています。

RAM領域は、0x1fff_0000 – 0x1fff_ffffと0x2000_0000 – 0x2002_ffffの2つに分かれています。

memory-map-k64

__ramfunc拡張キーワードを使用した場合

次に、test()関数の宣言に__ramfunc拡張キーワードを使用してみます。
RAMから実行したい関数(今回はtest())にのみ__ramfunc拡張キーワードを付けて定義します。EWARMを使用する場合は、これだけで対象の関数を自動的にRAMから実行することが可能です。

たったこれだけです。リンクファイルには一切手を入れません。


__ramfunc void test()
{
    volatile uint32_t cnt;
    cnt++;
}

では、ビルドしてマップファイルを確認してみます。

__ramfunc指定した場合のマップファイルです。

mapfile-pic2
test()関数の配置を確認します。

0x1fff00dとなっています。確かに、RAM領域となっていることが確認できます。

test()関数は、EWARMのイニシャライザによって、__ramfunc指定されている関数や変数をFlashからRAMに自動的に配置し、コピーしてくれます。

デバッグして確認

実際にデバッグしてtest()関数がRAMから実行されているか確認してみます。test()関数にブレイクして、実行アドレスを確認すると、確かにRAM領域のアドレスになっているのが、確認できると思います。

debug-breakpoint

確かに、RAMにジャンプしていますね。

まとめ

IAR EWARMを使用すると、__ramfunc拡張キーワードという呪文を使用するだけで、任意の関数を超簡単にRAMから実行させることが可能です。

また、関数のRAM領域の配置もIAR EWARMが自動的に配置し、FlashからRAMにコードのコピーも自動で行なってくれます。至れり尽くせりです。

関数のRAM実行は、実行スピードだけでは無く、フラッシュへの書き込み動作が必要な場合に、フラッシュROMによってはコード実行をRAMから実行させる必要があるケースがあります。このような場合にも、関数のRAM実行が必要になります。

今回は、自動的にRAMに配置させ、RAMから実行しましたが、場合によってはRAMのアドレスを指定したい場合もあると思います。

いずれ、手動で関数をRAMに任意のアドレスへ配置させ、実行させる手法を見ていきます。

最後までお読みいただきありがとうございます。

もし、良かった!と思われたら、シェアして頂ければ幸いです。