2399953_ja-JP

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

2399953_ja-JP

2399953_ja-JP

DSPI通信タイムアウトの問題

私は MPC5775B マイクロコントローラと SPI EEPROMを使っています。私のアプリケーションでは、CANメッセージは 割り込みで連続的に受信され、EEPROMとのSPI通信も 割り込み駆動型です。

CANバストラフィックが重(例:1msごとに5つのCAN IDが受信される)では、EEPROMの読み取り操作はタイムアウトし始めます。私はタイムアウトを10msとしてDSPI_MasterTransferBlocking() APIを使用しています。タイムアウト値を大幅に増やしてみましたが、それでも読み取り操作は失敗します。

興味深いことに、その動作は読み込まれるデータ量によって変化する。EEPROMから数バイトだけ読み取ろうとすると、SPI転送がタイムアウトします。しかし、EEPROMのページ全体(256バイト)を読み取った場合は、読み取り操作は正常に完了します。

また、CANトラフィックが停止されるとEEPROMの読み取り操作が問題なく成功することも観察しました。割り込みの優先順位を確認したところ、CANとSPIの両方の割り込みは同じ優先度レベル(優先度0)で設定されています。

理解したいのは以下の点です。

  • なぜ小さなSPI EEPROMの読み取り操作はCAN割り込み負荷が重い場合にタイムアウトするのに、より大きな(256バイト)ページ読み込みは正常に完了するのでしょうか?

  • これは割り込み飢餓、DSPI_MasterTransferBlocking()、またはCANとDSPI割り込みハンドラ間の相互作用に関連しているのでしょうか?

  • MPC5775B上で割り込み駆動のDSPI転送と高周波CAN割り込みを同時に使用する場合の既知の制限や推奨される構成はありますか?

さらに、デバッグ中に DSPI_MasterTransferBlocking() 内にブレークポイントを設定することで問題をデバッグしました。

status_t DSPI_MasterTransferBlocking(dspi_instance_t instance,
const void * sendBuffer、
void * receiveBuffer、
uint16_t フレーム、
uint32_t タイムアウト)
ヤージュ
DEV_ASSERT((uint32_t)instance < (SPI_INSTANCE_COUNT + DSPI_INSTANCE_COUNT));

status_t ステータス;
dspi_state_t * state = DSPI_state[instance];

if (state->status == DSPI_IN_PROGRESS)
ヤージュ
STATUS_BUSY を返します。
}

state->isBlocking = true;
(void)OSIF_SemaWait(&(state->dspiSemaphore), 0);
status = DSPI_MasterTransfer(instance, sendBuffer, receiveBuffer, frames);
if (status == STATUS_SUCCESS)
ヤージュ
status = OSIF_SemaWait(&(state->dspiSemaphore), timeout);
if (status != STATUS_SUCCESS)
ヤージュ
(void)DSPI_AbortTransfer(instance);
state->status = DSPI_TRANSFER_FAIL;

ステータスを返します。
}
}

STATUS_SUCCESS を返します。
}

dspi転送ステータスは成功しているが、dspi転送後の「OSIF_SemaWait」がタイムアウトしている。

Re: DSPI Communication timeout issue

こんにちは、

説明に基づくと、DSPI_MasterTransfer() が STATUS_SUCCESS を返すため、DSPI 転送自体は正常に開始されたようです。タイムアウトは、DSPI_MasterTransferBlocking() が転送完了通知を OSIF_SemaWait() で待機している間に発生します。

したがって、この症状は、基本的なDSPI起動の失敗というよりも、割り込み/完了処理パスに関連している可能性が高い。ブロッキングDSPI APIでは、転送が開始されると、呼び出し元はDSPI割り込み/コールバックパスがセマフォを解放するまで待機します。タイムアウトが経過する前にセマフォが解放されない場合、APIはタイムアウトを報告し、転送を中止します。

この問題がCAN割り込み負荷が重い場合にのみ発生するという事実は重要な手がかりです。CANとDSPI割り込みが同じ優先度で設定されている場合、連続的なCAN割り込み活動はDSPI割り込みのサービス遅延を引き起こすことがあります。短いEEPROM読み込みの場合、DSPIトランザクションは非常に速く完了するため、最終的なDSPI割り込みとセマフォの解放はタイミングに敏感です。256バイトのページ読み込みが長くなるほどDSPIトランザクションが長く活性化され、ドライバの割り込み処理経路の進行が異なるため、大きな転送は完了し短い転送がタイムアウトする理由が説明できます。

推奨されるチェック項目:

  1. DSPI割り込みをCAN RX割り込みよりも高い優先度で設定し、テストを繰り返します。
  2. CAN ISRはできるだけ短く保ちましょう。可能であれば、CANフレームプロセッシングをISRからタスク/メインループのコンテキストに移してください。
  3. DSPI ISRが失敗したCASEに入力されているか確認してください。
  4. DSPI転送完了コールバックまたは完了パスが状態->dspiSemaphoreを解放することを確認します。
  5. GPIOを切り替えるか、トレースポイントを使用します。
    1. CAN RSのISR入退入は可能
    2. DSPI ISRへのエントリー/イグジット
    3. DSPI転送完了コールバック
    4. OSIF_SemaWait() の前と後
  6. ブロッキングDSPI APIがISRやDSPI割り込みが実行できないコンテキストから呼び出されていないか確認してください。
  7. 診断実験として、ポーリング方式のDSPI転送、またはDMA方式のDSPI転送を試してみてください。ポーリングやDMAが同じCAN負荷で動作する場合、問題はSPIバス自体ではなく割り込みスケジューリング/完了処理にあることをさらにサポートしています。
  8. EEPROMアクセスの場合、小規模読み取りシーケンスがEEPROMプロトコルに従って必要なコマンド/アドレス/ダミー/読み取りフェーズおよびチップセレクト動作を保持していることも確認してください。しかし、エラーはセマフォ待機時に報告されるため、まずはDSPI完了割り込みパスに着目すべきである。

まとめると、最も可能性の高い方向は割り込みスターベーション、または高CAN割り込み負荷下でのDSPI完了の失敗/遅延処理です。最初の実用的なテストは、DSPI割り込みの優先度をCANより上に上げ、DSPI ISR/コールバックが失敗したCASEにセマフォをポストするかどうかを測定することです。

よろしくお願いいたします。

ピーター

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