2388026_ja-JP

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2388026_ja-JP

2388026_ja-JP

S32K314 RTD (MCAL) - OsIf クリティカルセクションが原因で発生した高優先度 ISR デッドロック

S32K314 RTD (MCAL) - OsIf クリティカルセクションが原因で発生した高優先度 ISR デッドロック

こんにちは、

私は以下のプラットフォームでアプリケーションを開発しています:

  • MCU:NXP S32K314

  • RTD 7.0.0(AUTOSAR・マカル)

  • FreeRTOS 7.0.0

  • S32 Design Studio 3.6.4

開発中に、優先度の高い割り込みに関連するデッドロックに遭遇しました。私の理解が正しいかどうか、また推奨される解決策があるかどうかをお伺いしたいと思います。

バックグランド

FreeRTOSでは、configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITYよりも高い優先度を持つISRは、FreeRTOS APIを呼び出してはならないと規定されています。

しかし、多くのRTD MCAL APIは、内部的に以下の呼び出しチェーンを通じてFreeRTOSのクリティカルセクションAPIを実行していることがわかりました。

MCAL API
    ↓
SchM_Enter_xxx()
    ↓
OsIf_SuspendAllInterrupts()
    ↓
SuspendAllInterrupts()
    ↓
OsIf_Interrupts_SuspendAllInterrupts()
    ↓
taskENTER_CRITICAL_FROM_ISR()

そして、

MCAL API
    ↓
SchM_Exit_xxx()
    ↓
OsIf_ResumeAllInterrupts()
    ↓
ResumeAllInterrupts()
    ↓
OsIf_Interrupts_ResumeAllInterrupts()
    ↓
taskEXIT_CRITICAL_FROM_ISR()

この挙動は、DIOやGPTのような単純なペリフェラルレジスタアクセスのみを行うAPIでも存在します。

問題

MCAL API が高優先度 ISR (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY より高い優先度) から呼び出されると、taskENTER_CRITICAL_FROM_ISR() の内部呼び出しによって FreeRTOS の割り込みマスキング状態が不整合になります。

その結果、taskEXIT_CRITICAL_FROM_ISR() が戻った後、BASEPRI が正しく復元されず、SysTick や PendSV などの優先度の低い割り込みがマスクされたままになります。

xPortSysTickHandler() が実行されなくなるため、スケジューラは最終的に停止します。

以下のようなAPIを使用して、この問題を再現することができました。

  • Dio_FlipChannel()

  • GPT(PIT)割り込みプロセッシング

  • SchMの排他領域を使用するその他のMCAL API

現在の回避策

RTDで生成されたソースコードを直接変更することを避けるため、GNUリンカーの--wrapオプションを使用して以下の関数をラップしました。

OsIf_Interrupts_SuspendAllInterrupts()
OsIf_Interrupts_ResumeAllInterrupts()

ラッパーは現在の割り込み優先度をチェックします。
添付のWrapperExample.cを参照してください。

現在のISRの優先度がconfigLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITYよりも高い場合、元の関数はスキップされます。

そうでない場合は、元の実装を呼び出します。

この回避策は、生成されたRTDソースを変更せずにデッドロックを解消するようです。

質問

  1. この挙動はRTD MCALのデザイン上当然のことですか?

  2. 高優先度のISRからDIO、GPT、CAN、または他のMCAL APIを呼び出すのは推奨されますか?

  3. NXPは、ウォッチドッグサービスやGPIOトグルなどの高優先度リアルタイム機能に対して専用ドライバ(複雑デバイスドライバ)の実装を推奨していますか?

  4. GNUリンカーの--wrapオプションを使用してOsIf_Interrupts_SuspendAllInterrupts()とOsIf_Interrupts_ResumeAllInterrupts()をラップすることは、許容できる回避策でしょうか?

  5. 生成されたRTDソースコードを変更する必要のない、この問題に対する公式または推奨される解決策はありますか?

何かアドバイスやご提案があれば、大変ありがたく思います。

よろしくお願いします。

Re: S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections

こんにちは、 @tobara さん

このケースは現在、RTD開発チームからの意見提出を待っています。


BR、ダニエル

Re: S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections

こんにちは、

ご質問に対する回答は以下のとおりです。


  • この挙動はRTD MCALの設計上当然のことですか?回答:はい、これはCAT1割り込み(つまり優先度がMAX SYSCALLより高い割り込み)からOSのAPIを呼び出すために起こります。MAX_SYSCALL以上の割り込みの手当は、RTOSの影響を受けずに最小限のレイテンシで作業を行うためです。RTOSによって生じるレイテンシを避けたいなら、最終的にRTOSを使うAPIを呼び出すべきではありません。

  • 高優先度のISRからDIO、GPT、CAN、または他のMCAL APIを呼び出すのは推奨されますか?

  • 回答:いいえ、最初の回答で述べた理由により、MAX_SYSCALより大きくすることはできません。


  • NXPは、ウォッチドッグサービスやGPIOトグルなどの高優先度リアルタイム機能に対して専用ドライバ(複雑デバイスドライバ)の実装を推奨していますか?

  • 回答: RTD SchM、OSIf API、RTOSによる遅延に耐えられるなら、既存のドライバーを使い、MAX_SYSCALLより低い割り込みから呼び出しすればいいです。優先度アップの効果は引き続き得られますが、チケットに記載されている問題は解消されません。

  • GNUリンカーの--wrapオプションを使用してOsIf_Interrupts_SuspendAllInterrupts()とOsIf_Interrupts_ResumeAllInterrupts()をラップすることは、許容できる回避策でしょうか?

  • 回答:いいえ、簡単な分析によると、この回避策は一方向のみを保護するものです。デッドロックは回避できるかもしれないが、優先度の高いISR(> MAX_SYSCALL)とレジスタ/リソースを共有する優先度の低いISRを保護するものではない。この実装は共有レジスタやグローバル変数に競合条件を導入することができます。

  • 生成された RTD ソース コードを変更する必要のない、この問題に対する公式または推奨される解決策はありますか?回答 (ただし、RTD チームによる確認が必要です) : IRQ > MAX_SYSCALL から RTD / RTOS API を呼び出さないでください。現在のRTD->OSIF->RTOSのレイテンシに耐えられるなら、優先度の高いIRQをMAX_SYSCALLより低く設定すればいいです。



すべての回答はRTDチームによる確認が必要です。私はRTOSの観点から回答しています。



Re: S32K314 RTD (MCAL) - High Priority ISR Deadlock Caused by OsIf Critical Sections

詳細なご説明をありがとうございました。

私は今、NXP RTD/MCALの以下の設計制約を理解しました。

  1. RTD/MCAL API は、優先度の高い ISR ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITYよりも優先度の高い割り込み) から呼び出してはなりません。
  2. --wrapを使う ことでデッドロックを防ぐことはできますが、RTDクリティカルセクションをバイパスすると、リソースやレジスタが高優先度コンテキストと低優先度コンテキスト間で共有される際に競合条件が発生する可能性があります。

いくつか追加の質問があります。

  1. アプリケーションが高優先度のISR(AUTOSARカテゴリー1 ISR)でのプロセッシングを必要とする場合、推奨されるソフトウェアアーキテクチャは何ですか?このような機能は、常に複雑なデバイスドライバ(CDD)として実装されるべきでしょうか、それとも専用の低レベルドライバーとして実装されるべきでしょうか?
  2. もしGPIOポートやタイマーチャネルが単一の高優先度ISRのみで、他のタスクやISRからは一切アクセスされない場合、レースコンディションに関する懸念はラップ回避策にも適用されます か?
  3. 現在のRTD/MCALは、高優先度ISRからのAPI利用をサポートしておらず、したがって高リアルタイム機能はCDDまたは専用ドライバで実装しなければならないと理解してよいでしょうか?

自動車分野以外の組み込みソフトウェアの経験から言うと、ハードウェア抽象化層はしばしばオペレーティングシステムに依存しないように設計されています。そのため、単純なGPIOおよびタイマーAPIが内部的にRTOSのクリティカルセクションAPIを呼び出していることに気づいて驚きました。

参考までに、この問題を避けるために実装したGPTドライバー(CpuPit.h/c)を添付しました。
RTDチームからのご意見やご提案をいただければ幸いです。

改めてサポートありがとうございます。

Tags (1)
No ratings
Version history
Last update:
a month ago
Updated by: