チームの皆さん、こんにちは。
FreeRTOSを実行しているS32K358で、ランダムなハードフォルトが発生しています。
アプリケーションは長時間正常に動作しますが、突然フリーズします。システムが実行を停止した後、ソフトウェア・ウォッチドッグ(SWT)はサービスされず、最終的にコントローラがリセットされます。
障害は即座に発生するわけではなく、約1~2時間の連続実行後に発生する。
障害発生後に停止すると、コールスタックには以下が表示されます。
PenSV_Handler()
↓
HardFault_Handler()
レジスタ値:
LR = 0xA5A5A5A5
PC = 0x00407BD9
その他の登録簿:
R0 = 0x204011A8
R3 = 0x2040012C
R12 = 0x20400010
ご提案やデバッグに関するアドバイスなど、何でもいただければ大変ありがたいです。
こんにちは、 @nirmal_masilamani さん。
FreeRTOSのコンテキスト切り替え時に保存されたタスクコンテキストが破損しているようです。
PendSVはFreeRTOSによってコンテキスト切り替えに使用されるため、PendSV_Handler()内でHardFaultが発生した場合、多くの場合、スケジューラが無効なタスクコンテキストを復元しようとしていることを意味します。
考えられる根本原因の一つは、タスクスタックオーバーフローです。タスクのスタックサイズを増やし、FreeRTOSのスタックオーバーフロー検出機能を有効にすることをお勧めします。
configCHECK_FOR_STACK_OVERFLOW
実装: vApplicationStackOverflowHook()。
さらに、uxTaskGetStackHighWaterMark()を使って各タスクの残りのスタック空間を定期的に監視することもできます。これにより、故障が発生する前にスタック限界に近いタスクを特定するのに役立ちます。
よろしくお願いいたします。
ダニエル
こんにちは、 @danielmartynek さん、
ご回答ありがとうございます。
既にスタックサイズを増やしたり、スタックオーバーフローフックを有効にしたりしてみました。
Overflow Hookにdebug CAN msgを追加しましたが、故障発生時にそのメッセージが届きません。
また、障害が発生した際には uxTaskGetStackHighWaterMark()を監視します。
タスク 1 : 1977 × 4 ≈ 7908 バイトの空き容量
タスク2:1971 × 4 ≈ 7884バイトの空き容量
タスク3:3988 × 4 ≈ 15952バイトの空き容量
こんにちは、 @nirmal_masilamani さん。
したがって、根本原因としてスタックオーバーフローを除外できるでしょう。
しかし、タスクコンテキストは依然として破損している。プロセッサはLR = 0xA5A5A5A5を復元しており、これがUsageFaultを引き起こします。0xA5A5A5A5 は tskSTACK_FILL_BYTE (0xA5U) から生成されるパターンで、FreeRTOS がタスクスタックを作成する際にタスクスタックを埋めるために使用されます。
したがって、LRが0xA5A5A5A5になった場合、コンテキストは有効なレジスタ値ではなく、元のスタックフィルパターンが残っている場所から復元されます。
SPが破損した場合に起こり得ます。その場合、PendSV_Handler()はRAM内の誤った場所からタスクコンテキストを復元します。
スタックポインタのアドレスからSRAM領域を特定できるはずです。
MPUとXRDCを使用して、その領域を適切に保護することをお勧めします。
また、FreeRTOS APIを呼び出す割り込み処理はありますか?もしそうなら、FromISR()のバリアントを使っているのか、configMAX_SYSCALL_INTERRUPT_PRIORITYに関して優先順位は正しく設定されているのか?
よろしくお願いいたします。
ダニエル