トロンフォーラム

第8回 メモリ管理機能

今回はT-Kernelのメモリ管理機能について説明します。

T-Kernelは組込み機器用のRTOSです。本連載の第1回(RTOS概論)でも説明したとおり、組込み機器では限られたリソースを有効に活用しなければなりません。その分りやすい例がメモリです。

情報系のOSでは、GB(ギガバイト)単位でメモリを搭載していたり、仮想メモリを利用することを前提にしていたりするため、メモリが枯渇する心配はほとんどありません※1

ところが、組込み機器ではそうはいきません。実行中にメモリを確保しようとしても、メモリ不足により獲得できない可能性がありますので、そのような前提でプログラムを開発する必要があります。

そこで、T-Kernelでは、メモリを管理するための機能として以下の2種類を用意しています。

  • 可変長メモリプール
  • 固定長メモリプール

今回は、これらの使い方について説明します。

可変長メモリプール

可変長メモリプールは、任意のサイズのメモリブロックを管理するための機能です。

C言語のライブラリにmallocという関数がありますが、これに似た機能を提供します。

mallocとの主な違いは以下の通りです。

  • 用途別に複数のメモリプールを用意することができる。
  • メモリブロックを獲得できない場合のタイムアウトを指定することができる。

T-Kernelでは複数のメモリプールが利用できますので、たとえば、メモリ不足の際に待ってもよい処理と、メモリ不足による中断が許されないクリティカルな処理に対して、別々のメモリプールを割り当てることができ、クリティカルな処理が他の処理から影響されにくいシステムを構築できます。

図4 リスト2で追加した変換機能の全体構成

図4 リスト2で追加した変換機能の全体構成

メモリが獲得できない場合、情報系のOSでは、メモリ不足の場合に二次記憶にメモリ内容を退避すること(ページアウト)でメモリの空き領域を確保したり、自動的にガベージコレクションを行ってくれる場合もあります。これらは便利な機能ではありますが、いつメモリが獲得できるのかが分らないまま延々待たされる危険性があるので、リアルタイム性が必要とされる組込み機器には不向きです。

一方T-Kernelでは、メモリが獲得できない場合の動作を明確に制御できるように、メモリ獲得用のシステムコールにタイムアウト機能が付いています。タイムアウト時間を指定できるので、メモリが獲得できない場合の動作として以下を選択することができます。

  • メモリが獲得できなければ即時エラー終了する。
  • メモリが獲得できるまで待つ。
  • 指定された時間待ってもメモリを獲得できなければエラー終了する。

このように、メモリを獲得できなかった場合に、待ち時間の最大値をアプリケーションから制御することで、システム全体としてのリアルタイム性を確保できるようになっています。

図2 可変長メモリプールとmalloc (2)

図2 可変長メモリプールとmalloc (2)

リスト1に、実際に可変長メモリプールを利用した例を示します。

※ 以下のサンプルプログラムはこちらからダウンロードできます。

リスト1は、コンソールから入力した文字列の簡単なヒストリ機能を実現するプログラムです。コンソールから入力された文字列※2を保存しておいて、後から一覧を表示したり、以前に入力した別の文字列に置き換えたりできます。

文字列が入力されると、可変長メモリプールから必要なサイズのメモリブロックを獲得し、そこに保存していきます。また、新しい文字列の入力があった場合、古い入力文字列を入れたメモリブロックを解放することにより、メモリが不足しないようにしています。

ヒストリ機能に対するコマンドは以下の2種類です。

  • exit
    プログラムを終了する。
  • history
    保存されている履歴を表示する。

また、以下を入力すると以前入力した文字列(コマンド)に置き換えます。

  • ##
    直前のコマンドに置き換える。
  • #[数字]
    [数字]で示される履歴番号のコマンドに置き換える。
  • #-[数字]
    [数字]で示されるだけ前のコマンドに置き換える。

なお、リスト1ではわざとメモリプールのサイズを少なく設定しています。このため、たくさんの文字列を入力し続けるとメモリブロックを獲得できなくなります。

試しに、60文字前後の文字列を入力し続けてください。aaaaaa...aaaとかbbbbbb...bbbとかで構いません。数回入力するとメモリブロックが獲得できなくなって、3秒間反応がなくなります。(この時間は16行目のTMO_GETBLKで指定しています。)その後、またプロンプト( '>' ) が表示されて入力待ちになります。

少ない文字数であれば入力できますので、今度は1文字だけ入力して[Enter]を入力してください。すると以前に獲得していたメモリブロックが解放されて、新たにメモリブロックを確保できるようになります。


※1 このため、情報系OS用のドライバやアプリケーションでは、メモリ不足に関するエラー処理が省略されているものもあります。それでも、メモリが枯渇する心配はほとんどないのでたいがいは動作してしまいます。

※2 実装を簡単にするため、コンソールからの入力にはT-Monitorのtm_getline()を利用しています。tm_getline()用のバッファは80バイトしか用意していませんので、それ以上は入力せず、その前に必ず[Enter]を入力してください。入力しすぎた場合は[DEL]やCtrl+Hで文字を削除してください。

Return Top