こんにちは、
SDK内のIMXRT EDMA APIは「ハッピーケース」割り込みを正しく処理しているようです。しかし、エラー割り込みを処理するための仕組みは見当たらないようだ。それだけでなく、すべてのDMAに対して1つのグローバルなDMA_ERROR_IRQHandlerが存在するようです。例えばDMA0とDMA1の両方を使っている場合、状況が「良好」な状態にあるときにDMA0/DMA1のIRQHandlerが呼び出され、SDKがどのDMAがハッピーインタラプトを受け取ったかを識別できます。しかし、DMAエラーが発生した場合、グローバルなエラー割り込みハンドラが1つしかないため、どのDMA(0、1、またはその他)でエラーが発生したかを簡単に知る方法はありません。
以前の質問で、LPUARTエラーIRQ処理について質問したのと同様です。なぜこれがSDKに組み込まれていて、DMAエラーを処理したり適切なコールバックを呼び出したりしないのでしょうか?今は、エラーがどのDMAにあるかを手作業で特定し、SDK外の特別な処理を呼ぶ方法を考えなければなりません。単にコールバックを呼んでもらうのではなく。
本番コードで使えるはずのSDKにしては、堅牢性の機能が欠けているように思えますし、多くの人はこれらのエラーがSDKによって処理されていると思い込んでいて、実際にはそうではないという事実を考えていないのだと思います。
-m
@nxp16様、
どのi.MX RTデバイスをお使いですか?DMA0とDMA1の話ですが、2つのDMAコントローラペリフェラルではなく、2つのDMAチャネルのことを指していますか?
すべての i.MX RTデバイスに2つのeDMAコントローラーがあるわけではありません。例えば:
i.MX RT1180には2つのeDMAコントローラが含まれています。スタートアップファイル(例:startup_mimxrt1189_cm33.c)には、DMA_ERROR_IRQHandlerとDMA4_ERROR_IRQHandlerの2つのDMAエラーハンドラがあります。
i.MX RT1050にはeDMAコントローラが1つしかありません。起動ファイル(例えば、startup_mimxrt1052.c)では、DMAエラーハンドラはDMA_ERROR_IRQHandlerという1つだけです。
一般的に、DMAエラーは比較的まれなイベントです。ハードウェアアーキテクチャの観点からは、チャネルエラーの状態はモジュールレベルのエラー要求に集約され、DMAエラー割り込みを引き起こします。したがって、ソフトウェアは各チャネルのエラーステータスレジスタ(例えばCHn_ES)を調べ、どの特定のチャネルがエラーを引き起こしたかを特定しなければなりません。
よろしくお願いいたします。
シェリー・チャン
すみません、チャネルのことを言いました。私はIMXRT1172を使用しています。
もし使っていた周辺機器に問題があった場合、DMAエラーは起こるのではないでしょうか?つまり、LPSPIとDMAを組み合わせた場合、SPIエラーが発生するとDMAエラーも発生するのではないでしょうか?そうでない場合、DMA使用時のSPIエラーはSPIエラー割り込みをトリガーしますか?
ありがとうございます
-m
@nxp16様、
いいえ。DMA使用中に周辺エラーが発生しても、必ずしもDMAコントローラ自体がエラーを報告するわけではありません。ほとんどの場合、SPIエラーとDMAエラーは2つの別々のステータスおよび割り込み機構で処理されます。
DMAは、DMA、バス、または転送層のエラーのみを報告します。LPSPIにおけるプロトコルレベルまたはFIFO関連のエラーは、LPSPIペリフェラル自身のステータスフラグやエラー割り込みを通じて処理されるべきです。DMAモードで動作させた場合でも、すべてのSPIエラーが自動的にDMAエラーに変換されるわけではありません。
よろしくお願いいたします。
シェリー・チャン
やはりそうだったか。その場合、SDKの転送APIはさらに堅牢性が低くなります。SDK外でペリフェラルやDMAエラーを処理しなければならない場合、デフォルトのIRQハンドラをやや巧妙にオーバーライドしたり、エラープロセッシング後もSDKハンドラーに呼び出すようにするなど、かなりの追加作業が必要です。これらの機能がSDKの転送APIに含まれていないのは非常に落胆します。
@nxp16様、
ご懸念は理解できますし、SDKトランスファーAPIと別にペリフェラルエラーを扱うことで必要なアプリケーションレベルのコード量が増えることに同意します。ご意見ありがとうございます。皆さんのご意見はSDKチームにお伝えします。
よろしくお願いいたします。
シェリー・チャン
実際は、思っていたよりもひどい。EDMA LPSPI転送APIを使用すると、LPSPI_MasterTransferEDMAが呼び出す関数LPSPI_PrepareTransferEDMAがすべてのSPI割り込みを無効にするため、SPIエラーを捕捉できなくなります。そのため、エラー割り込みを呼び出し前に有効にすることは不可能で、再度無効化され、SPI EDMA転送がすでに進行中なので遅すぎます。これはこのAPIの重大なバグです。
-m
はい、今のところはそれが回避策として私が取らざるを得なかった方法です。しかし、SDKファイルの編集はあまり良い解決策ではありません。残念ながらSDKの更新時にファイルが変更される可能性があるからです。
ありがとうございます
-m
@nxp16様、
ご指摘ありがとうございます。
LPSPI_PrepareTransferEDMA(LPSPI_Type *base)の実装を確認したところ、LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable)が呼び出されていることが分かりました。
ShellyZhang_0-1784514572337.png
kLPSPI_AllInterruptEnableを無効にするのではなく、EDMA転送操作に必要な割り込みのみを無効にし、エラー割り込みは有効のままにする。