2009-04-30 3 views
2

私は複数の(> 20)タスクが異なる優先順位で実行されている組み込みシステムを持っています。私はまた、他のすべてのタスクが滞っていないことを確認するために実行されるウォッチドッグタスクを持っています。私のウォッチドッグは働いています。なぜならブルームーンに入るたびに、タスクがチェックインしなかったためシステムをリブートするからです。どのタスクが死んでいるかを調べる方法は?

どのタスクが亡くなったのかをどのように判断できますか?

降伏していないより高い優先度のタスクによって保留されている可能性があるため、ウォッチドッグを蹴る最も古いタスクを責めるだけではありません。

提案がありますか?

答えて

2

ごとのタスクウォッチドッグは、すべてのウォッチドッグを蹴ることができるように優先度の高いタスクが十分な時間を得ていることが必要です。どのタスクが間違っているかを判断するには、他のタスクが飢えているタスクを見つけなければなりません。実際の原因を特定するためにウォッチドッグチェック間のタスク実行時間を測定する必要があります。

1

これは先制ですか?もしそうでなければ、ウォッチドッグ・タスクは実行されないので、私はそちらに集まります。

OSについては言及しませんが、ウォッチドッグタスクが1つのタスクがチェックインしていないかどうかを確認できる場合は、タスクとウォッチドッグの間に個別の通信チャネルが必要です。

にチェックインしていないタスク番号を何らかの形でダンプするように、タスクコントロールブロックとメモリをダンプするように、ウォッチドッグを変更する必要があります。

OSによっては、これは簡単で難しい場合もあります。

0

システムおよびOSによっては、さまざまな方法があります。私が使用した非常に低いレベルのアプローチの1つは、各タスクが実行されているときにLEDを点滅させることです。非常に高速なタスク切り替えを確認するには、LEDにスコープを配置する必要があります。

0

割り込み駆動型ウォッチドッグでは、タスクスイッチャーが変更されるたびに現在実行中のタスク番号を更新するだけで、どちらが失敗したのかを識別することができます。

しかし、あなたはあなた自身がタスクとしてウォッチドッグを書きましたので、リブートする前に必ずウォッチドッグが飢えたタスクを特定できるとお考えですか?これをメモリに保存することで、ウォームリブートを超えて継続することも、デバッグインタフェースを介して送信することもできます。この問題は、飢えたタスクがおそらく問題ではないということです。おそらく、原因を特定するために最後のいくつかのタスクスイッチ(および時間)を知りたいと思うでしょう。

0

単純化し、バックナプキンのアプローチのこのようなものになるだろう:

int8_t wd_tickle[NUM_TASKS] 

void taskA_main() 
{ 
    ... 
    // main loop 
    while(1) { 
    ... 
    wd_tickle[TASKA_NUM]++; 
    } 
} 

... tasks B, C, D... follow similar pattern 

void watchdog_task() 
{ 
    for(int i= 0; i < NUM_TASKS; i++) { 
    if(0 == wd_tickle[i]) { 
     // Egads! The task didn't kick us! Reset and record the task number 
    } 
    } 
} 
+0

問題は、BはAよりも優先度が高いことです.Bはロックされていますが、Aはウォッチドッグをキックしません。 AはBのロックアップのせいになる。 – Robert

2

私はウォッチドッグリセットの問題で最後の数週間働いていました。しかし、幸い私のためには、ARM開発環境のramdumpファイルには、各割り込み時にPCとSLRを含む割り込みハンドラトレースバッファが1つあります。したがって、トレースバッファからは、WDリセット前にコードのどの部分が実行されているかを正確に知ることができました。

あなたは、割り込みごとにPC、SLRを格納するメカニズムが同じであれば、犯人タスクを正確に見つけることができると思います。

0

システムはどのように正確に動作していますか?私は常にソフトウェアとハ​​ードウェアウォッチドッグの組み合わせを使用します。私に説明させてください...

私の例では、プリエンプティブリアルタイムカーネルを使用しており、CPU /マイクロコントローラでウォッチドッグサポートを行っていることを前提としています。このウォッチドッグは一定の時間内に蹴られなかった場合にリセットを行います。

1)定期システムタイマー(「RTOS時計」)が動作しています(「スリープ」などの機能が動作しなくなり、システムが使用できなくなる)。

2)すべてのスレッドは、妥当な期間実行できます。

私のRTOS(www.ieton.be/micror2k)は、RTOSクロック割り込みハンドラでコードを実行する可能性を提供します。これはハードウェアウォッチドッグをリフレッシュする唯一の場所なので、クロックが常に実行されていることを確認します(ウォッチドッグがシステムをリセットしない場合)。

(常に優先度が最も低い)アイドル状態のスレッドでは、「ソフトウェアウォッチドッグ」がリフレッシュされます。これは、単に変数を特定の値(たとえば1000)に設定することです。 RTOSクロック割り込み(ハードウェアウォッチドッグをキックする場所)では、この値を減らしてチェックします。値が0になると、アイドルスレッドが1000クロックティックで実行されておらず、システムを再起動したことを意味します(ハードウェアのウォッチドッグを再起動させるために割り込みハンドラ内で無期限にループすることによって可能です)。

元の質問については、私はシステム時計が稼働し続けていると仮定しているので、システムをリセットするのはソフトウェアウォッチドッグです。 RTOSクロック割り込みハンドラでは、ソフトウェアウォッチドッグの状況が発生した場合に備えて、「統計収集」を行うことができます。システムをリセットする代わりに、問題が発生した後に各クロックティックでどのスレッドが実行されているのかを確認し、何が起きているのかを調べることができます。それは理想的ではありませんが、それは助けになります。

もう1つの方法は、複数のソフトウェアウォッチドッグを異なる優先度で追加することです。アイドルスレッドがVariableAを1000に設定し、(専用の)中優先スレッドに変数Bを設定させます。RTOSクロック割り込みハンドラでは、両方の変数をチェックします。この情報を使用すると、ループしているスレッドの優先度が「中」または「中」より高いかどうかを知ることができます。あなたが望むなら、あなたが好きな3番目または4番目のソフトウェアウォッチドッグを追加することができます。最悪の場合は、使用されている優先度ごとにソフトウェアウォッチドッグを追加します(ただし、余分なスレッドが必要になります)。

関連する問題