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

高橋和浩 takahashi_kazuhiro @ nifty.com
2009年 6月 5日 (金) 15:01:54 JST


いつもMLを拝見させていただいています。
アライブビジョンソフトウエアの高橋です。

TOPPERS固有の問題ではなく、ITRONのQ&Aですね。

貴殿が見たメーリングリストの問題について仕組みが
理解できれば、すぐにお解りになると思います。

理由は、端的に言うとT_MSGは、カーネル内で頭のポインタを
使ってリンクリストとして使っているからです。

ですから、メールボックスをsndしてからrcvするまで
そこを書いてはならないのです。

グローバル変数で動きがおかしくなったのは、そこを直接
書き換えているからのように思います。
        rcv_mbx(MID_MSG, (T_MSG **)&msg);

カーネル実装方法によって、発生する場合としない場合がありますが、
TOPPERS/JSPの場合に以下のようにリストからの取り外しと
出力をしているため無限に取り出せるようになるようです。
mailbox.c
rcv_mbxの一部
if (mbxcb->head != NULL) {
	*ppk_msg = mbxcb->head; 		//ここでmsgにmsg自身のアドレスの上書きがされる
	mbxcb->head = (*ppk_msg)->next;		//ダブルポインタの先は通常NULLのはずが
						//アドレス上書きのためmsgのアドレスとなる
						//結局 mbxcb->headは書き換わらない。
						//なので無限にrcv_mbxできる
	ercd = E_OK;
}
正常に動作する場合は、
動作がゆっくりの時で、task2が一旦待ちに入ってからsnd_mbx()によって解除される場合
ですね。この場合にカーネル内でリンクリストが作られないため誤動作もしなくなります。
上記リストの部分は処理されません。


>グローバル変数でmsgを定義していた場合にはなぜ不具合がおきたのかその原因が知りたいとい
>考えております。
メールボックスは、カーネルがユーザーからもらったデータを元にして処理をします。
ところが、貴殿のプログラムはrcv時にそのエリアに直接書き込んでいます。
それが問題なのです。 また、繰り返しメッセージを送る場合に、同じ変数は使えません。
もうすでにカーネルに渡してしまっているからです。
for文でまわす場合に以下のような、配列で10個を送るのはいいのですが
--------
typedef struct {
	T_MSG	msg;
	UW	user_data;
} UserMSG;

UserMSG g_userMsg[10];
----------
ひとつの変数を10回使いまわすとダメだということです。

また、高信頼性カーネルというのでしょうか、優先度データキューというサービスコールが
追加され、メールボックスは上記のような問題からあまり推奨されなくなっているようです。

基本的に受信時のポインタ操作が間違っていますが、それを直した上でデータキューに
書き直したらいいいかと思います。

-- 
アライブビジョンソフトウエア株式会社
高橋和浩
673-0031兵庫県明石市小久保2-2-7幹線ビル4F
Email:takahashi_kazuhiro @ nifty.com
http://homepage3.nifty.com/ALVS/