- ベストアンサー
RTOSのセマフォの使い方についての疑問
今、H8S2368というマイコンを使って、RTOSのuCOSについて勉強しているところなのですが、RTOSがどのように動いているのかというのをイメージすることができなくて質問させていただきます。 たとえば、3つのタスクを宣言して、Swというタスクで、OscWaitというセマフォを使って、”OSSemPend(OscWait, 500, &err);”の500ミリ秒でタイムアウトが発生して、”OSSemPost(OscWait);”でセマフォを解除して、OscWaitで止まっていたOsc,Osc02のタスクを動かした場合、この場合、どのようにタスク内のプログラムは動きだすのでしょうか。 たぶんなのですが、Oscのタスクの方がプライオリティが高いので、こちらがまず動いて、while文で再度”OSSemPend(OscWait, 100, &err);”でOscWaitの信号が赤になって止まって、それから、Osc02のタスクが動き始めて、というのを繰り返すものと考えているのですが、そのように考えてよいのでしょうか? #define TASK_SW_ID 5 #define TASK_OSC_ID 6 #define TASK_OSC02_ID 7 #define TASK_SW_PRIORITY 30 #define TASK_OSC_PRIORITY 31 #define TASK_OSC02_PRIORITY 32 #define TASK_OSC_STK_SIZE 0x200 #define TASK_OSC02_STK_SIZE 0x200 #define TASK_SW_STK_SIZE 0x200 DECLARE_TASK(Sw,TASK_SW_STK_SIZE,TASK_SW_ID); DECLARE_TASK(Osc,TASK_OSC_STK_SIZE,TASK_OSC_ID); DECLARE_TASK(Osc02,TASK_OSC02_STK_SIZE,TASK_OSC02_ID); CAEATE_TASK(Sw ,TASK_SW_STK_SIZE ,TASK_SW_PRIORITY,0x00/*OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR*/); CAEATE_TASK(Osc ,TASK_OSC_STK_SIZE ,TASK_OSC_PRIORITY,0x00/*OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR*/); CAEATE_TASK(Osc02 ,TASK_OSC02_STK_SIZE ,TASK_OSC02_PRIORITY,0x00/*OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR*/); OS_EVENT *OscWaitt; DECLARE_TASK_FUNC(Sw) { BYTE err; OscWait = OSSemCreate(0); parg = parg; while(1) { OSSemPend(OscWait, 500, &err); OSSemPost(OscWait); } } DECLARE_TASK_FUNC(Osc) { BYTE err; OscWait = OSSemCreate(0); parg = parg; while(1) { OSSemPend(OscWait, 100, &err); if(err != 0){ continue; } OSC_temp++; printf("OSC_temp %d \n\r",OSC_temp); } } DECLARE_TASK_FUNC(Osc02) { u16 cur,old; u8 OSC_temp02=0; BYTE err; OscWait = OSSemCreate(0); parg = parg; while(1) { OSSemPend(OscWait, 100, &err); if(err != 0){ continue; } OSC_temp02++; printf("OSC_temp02 %d \n\r",OSC_temp02); } }
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
なにか参考のサンプルでも見て書かれたほうがいいと思います。 かなり間違っています。 それぞれのタスクでセマフォ生成を行っていますよね。 それを共通変数にハンドルをコピーしてしまっています。 セマフォ生成は、まず最初のタスクだけで生成しなければ、タスク同期通信 が正常に動作しないですね。 ですので、OSC と OSC2でのセマフォ生成の部分を削除する必要があります。 そのような修正をした場合でも、100msタイムアウトと500msタイムアウトが微妙 で不定な動作、つまりマイコンの性能によって結果の異なるような動きになります。 OSCおよびOSC2がどのような状態にあるかによって動作が違うからです。 状態1 OSC OSC2 両方セマフォ待ちのとき 状態2 OSC OSC2 両方レディのとき 状態3 OSC がセマフォ待ちでOSC2がレディのとき 状態4 OSC がレディでOSC2がセマフォ待ちのとき 4つの状態が考えられるからです。 OSCとOSC2の動きを考えるとまずSWがセマフォ待ち500ms待ちに入ったときに OSCが実行状態になり、間もなく100ms待ちになります。次にOSC2が実行状態になり 間もなく100ms待ちになります。OSCが100msタイムアウトになりまた待ちになります。 ただし、そこでprintfが入るため、その間にOSC2がタイムアウトになり、レディ状態に なっていますが、ここはprintfの実装によりますが、ポーリングで印字しているなら printfがおわりOSCが終わるまでOSC2はレディ状態のままです。結構msオーダーで時間が かかります。時間軸を考えた場合にOSC OSC2がこの繰り返しをしている間にSWが500msの タイムアウトになり、セマフォをポストします。そのときにOSCとOSC2はどの状態になって いるかは、上記4つの状態ではあるがどの状態かはさだかでありません。 そのとき 状態1なら これはセマフォの仕様によります。 優先度待ち仕様(ITRONで言うTA_TPRI)の場合は、OSCですが、 FIFO待ち仕様の場合は、通常OSCが先に待ち状態になることが多いですが、 OSCが待ちになってからOSC2がタイムアップする場合がある場合は逆の場合も ありえます。 状態2なら 優先度の高いOSCが先にセマフォ待ちをしようとするので、セマフォで待とうとして も、待たずに返ってくる(獲得できる)かと思います。 状態3なら OSCがセマフォを獲得 状態4なら OSC2がセマフォを獲得 になるでしょう。
その他の回答 (1)
- tadys
- ベストアンサー率40% (856/2135)
タイムアウトが発生したならば、おそらくセマフォの取得に失敗しています。 取得していないセマフォの開放はできないので多分エラーになるでしょう。 Osc,Osc02については他の原因でセマフォが開放するまで待たされるでしょう。 もし取得できていないセマフォが開放できたとするとプログラムの動作は予期しない動作になるでしょう。
お礼
回答頂きありがとうございました。 マイコンでのOSの使い方についてまだまだわからない点があり、大変助かります。セマフォの理解ももっと必要だなと痛感しております。
お礼
回答頂きありがとうございます。助かります。 まだまだ、OSの動作の理解が乏しく、ちぐはぐな質問になってしまい大変申し訳ありません。 ”OscWait = OSSemCreate(0);”という使い方は複数回使ってワイケないということなんですね。また、どのように動かしたいかということもちゃんと決めておかなければタスクの状態というのを把握するのが困難なんだということもわかった気がします。 教えて頂いた”状態”というのをイメージすればとても効率が上がりそうだなと思いました。