9.2 固定長メモリ・プール
RI600PXでは,処理プログラムから動的なメモリ操作要求が行われた際に利用するメモリ領域として“固定長メモリ・プール”を提供しています。

なお,固定長メモリ・プールに対する動的なメモリ操作は,固定サイズの固定長メモリ・ブロックを単位として行われます。

9.2.1 固定長メモリ・プールの生成

固定長メモリ・プールは,以下のいずれかの方法で生成します。

1 ) システム・コンフィギュレーション・ファイルによる生成
システム・コンフィギュレーション・ファイルで静的API“memorypool[]”を使用して固定長メモリ・プールを生成します。
静的API“memorypool[]”の詳細は,「20.17 固定長メモリ・プール情報(memorypool[])」を参照してください。



2 ) cre_mpfまたはacre_mpfサービスコールによる生成
cre_mpfは,パラメータpk_cmpfが指す領域に設定された固定長メモリ・プール生成情報にしたがって,パラメータmpfidで指定された固定長メモリ・プールIDの固定長メモリ・プールを生成します。
acre_mpfは,パラメータpk_cmpfが指す領域に設定された固定長メモリ・プール生成情報にしたがって固定長メモリ・プールを生成し,生成された固定長メモリ・プールIDを返します。
指定する固定長メモリ・プール生成情報は,以下の通りです。




- 固定長メモリ・プール属性(mpfatr
以下を指定します。


- タスク待ちキューの順序(FIFO順またはタスクの現在優先度順)

- 獲得可能なメモリ・ブロック数(blkcnt),メモリ・ブロックのサイズ(バイト数)(blksz),固定長メモリ・プール領域の先頭アドレス(mpf
mpfからTSZ_MPF(blkcnt, blksz)バイトを固定長メモリ・プール領域とします。TSZ_MPFマクロについては「18.3.3 固定長メモリ・プール関連」を参照してください。
固定長メモリ・プール領域は,メモリ・ブロックにアクセスするタスクがアクセス可能なメモリオブジェクト内としてください。



- 固定長メモリ・プール管理領域の先頭アドレス(mpfmb
mpfmbからTSZ_MPFMB(blkcnt, blksz)バイトを固定長メモリ・プール管理領域とします。TSZ_MPFMBマクロについては「18.3.3 固定長メモリ・プール関連」を参照してください。
固定長メモリ・プール管理領域は,メモリ・オブジェクト以外でかつユーザ・スタック以外の領域に作成してください。



これらのサービス・コールは,信頼されたドメインに所属するタスクだけが呼び出せます。

以下に,代表としてacre_mpfの記述例を示します。

 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 
 #define BLKCNT 32                       /*獲得可能なメモリ・ブロック数*/
 #define BLKSZ  16                       /*メモリ・ブロックのサイズ(バイト数)*/
 
 #pragma section B BU_SH                 /*固定長メモリ・プール領域のセクション*/
 static UW mpf_area[ TSZ_MPF( BLKCNT, BLKSZ)/sizeof(UW)];/* 固定長メモリ・プール領域*/
 
 #pragma section B BRI_RAM               /* 固定長メモリ・プール管理領域のセクション*/
 static UW mpfmb_area[ TSZ_MPFMB( BLKCNT, BLKSZ)/sizeof(UW)];
                                /* 固定長メモリ・プール管理領域*/
 #pragma section
 #pragma task Task1                      /*備考参照*/
 void Task1 ( VP_INT exinf );            /*備考参照*/
 void Task1 ( VP_INT exinf )
 {
         ID      mpfid;                  /*変数の宣言*/
         T_CMPF  pk_cmpf = {             /*変数の宣言,初期化*/
                      TA_TFIFO,      /*固定長メモリ・プール属性(mpfatr)*/
                      BLKCNT,        /*獲得可能なメモリ・ブロック数(blkcnt)*/
                      BLKSZ,         /*メモリ・ブロックのサイズ(バイト数)(blksz)*/
                      (VP)mpf_area,  /*固定長メモリ・プール領域の先頭アドレス(mpf)*/
                      (VP)mpfmb_area /*固定長メモリ・プール管理領域の先頭アドレス(mpfmb)*/
        };
         ............
         ............
         mpfid = acre_mpf ( &pk_cmpf );   /*固定長メモリ・プールの生成*/
         ............
         ............
 }


備考 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。

9.2.2 固定長メモリ・プールの削除

- del_mpf
パラメータmpfidで指定された固定長メモリ・プールを削除します。
対象固定長メモリ・プールでget_mpfまたはtget_mpfによって待っているタスクがある場合は,そのタスク待ち状態を解除し,get_mpfまたはtget_mpfの戻り値としてE_DLTを返します。
本サービス・コールは,信頼されたドメインに所属するタスクだけが呼び出せます。
以下に,本サービス・コールの記述例を示します。




 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 #pragma task Task1                      /*備考参照*/
 void Task1 ( VP_INT exinf );            /*備考参照*/
 void Task1 ( VP_INT exinf )
 {
         ID      mpfid = 8;              /*変数の宣言,初期化*/
 
         ............
         ............
 
         del_mpf( mpfid );               /*固定長メモリ・プールの削除*/
 }


備考 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。

9.2.3 固定長メモリ・ブロックの獲得

固定長メモリ・ブロックの獲得は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

RI600PXでは,固定長メモリ・ブロックを獲得する際,メモリ・クリア処理を行っていません。したがって,獲得された固定長メモリ・ブロックの内容は不定となります。

- get_mpf(待つ)

- pget_mpfipget_mpf(ポーリング)

- tget_mpf(タイムアウト付きで待つ)

- get_mpf(待つ)
パラメータmpfidで指定された固定長メモリ・プールから固定長メモリ・ブロックを獲得し,その先頭アドレスをパラメータp_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールから固定長メモリ・ブロックを獲得することができなかった(空き固定長メモリ・ブロックが存在しなかった)場合には,固定長メモリ・ブロックの獲得は行わず,自タスクを対象固定長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からWAITING状態(固定長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,固定長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。




 
固定長メモリ・ブロック獲得待ち状態の解除操作

戻り値

rel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。

E_OK

irel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。

E_OK

rel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

irel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

vrst_mpfの発行により,対象固定長メモリ・プールがリセットされた。

EV_RST

del_mpfの発行により,待ち状態を強制的に解除された。

E_DLT



以下に,本サービス・コールの記述例を示します。

 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 #pragma task Task1                      /*備考4参照*/
 void Task1 ( VP_INT exinf );            /*備考4参照*/
 void Task1 ( VP_INT exinf )
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mpfid = 1;              /*変数の宣言,初期化*/
         VP      p_blk;                  /*変数の宣言*/
 
         ............
         ............
 
                                         /*固定長メモリ・ブロックの獲得*/
         ercd = get_mpf ( mpfid, &p_blk );
 
         if ( ercd == E_OK ) {
                 ............            /*正常終了処理*/
                 ............
                                         /*固定長メモリ・ブロックの返却*/
                 rel_mpf ( mpfid, p_blk );
         } else if ( ercd == E_RLWAI ) {
                 ............            /*強制終了処理*/
                 ............
         }
 
         ............
         ............
 }


備考1 自タスクを対象固定長メモリ・プールの待ちキューにキューイングする際のキューイング方式は,固定長メモリ・プールの生成に指定した順(FIFO順または現在優先度順)に行われます。

備考2 獲得したメモリ・ブロックの内容は不定です。

備考3 メモリ・ブロックのアライメント数は1です。これより大きいアライメント数のメモリ・ブロックを獲得したい場合は,以下を守ってください。

- 固定長メモリ・プール生成時に指定するメモリ・ブロック・サイズを,目的のアライメン数の倍数とする。

- 固定長メモリ・プール領域の先頭アドレスを,目的のアライメント数のアドレスとする。

備考4 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。

- pget_mpfipget_mpf(ポーリング)
パラメータmpfidで指定された固定長メモリ・プールから固定長メモリ・ブロックを獲得し,その先頭アドレスをパラメータp_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールから固定長メモリ・ブロックを獲得することができなかった(空き固定長メモリ・ブロックが存在しなかった)場合には,固定長メモリ・ブロックの獲得は行わず,戻り値としてE_TMOUTを返します。
以下に,本サービス・コールの記述例を示します。




 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 #pragma task Task1                      /*備考3参照*/
 void Task1 ( VP_INT exinf );            /*備考3参照*/
 void Task1 ( VP_INT exinf )
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mpfid = 1;              /*変数の宣言,初期化*/
         VP      p_blk;                  /*変数の宣言*/
 
         ............
         ............
 
                                         /*固定長メモリ・ブロックの獲得*/
         ercd = pget_mpf ( mpfid, &p_blk );
 
         if ( ercd == E_OK ) {
                 ............            /*ポーリング成功処理*/
                 ............
 
                                         /*固定長メモリ・ブロックの返却*/
                 rel_mpf ( mpfid, p_blk );
         } else if ( ercd == E_TMOUT ) {
                 ............            /*ポーリング失敗処理*/
                 ............
         }
 
         ............
         ............
 }


備考1 獲得したメモリ・ブロックの内容は不定です。

備考2 メモリ・ブロックのアライメント数は1です。これより大きいアライメント数のメモリ・ブロックを獲得したい場合は,以下を守ってください。

- 固定長メモリ・プール生成時に指定するメモリ・ブロック・サイズを,目的のアライメン数の倍数とする。

- 固定長メモリ・プール領域の先頭アドレスを,目的のアライメント数のアドレスとする。

備考3 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。

- tget_mpf(タイムアウト付きで待つ)
パラメータmpfidで指定された固定長メモリ・プールから固定長メモリ・ブロックを獲得し,その先頭アドレスをパラメータp_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールから固定長メモリ・ブロックを獲得することができなかった(空き固定長メモリ・ブロックが存在しなかった)場合には,固定長メモリ・ブロックの獲得は行わず,自タスクを対象固定長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からタイムアウト付きのWAITING状態(固定長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,固定長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。




 
固定長メモリ・ブロック獲得待ち状態の解除操作

戻り値

rel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。

E_OK

irel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。

E_OK

rel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

irel_waiの発行により,待ち状態を強制的に解除された。

E_RLWAI

vrst_mpfの発行により,対象固定長メモリ・プールがリセットされた。

EV_RST

パラメータtmoutで指定された待ち時間が経過した。

E_TMOUT

del_mpfの発行により,待ち状態を強制的に解除された。

E_DLT



以下に,本サービス・コールの記述例を示します。

 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 #pragma task Task1                      /*備考5参照*/
 void Task1 ( VP_INT exinf );            /*備考5参照*/
 void Task1 ( VP_INT exinf )
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mpfid = 1;              /*変数の宣言,初期化*/
         VP      p_blk;                  /*変数の宣言*/
         TMO     tmout = 3600;           /*変数の宣言,初期化*/
 
         ............
         ............
 
                                         /*固定長メモリ・ブロックの獲得*/
         ercd = tget_mpf ( mpfid, &p_blk, tmout );
 
         if ( ercd == E_OK ) {
                 ............            /*正常終了処理*/
                 ............
 
                                         /*固定長メモリ・ブロックの返却*/
                 rel_mpf ( mpfid, p_blk );
         } else if ( ercd == E_RLWAI ) {
                 ............            /*強制終了処理*/
                 ............
         } else if ( ercd == E_TMOUT ) {
                 ............            /*タイムアウト処理*/
                 ............
         }
 
         ............
         ............
 }


備考1 自タスクを対象固定長メモリ・プールの待ちキューにキューイングする際のキューイング方式は,固定長メモリ・プール生成時に指定した順(FIFO順または現在優先度順)に行われます。

備考2 獲得したメモリ・ブロックの内容は不定です。

備考3 メモリ・ブロックのアライメント数は1です。これより大きいアライメント数のメモリ・ブロックを獲得したい場合は,以下を守ってください。

- 固定長メモリ・プール生成時に指定するメモリ・ブロック・サイズを,目的のアライメン数の倍数とする。

- 固定長メモリ・プール領域の先頭アドレスを,目的のアライメント数のアドレスとする。

備考4 待ち時間tmoutTMO_FEVRが指定された際には“get_mpfと同等の処理”を,TMO_POLが指定された際には“pget_mpfと同等の処理”を実行します。

備考5 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。

9.2.4 固定長メモリ・ブロックの返却

固定長メモリ・ブロックの返却は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- rel_mpfirel_mpf
パラメータmpfidで指定された固定長メモリ・プールにパラメータblkで指定された固定長メモリ・ブロックを返却します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールの待ちキューにタスクがキューイングされていた場合には,固定長メモリ・ブロックの返却は行わず,該当タスク(待ちキューの先頭タスク)に固定長メモリ・ブロックを渡します。これにより,該当タスクは,待ちキューから外れ,WAITING状態(固定長メモリ・ブロック獲得待ち状態)からREADY状態へ,またはWAITING-SUSPENDED状態からSUSPENDED状態へと遷移します。
以下に,本サービス・コールの記述例を示します。



 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 #pragma task Task1                      /*備考2参照*/
 void Task1 ( VP_INT exinf );            /*備考2参照*/
 void Task1 ( VP_INT exinf )
 {
         ER      ercd;                   /*変数の宣言*/
         ID      mpfid = 1;              /*変数の宣言,初期化*/
         VP      blk;                    /*変数の宣言*/
 
         ............
         ............
 
         ercd = get_mpf ( mpfid, &blk ); /*固定長メモリ・ブロックの獲得*/
 
         if ( ercd == E_OK ) {
                 ............            /*正常終了処理*/
                 ............
 
                 rel_mpf ( mpfid, blk ); /*固定長メモリ・ブロックの返却*/
         } else if ( ercd == E_RLWAI ) {
                 ............            /*強制終了処理*/
                 ............
         }
 
         ............
         ............
 }


備考 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。

9.2.5 固定長メモリ・プール詳細情報の参照

固定長メモリ・プール詳細情報の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- ref_mpfiref_mpf
パラメータmpfidで指定された固定長メモリ・プールの固定長メモリ・プール詳細情報(待ちタスクの有無,空き固定長メモリ・ブロックの総数など)をパラメータpk_rmpfで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。


 #include        "kernel.h"              /*標準ヘッダ・ファイルの定義*/
 #include        "kernel_id.h"           /*cfg600pxが出力するヘッダ・ファイルの定義*/
 #pragma task Task1                      /*備考2参照*/
 void Task1 ( VP_INT exinf );            /*備考2参照*/
 void Task1 ( VP_INT exinf )
 {
         ID      mpfid = 1;              /*変数の宣言,初期化*/
         T_RMPF  pk_rmpf;                /*データ構造体の宣言*/
         ID      wtskid;                 /*変数の宣言*/
         UINT    fblkcnt;                /*変数の宣言*/
 
         ............
         ............
 
         ref_mpf ( mpfid, &pk_rmpf );    /*固定長メモリ・プール詳細情報の参照*/
 
         wtskid = pk_rmpf.wtskid;        /*待ちタスクの有無の獲得*/
         fblkcnt = pk_rmpf.fblkcnt;      /*空き固定長メモリ・ブロックの総数の獲得*/
 
         ............
         ............
 }


備考1 固定長メモリ・プール詳細情報T_RMPFについての詳細は,「【 固定長メモリ・プール詳細情報T_RMPFの構造 】」を参照してください。

備考2 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。