2388026_ja-JP

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

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ソースコードを変更する必要のない、この問題に対する公式または推奨される解決策はありますか?

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

よろしくお願いします。

タグ(1)
評価なし
バージョン履歴
最終更新日:
昨日
更新者: