質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

Q&A

3回答

5917閲覧

【組込み】【iTRON】メッセージ送信について

G.S.

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

0グッド

0クリップ

投稿2016/03/06 15:57

編集2016/03/07 10:30

注:実機が無いので
金澤ソフト設計様のWindows版iTRONを使用しています。


【質問1】
タスクコンテキストとは
タスク、及びタスクから呼び出される関数

非タスクコンテキストとは
上記以外の、タスク処理とは完全に独立している処理

という考え方でよろしいでしょうか?

【質問2】
iTRONのメールボックスについて

以下のパターン1、2、3の考え方に間違いがありませんでしょうか?


・メッセージを格納するポインタは静的変数(static宣言)にするのが無難である。

メッセージを格納するポインタが自動変数のとき

  • (パターン1)

タスクを定義している箇所から直接送信する場合、
そのタスクが休止状態になると、メッセージポインタがメモリから削除されるため、
他所での受信処理ができなくなる。

C

1TASK tsk_mbx1_send_test( VP_INT stacd ) 2{ 3 //メッセージ送信後、タスクが終了して休止状態になる場合 4 //送信メッセージポインタがメモリから削除される 5 T_MSGEX mbx_msgex; 6/**** 中 略 *****/ 7 result = snd_msg(MBX1_NO,(T_MSG *)&mbx_msgex); 8}
  • (パターン2)

上記の場合でも、そのタスクが休止状態にならない場合、
メッセージポインタがメモリに保持されるため、他所での受信処理が可能になる。

C

1TASK tsk_mbx1_send_test( VP_INT stacd ) 2{ 3 //メッセージ送信後も、タスクが終了しない場合、 4 //送信メッセージポインタはメモリに保持される 5 6 T_MSGEX mbx_msgex; 7 8 while(TRUE) //無限ループ 9 { 10/**** 中 略 *****/ 11 result = snd_msg(MBX1_NO,(T_MSG *)&mbx_msgex); 12 } 13}
  • (パターン3)

タスクから別の関数を介してメッセージ送信する場合、
呼び出し元のタスクが休止状態にならない場合であっても、
関数が終了した時点でメッセージポインタがメモリから削除されてしまい、
他所での受信処理ができなくなる。

C

1TASK tsk_mbx1_send_test( VP_INT stacd ) 2{ 3 while(TRUE) //無限ループ 4 { 5/**** 中 略 *****/ 6 result = f_mbx1_send_test(); //メッセージ送信を別関数化 7 } 8} 9 10static ER f_mbx1_send_test(void) 11{ 12 //関数の実行終了とともに送信メッセージポインタが 13 //メモリから削除されてしまう 14 T_MSGEX mbx_msgex; 15/**** 中 略 *****/ 16 result = snd_msg(MBX1_NO,(T_MSG *)&mbx_msgex); 17}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

T.Kanno

2016/03/07 00:24

いくつもの質問を一度に行うと、回答しにくいです。
guest

回答3

0

こんにちは。

ITRON、昔触ったことが有ります。ちょっと懐かしい。

タスクコンテキストとは
タスク、及びタスクから呼び出される関数

概ねその通りです。追加でタスク例外処理ルーチンもタスクのコンテキストで実行されるようです。

非タスクコンテキストとは
上記以外の、タスク処理とは完全に独立している処理

メモリ空間を全システムで共有しているので「完全に独立している」わけではないです。
非タスクコンテキストはタスクとは異なるスタックで動作しているルーチンです。他の処理とスタックを共有しているので、待ちを行ってスタックを握ったままにすると他の処理を実行できなくなりますので、待ちは禁止されています。
典型的には割り込みハンドラーですね。他の全ての処理に優先して実行されるので、その中で「待ち」をやるとか「あり得ない」話です。割り込みハンドラーで100mSecとか費やしたら、他の優先順位の低い割り込み応答がそれだけ待たされますから許されません。かなり特殊な「実行」状態なのです。

以下のパターン1、2、3の考え方に間違いがありませんでしょうか?

間違いないと思います。

・メッセージを格納するポインタは静的変数(static宣言)にするのが無難である。

その通りと思います。
次のメッセージをそのメモリに書き始める前に、前のメッセージが受信され、かつ、そのメモリを受信側タスクがもうアクセスしないことを確実にする仕組みを設ける必要がありますが、uITRON的にはこの方向性が妥当だろうと思います。

他にはmalloc等で確保したメモリを使って送信し、受信側で処理が終わったら解放することが考えられます。しかし、メモリが潤沢にあるわけでないシステムでやるにはメモリの使用効率が悪くなりすぎると思います。
メモリの獲得/解放はメモリをどの程度使うのか事前に設計し辛い時に行いますね。皆が一斉にメモリ獲得すると直ぐにメモリ不足になるような小さなシステムでどうやってメモリ不足に備えるのか? 対策は悪夢になりそうです。

投稿2016/03/07 01:27

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

G.S.

2016/03/07 14:09

丁寧な解説ありがとうございます。 実務経験がおありのようで、大変参考になります。
guest

0

質問1
質問者の考えでほぼ間違いありません。
「タスクのコンテキストで動くかどうか」です。割り込みや各種のハンドラは
タスクとは別のコンテキストなので「非タスク部」です。

質問2
質問者の考えでほぼ問題ありません。
「(ポインタではなく)メッセージの実体は送信側、受信側どちらからでもいつでも見られるメモリーに置け」
ということです。
そういうことですので、メッセージの実体はローカル変数ではなく、外部の静的変数や
動的に確保したメモリとする場合が多いです。

既にお持ちかもしれませんが、μITRONの仕様書はトロン協会や名古屋大学の高田研究室などから
無料で手に入りますので、手元に置いておくといいでしょう。
また、μITRON(特にVer3)は実装依存の項目が多いので、OSメーカーの仕様にも
目を通して下さい。

投稿2016/03/07 01:02

nob.

総合スコア711

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

G.S.

2016/03/07 14:10

ありがとうございます。 実務から離れていることもあり、再勉強中です。
guest

0

質問1

コンテキストの切り分けはおおむねOKと思います。
非タスクコンテキストは、通常は割り込みハンドラなどになると思います。
おおむね、どこのスタックで動いているかで切り分けられると思います。
各タスクのスタックを使用=タスクコンテキスト。
タスク以外のスタックを使用=非タスクコンテキスト。
一般に、非タスクコンテキストはタスクではないので待ち状態に入れない
ため、そのようなAPIは呼べないですよね。

質問2

どうなるかという結果についてはあっていると思いますが、理由が少し違うと思います。

まず、メッセージを割り当てる記憶域とタスクの状態は無関係です。
さらに、問題なのはメッセージの本体が、関数の戻り(=スタックフレームの解放)で破壊されてしまう事だと思います。
APIの呼び出し時に渡されたメッセージへのポインタは、API内部でコピーされるはずですので、ポインタの記憶域による制約はないと思いますよ。

>・メッセージを格納するポインタは静的変数(static宣言)にするのが無難である。

特に何のメリットもないと思います。問題は、ポインタではなくメッセージの本体が保持されるかどうかです。

~~
>・メッセージを格納するポインタは静的変数(static宣言)にするのが無難である。

上記を、「メッセージを格納する領域は…」と読み替えて捕捉します。

おそらく、1つのメッセージの処理が終了するまで次が動かないような、競合の発生可能性のないシステムなら static でOKで、それがシンプルで合理的な方法と思いますが、次が動いてしまったりする競合の発生する応用の場合には、素直にメモリを確保する方がバッファ管理や競合回避を考えるとよいかもしれません。

投稿2016/03/07 00:43

編集2016/03/07 02:03
T.Kanno

総合スコア915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Chironian

2016/03/07 01:31

タスクの休止状態って、そのメインルーチンからreturnした状態なのですよ。 名前的にはなんとなく、まだタクスが「生きて」いそうな名前なのですけどね。
T.Kanno

2016/03/07 01:51

タスク関数からの return で休止になるということですかね? それなりのガードはかけられていそうですが、なんとも怪しげな不安が付きまといますね。 とりあえず、休止で解放や破壊になるわけでは無く、スタックフレームの解放に起因するというお話でした。
Chironian

2016/03/07 02:46

uITRONのタスクの休止≒一般的なスレッドの終了です。 スタックフレームも解放されるのですよ。 ですので、G.S.さんが問うているタスクの休止に関しては例外的に「メッセージを割り当てる記憶域」に影響するのです。
nob.

2016/03/07 12:44

パターン1ですが、タスクの外へリターンしています。こういう場合、どう振る舞うか、規定はなかったように思います。 大抵の実装では、暴走するのではないでしょうか。
G.S.

2016/03/07 14:01 編集

皆様コメントありがとうございます。 メッセージの実体部分をメモリプールから確保すると、メッセージ自体は送受信できるようですが そのメッセージの優先順位を格納する変数の中身が化けてしまうようです。 やはりstatic宣言すべきかと思いました。
nob.

2016/03/07 14:34

Chironianさん。 確認できました。 ver4で規定されたんですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問