(toppers-users 2959) メールボックスに使用するメッセージのメモリ確保について

Tatsuya SHIMIZU shimizu_t @ totani.co.jp
2009年 6月 5日 (金) 13:31:40 JST


お世話になります。
清水と申します。

メッセージボックスの使い方について,基本的なことなのかも知れませんが質問させて頂きます(ITRONはまだまだ使いだして日が浅く初心者です)。

下記のようなコードを書きましたが,一見は正常に動いているのですが不具合があります。

//メッセージ構造体の宣言
typedef struct _MESSAGE
{
 T_MSG pk_msg;
 UW size;
 ID tid;

 UH x;
 UH y;
} MESSAGE;

//メッセージの定義
MESSAGE msg;

//メッセージ送信側のタスク
void task1(VP_INT exinf)
{
   --変数定義等は省略--

   msg.x   = x; //送信データを入れる
   msg.y   = y;
   msg.tid = TSKID_TASK1;

   snd_mbx(MID_MSG, (T_MSG*)&msg); //メッセージの送信
   slp_tsk(); //同期を取る
}

//メッセージ受信側のタスク
void task2(VP_INT exinf)
{
    --変数定義等は省略--

    for( ; ; )
    {
        rcv_mbx(MID_MSG, (T_MSG **)&msg);
        x = msg.x;
        y = msg.y;

        wup_tsk(msg.tid);
    }
}

上記はユーザーからの入力を受けて割り込みハンドラが起動され,割り込みハンドラからtask1が呼ばれるというアプリケーションです。
rcv_mbxで受信しているのでメッセージが送信された時だけrcv_mbxを通過すると認識しています。

 実際に通常は思った通りに動作しているのですが,素早く連続して入力をするとその後入力していないのにも関わらずrcv_mbxを通過してtask2のずっとfor文でループしているようです。

 上のコードはmsgをグローバル変数として定義していました。
これをタスク内で定義するとループするといった不具合がなくなりました。

 そこで,私のメモリに対する認識は次のようなのですが,間違っていますでしょうか?

・各タスクはコンフィギュレーションファイルで設定した大きさのスタック領域は確実に使える,それ以外の空いている部分にグローバル変数や動的にメモリを確保するメモリプール等が配置される。

・メモリプール等は 動的に配置できるのに加えて,OSが管理している領域であることが単なるグローバル変数と違うところである。


過去のメーリングリストでは,以下のようなことが書いてありました。
・for文などの中でsnd_mbxを使うと,リンクリストが破綻するので使ってはならない。(まだ,具体的にどうなるのか理解できていませんが…)

・メッセージはメッセージは固定長メモリプールなどに置く。
 タスクのスタック領域に置くのは危険。(これも理由があまり理解できていないのですが…)
→動的にメモリを確保するより,静的にメモリを確保した方が安全かなと考えたのですが。


長々となってしまいましたが,結局のところ,グローバル変数でmsgを定義していた場合にはなぜ不具合がおきたのかその原因が知りたいとい考えております。

以上,何かアドバイス等があれば,よろしくお願い致します。