プロが教えるわが家の防犯対策術!

今、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のタスクが動き始めて、というのを繰り返すものと考えているのですが、そのように考えてよいのでしょうか?



#defineTASK_SW_ID 5
#defineTASK_OSC_ID 6
#defineTASK_OSC02_ID 7


#defineTASK_SW_PRIORITY 30
#defineTASK_OSC_PRIORITY 31
#defineTASK_OSC02_PRIORITY 32


#defineTASK_OSC_STK_SIZE 0x200
#defineTASK_OSC02_STK_SIZE 0x200
#defineTASK_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);


}
}

A 回答 (2件)

タイムアウトが発生したならば、おそらくセマフォの取得に失敗しています。



取得していないセマフォの開放はできないので多分エラーになるでしょう。
Osc,Osc02については他の原因でセマフォが開放するまで待たされるでしょう。

もし取得できていないセマフォが開放できたとするとプログラムの動作は予期しない動作になるでしょう。
    • good
    • 0
この回答へのお礼

回答頂きありがとうございました。

マイコンでのOSの使い方についてまだまだわからない点があり、大変助かります。セマフォの理解ももっと必要だなと痛感しております。

お礼日時:2010/03/09 18:26

なにか参考のサンプルでも見て書かれたほうがいいと思います。


かなり間違っています。
それぞれのタスクでセマフォ生成を行っていますよね。
それを共通変数にハンドルをコピーしてしまっています。
セマフォ生成は、まず最初のタスクだけで生成しなければ、タスク同期通信
が正常に動作しないですね。
ですので、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がセマフォを獲得

になるでしょう。
    • good
    • 0
この回答へのお礼

回答頂きありがとうございます。助かります。

まだまだ、OSの動作の理解が乏しく、ちぐはぐな質問になってしまい大変申し訳ありません。

”OscWait = OSSemCreate(0);”という使い方は複数回使ってワイケないということなんですね。また、どのように動かしたいかということもちゃんと決めておかなければタスクの状態というのを把握するのが困難なんだということもわかった気がします。

教えて頂いた”状態”というのをイメージすればとても効率が上がりそうだなと思いました。

お礼日時:2010/03/09 18:32

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!