20

いくつかの埋め込みコードをFreeRTOSに移動した後、ウォッチドッグに関する興味深いジレンマが残りました。ウォッチドッグタイマーは、私たちのアプリケーションの必需品です。FreeRTOSを使用することは、私たちにとっても大きな恩恵です。アプリケーションがよりシングルタスクである場合、タスクがタイムリーに論理的に進行していることを確認できるように、ロジックフローのタイムリーなポイントでウォッチドッグにフィードしました。

ただし、複数のタスクがある場合、それは簡単ではありません。あるタスクは、何らかの理由で進行せずに拘束される可能性がありますが、別のタスクはうまく機能し、ウォッチドッグを幸せに養うのに十分な進歩を遂げています。

1つの考えは、ウォッチドッグにフィードするためだけに別のタスクを起動し、他のタスクが定期的にインクリメントするいくつかのカウンターを使用することでした。ウォッチドッグタスクがチェックされると、すべてのカウンターが他のすべてで進行しているように見えます。タスク、もしそうなら、先に進んでウォッチドッグに餌をやる。

このような状況で他の人が何をしたのか知りたいですか?

4

4 に答える 4

13

他のすべてのタスクのステータスを監視するウォッチドッグタスクは、優れたソリューションです。ただし、カウンターの代わりに、タスクごとにステータスフラグを使用することを検討してください。ステータスフラグには、UNKNOWN、ALIVE、およびASLEEPの3つの可能な値が必要です。定期的なタスクが実行されると、フラグがALIVEに設定されます。非同期イベントでブロックするタスクは、ブロックする前にフラグをASLEEPに設定し、実行時にALIVEに設定する必要があります。ウォッチドッグモニタータスクの実行時に、すべてのタスクがALIVEまたはASLEEPの場合、ウォッチドッグをキックする必要があります。次に、ウォッチドッグ監視タスクは、すべてのALIVEフラグをUNKNOWNに設定する必要があります。(ASLEEPフラグはASLEEPのままにする必要があります。)モニタータスクがウォッチドッグを再びキックする前に、UNKNOWNフラグのあるタスクを実行し、フラグをALIVEまたはASLEEPに再度設定する必要があります。

詳細については、この記事の「マルチタスク」セクションを参照してください: http ://www.embedded.com/design/debug-and-optimization/4402288/Watchdog-Timers

于 2013-02-08T20:19:03.550 に答える
2

これは確かにウォッチドッグタイマーの大きな苦痛です。

私のボードはGPIOラインにLEDがあるので、while / sleepループ(750msオン、250msオフ)で、次に低い優先度のスレッド(最も低いのはアイドル状態のスレッドで低電力になります)で点滅しますループ内のモード)。LEDフラッシュスレッドにwdogフィードを入れました。

これは、完全なクラッシュとCPUループの優先度の高いスレッドには役立ちますが、システムがデッドロックした場合には役立ちません。幸いなことに、私のメッセージパッシングデザインはデッドロックしません(とにかく、頻繁ではありませんが:)。

于 2013-02-07T21:08:53.090 に答える
2

タスクが削除されたり、長期間休止したりする可能性のある状況に対処することを忘れないでください。これらのタスクが以前にウォッチドッグタスクでチェックインされていた場合は、「チェックアウト」メカニズムも必要です。

つまり、ウォッチドッグタスクが担当するタスクのリストは動的である必要があり、一部のワイルドコードがリストからタスクを簡単に削除できないように編成する必要があります。

私は知っている、簡単に言ってからやった...

于 2013-03-19T21:42:09.423 に答える
0

FreeRTOSタイマーを使用してソリューションを設計しました。

  1. HWWDに給電するSystemSupervisorSWタイマー。FreeRTOSに失敗すると、リセットが発生します。
  2. 各タスクは、SystemReset関数を使用して「独自の」SWタイマーを作成します。
  3. タイマーが期限切れになる前に「手動で」リロードする各タスク。
  4. SystemReset関数は、suisideをコミットする前にデータを保存します

いくつかの擬似コードのリストは次のとおりです。

//---------------------------------
//
// System WD
//
void WD_init(void)
{
HW_WD_Init();
    //  Read Saved Failure data, Send to Monitor
    //  Create Monitor timer
    xTimerCreate(   "System WD",        //  Name
                    HW_WD_INTERVAL/2,   //  Reload value
                    TRUE,               //  Auto Reload
                    0,                  //  Timed ID (Data per timer)
                    SYS_WD_Feed);
}
void SYS_WD_Feed(void)
{
    HW_WD_Feed();
}

//-------------------------
//   Tasks WD
//
WD_Handler WD_Create()
{
    return xTimerCreate(   "",                 //  Name
                           100,                //  Dummy Reload value
                           FALSE,               //  Auto Reload
                           pxCurrentTCB,       //  Timed ID (Data per timer)
                           Task_WD_Reset);
}

Task_WD_Reset(pxTimer)
{
    TaskHandler_t th = pvTimerGetTimerID(pxTimer)
    // Save Task Name and Status
    //  Reset
}

Task_WD_Feed(WD_Handler, ms)
{
    xTimerChangePeriod(WD_Handler, ms / portTICK_PERIOD_MS, 100);
}
于 2016-02-24T10:19:15.217 に答える