どのタスクが無効になっているかを判断するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/807017

  •  03-07-2019
  •  | 
  •  

質問

異なる優先度で複数 (20 以上) のタスクが実行されている組み込みシステムがあります。他のすべてのタスクが停止していないかどうかを確認するために実行されるウォッチドッグ タスクもあります。私のウォッチドッグは、タスクがチェックインされなかったためにシステムを再起動するので、機能しています。

どのタスクが終了したかを確認するにはどうすればよいですか?

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

助言がありますか?

役に立ちましたか?

解決

タスクごとのウォッチドッグでは、すべてのタスクがウォッチドッグをキックできるように、優先度の高いタスクが適切な時間の間譲歩する必要があります。どのタスクに問題があるかを判断するには、他のタスクを枯渇させているタスクを見つける必要があります。実際の原因を特定するには、ウォッチドッグ チェック間のタスク実行時間を測定する必要があります。

他のヒント

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

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

これは先制ですか?そうしないと、他の1つがスタックした場合にウォッチドッグタスクが実行されないためです。

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

おそらく、ウォッチドッグを変更して、チェックインしていないタスクのタスク番号をダンプし、 タスク制御ブロックとメモリをダンプして、事後分析を行う必要があります。 。

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

システムとOSに応じて、異なるアプローチがあります。私が使用した非常に低レベルのアプローチの1つは、各タスクの実行中にLEDを点滅させることです。非常に高速なタスクの切り替えを確認するには、LEDにスコープを設定する必要があります。

割り込み駆動型ウォッチドッグの場合、タスクスイッチャーを変更するたびに現在実行中のタスク番号を更新するだけで、どのタスクが生成されなかったかを特定できます。

ただし、ウォッチドッグを自分でタスクとして作成することをお勧めします。したがって、再起動する前に、ウォッチドッグは確実に飢star状態のタスクを識別できますか?ウォームリブート後も保持されるメモリにこれを保存するか、デバッグインターフェイスを介して送信できます。これに関する問題は、飢えたタスクはおそらく問題のあるタスクではないということです。原因を特定するために、おそらく最後のいくつかのタスクスイッチ(および時間)を知りたいでしょう。

ナプキンアプローチの単純なバックは、次のようなものになります。

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
     }
    }
}

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

この例では、プリエンプティブ リアルタイム カーネルを使用しており、CPU/マイクロコントローラーにウォッチドッグ サポートがあることを前提としています。このウォッチドッグは、一定期間内に起動されなかった場合にリセットを実行します。次の 2 つのことを確認してください。

1) 定期的なシステム タイマー (「RTOS クロック」) が実行されています (そうでないと、「スリープ」などの機能が動作しなくなり、システムが使用できなくなります)。

2) すべてのスレッドは、適切な期間内に実行できます。

私の RTOS (www.lieron.be/micror2k) では、RTOS クロック割り込みハンドラーでコードを実行することができます。ここはハードウェア ウォッチドッグを更新する唯一の場所であるため、クロックが常に動作していることがわかります (そうでない場合、ウォッチドッグがシステムをリセットします)。

アイドル スレッド (常に最低の優先順位で実行されている) では、「ソフトウェア ウォッチドッグ」が更新されます。これは単に変数を特定の値に設定するだけです (例:1000)。RTOS クロック割り込み (ハードウェア ウォッチドッグを起動する) では、この値をデクリメントして確認します。0 に達した場合は、アイドル スレッドが 1000 クロック ティックの間実行されていないことを意味し、システムを再起動します (これは、割り込みハンドラー内で無限にループしてハードウェア ウォッチドッグを再起動させることで実行できます)。

さて、元の質問です。システムクロックは動作し続けると思いますので、システムをリセットするのはソフトウェアウォッチドッグです。RTOS クロック割り込みハンドラーでは、ソフトウェア ウォッチドッグ状況が発生した場合に備えて「統計収集」を行うことができます。システムをリセットする代わりに、(問題が発生した後) クロック刻みごとにどのスレッドが実行されているかを確認し、何が起こっているかを調べてみることができます。理想的ではありませんが、役に立ちます。

もう 1 つのオプションは、異なる優先順位で複数のソフトウェア ウォッチドッグを追加することです。アイドル状態のスレッドには変数 A を 1000 に設定し、(専用の) 中優先度スレッドには変数 B を設定します。RTOS クロック割り込みハンドラーでは、両方の変数をチェックします。この情報により、ループしているスレッドの優先順位が「中」より高いか、「中」より低いかがわかります。必要に応じて、3 つ目、4 つ目、または必要な数のソフトウェア ウォッチドッグを追加できます。最悪の場合は、使用される優先度ごとにソフトウェア ウォッチドッグを追加します (ただし、追加のスレッドの数と同じだけ費用がかかります)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top