ソフトウェアを開発していて、処理が遅い、パフォーマンスが足りない!と思うことがよくあります。
その度に、更にパフォーマンスが高いマイコンを選定していては、システムの部材コストがあがり青天井状態になります。
資材調達チームからは、厳しい価格目標があり、高い性能のマイコンを選ぶのにも限界があります。
そこで、プログラム実行の性能を上げる一つの手法として、コードを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の領域に配置されるはずです。
早速、何もしない場合のビルド後のマップファイルを確認してみます。
test()関数は、0x13e1に配置されています。
今回使用しているKinetis K64Fのメモリ構成は、以下のようになっています。
RAM領域は、0x1fff_0000 – 0x1fff_ffffと0x2000_0000 – 0x2002_ffffの2つに分かれています。
__ramfunc拡張キーワードを使用した場合
次に、test()関数の宣言に__ramfunc拡張キーワードを使用してみます。
RAMから実行したい関数(今回はtest())にのみ__ramfunc拡張キーワードを付けて定義します。EWARMを使用する場合は、これだけで対象の関数を自動的にRAMから実行することが可能です。
たったこれだけです。リンクファイルには一切手を入れません。
__ramfunc void test()
{
volatile uint32_t cnt;
cnt++;
}
では、ビルドしてマップファイルを確認してみます。
__ramfunc指定した場合のマップファイルです。
0x1fff00dとなっています。確かに、RAM領域となっていることが確認できます。
test()関数は、EWARMのイニシャライザによって、__ramfunc指定されている関数や変数をFlashからRAMに自動的に配置し、コピーしてくれます。
デバッグして確認
実際にデバッグしてtest()関数がRAMから実行されているか確認してみます。test()関数にブレイクして、実行アドレスを確認すると、確かにRAM領域のアドレスになっているのが、確認できると思います。
確かに、RAMにジャンプしていますね。
まとめ
IAR EWARMを使用すると、__ramfunc拡張キーワードという呪文を使用するだけで、任意の関数を超簡単にRAMから実行させることが可能です。
また、関数のRAM領域の配置もIAR EWARMが自動的に配置し、FlashからRAMにコードのコピーも自動で行なってくれます。至れり尽くせりです。
関数のRAM実行は、実行スピードだけでは無く、フラッシュへの書き込み動作が必要な場合に、フラッシュROMによってはコード実行をRAMから実行させる必要があるケースがあります。このような場合にも、関数のRAM実行が必要になります。
今回は、自動的にRAMに配置させ、RAMから実行しましたが、場合によってはRAMのアドレスを指定したい場合もあると思います。
いずれ、手動で関数をRAMに任意のアドレスへ配置させ、実行させる手法を見ていきます。
最後までお読みいただきありがとうございます。
もし、良かった!と思われたら、シェアして頂ければ幸いです。