i.MXRT1176では、EDMAとFLEXCANを使用しています。(SDK 26.03)
DMA転送完了時にコールバック関数が定義されています。
これが私たちの流れです。
1.転送を開始するには、`FLEXCAN_TransferReceiveFifoEDMA()` を呼び出してください。
2. DMA転送完了時にユーザー定義コールバックが呼び出されます。
3. データはDMAバッファからコピーされ、メッセージの受信を継続するために`FLEXCAN_TransferReceiveFifoEDMA()`が呼び出されます。
4. 手順2~4を繰り返す
別のノードから最小限のフレーム間隔でバースト的にメッセージを送信すると、ACKエラーの数が増加することがわかりました。つまり、iMXがメッセージをACKできないということです。
処理の流れを追っていくと、DMA転送完了コールバックが発生するたびに、FLEXCAN上でDMAが無効化されているようです。「FLEXCAN_TransferReceiveFifoEDMA()」が呼び出されると再び有効化されます。 これは「FLEXCAN_EnableRxFifoDMA()」を呼び出すことで行います。有効化/無効化DMAはFLEXCANのMCRレジスタ内のDMAビットを更新し、フリーズモードでのみ可能です。メッセージを一気に受信しているため、FLEXCANがフリーズモードに設定されている間に送信が進行中である可能性があります。そして、着信メッセージをACKで確認できません。
こんにちは、@r-uv さん。
詳細な分析をありがとうございました。あなたの観察はSDKの実装と一致しています。
FLEXCAN_TransferReceiveFifoEDMA() は、有限長のトランザクション API です。DMA完了の後、ドライバーはRx FIFO DMA要求を無効化し、次の呼び出しで再び有効化します。MCR[DMA]を変更するにはフリーズモードが必要となるため、最小IFSトラフィックの次のフレームがFlexCANが通常モードに戻る前に到着する可能性があり、その結果ACKが欠落する可能性があります。
これは、繰り返し行われるDMAの有効化/無効化操作を削除するとACKエラーは解消されるものの、フレームのドロップが依然として発生する理由も説明しています。フリーズに関連するACKギャップは解消されますが、eDMA転送は継続的に再有効化されないためです。
連続的なバーストトラフィックについては、Rx FIFO DMA要求を有効にし、ハードウェアチェーンのピンポン/散乱集いTCDを使用して次のバッファが自動的に有効化されるようにすることを推奨します。これは、FLEXCAN_TransferReceiveFifoEDMA() を繰り返し再起動するのではなく、連続した DMA 受信パスを必要とします。
よろしくお願いします、
ギャビン
ご回答ありがとうございます。SDKにこのサポートを追加する計画はありますか?現在のトランザクションAPI実装だけでなく、継続的なDMAベースの実装はどうでしょうか?