9.2 固定長メモリ・プール
RI600PXでは,処理プログラムから動的なメモリ操作要求が行われた際に利用するメモリ領域として“固定長メモリ・プール”を提供しています。
なお,固定長メモリ・プールに対する動的なメモリ操作は,固定サイズの固定長メモリ・ブロックを単位として行われます。
固定長メモリ・プールは,以下のいずれかの方法で生成します。
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に出力するため,記述不要です。
#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に出力するため,記述不要です。
固定長メモリ・ブロックの獲得は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
RI600PXでは,固定長メモリ・ブロックを獲得する際,メモリ・クリア処理を行っていません。したがって,獲得された固定長メモリ・ブロックの内容は不定となります。
-
get_mpf(待つ)
パラメータ
mpfidで指定された固定長メモリ・プールから固定長メモリ・ブロックを獲得し,その先頭アドレスをパラメータ
p_blkで指定された領域に格納します。
ただし,本サービス・コールを発行した際,対象固定長メモリ・プールから固定長メモリ・ブロックを獲得することができなかった(空き固定長メモリ・ブロックが存在しなかった)場合には,固定長メモリ・ブロックの獲得は行わず,自タスクを対象固定長メモリ・プールの待ちキューにキューイングしたのち,RUNNING状態からWAITING状態(固定長メモリ・ブロック獲得待ち状態)へと遷移させます。
なお,固定長メモリ・ブロック獲得待ち状態の解除は,以下の場合に行われます。
|
|
rel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。
|
|
irel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。
|
|
|
|
|
|
|
|
|
|
#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_mpf,
ipget_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の発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。
|
|
irel_mpfの発行により,対象固定長メモリ・プールに固定長メモリ・ブロックが返却された。
|
|
|
|
|
|
|
|
パラメータ tmoutで指定された待ち時間が経過した。
|
|
|
|
#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です。これより大きいアライメント数のメモリ・ブロックを獲得したい場合は,以下を守ってください。
- 固定長メモリ・プール生成時に指定するメモリ・ブロック・サイズを,目的のアライメン数の倍数とする。
- 固定長メモリ・プール領域の先頭アドレスを,目的のアライメント数のアドレスとする。
備考5 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。
固定長メモリ・ブロックの返却は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
rel_mpf,
irel_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に出力するため,記述不要です。
固定長メモリ・プール詳細情報の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。
-
ref_mpf,
iref_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; /*空き固定長メモリ・ブロックの総数の獲得*/
............
............
}
|
備考2 システム・コンフィギュレーション・ファイルで生成したタスクについては,これらのステートメントはcfg600pxがkernel_id.hに出力するため,記述不要です。