メインコントローラー:imx8mp
カーネル: Linux 5.4.70
サウンドカード:SGTL5000
アプリケーション:mmapを使用してデータをDMAバッファに移動します。
障害の症状: アプリケーションが一定時間オーディオを再生すると、カーネルに次のエラーメッセージが表示されます: fsl-sai 30C3000.sai: isr:Transmit。「アンダーランが検出されました」というメッセージが画面に表示され、特定のカーネルファイル(./kernel/kernel-5.4.70/sound/soc/fsl/fsl_sai.c)に対応しています。
..........
if(flags & FSL_SAI_CSR_FEF) {
dev_dbg(dev,"isr:送信アンダーランを検出しました\n");
/* 安全のためFIFOをリセット */
xcsr |= FSL_SAI_CSR_FR;
}
..........
同時に、`cat /proc/interrupts | grep sdma` コマンドを使用してサウンドカードの DMA 割り込み数をチェックし、増加しないようにします。
現在のコード構成では、FIFOがアンダーランするとFIFOの状態が異常になり、それが原因でDMAが誤動作するというのは本当でしょうか?
IMX8MPの仕様を見ると、次のような説明があります。FCONT: IMX8MP PRMドキュメント14.4.2.7.3。FIFOエラー継続が有効になっている場合、FIFOはアンダーラン後もソフトウェアの介入なしにデータの送信を継続します。データが正しい順序で送信されるようにするため、送信機は、FIFO がアンダーランしたフレーム内の同じワード番号から処理を続行しますが、送信 FIFO に新しいデータが書き込まれた後にのみ続行します。
仕様書に記載されているこの構成によると、この状況でDMAがアンダーランした後でも、正常に動作し続けることができるのでしょうか?DMAがデータをFIFOに移動すれば、以前のDMAが誤動作してFIFOがアンダーランする代わりに、以前のサウンドを再生し続けることができるのでしょうか?
こんにちは@zhuliushun
1. FCONTの理解は基本的に正しいが、FCONTは根本的な解決策ではない。
2. 根本的な原因は、TX FIFOの供給速度が消費速度よりも遅いことです。この点を確認して、原因を特定してください。
3. 次の2つのパッチのインストールを検討してください。
LKML: Shengjiu Wang: [PATCH] ASoC: fsl_sai: 「FIFO continue on error」FCONTビットを有効にする
ASoC: fsl_sai: ISR 内の不要な FIFO リセットを削除 - Patchwork
よろしくお願いします、
志明
こんにちは@Zhiming_Liu
はい、この問題の原因は、FIFOへのデータ充填速度がFIFOのデータ消費速度よりも遅いことです。そして、FIFOへのデータ充填はDMAに基づいています。
1. 現在のデバッグにより、FIFOが空になるとアンダーランが発生し、DMAも動作を停止するため、FIFOが補充されなくなることが明らかになりました。
2.投稿にある 2 つのパッチを適用した後、デバッグの結果、FIFO がまだアンダーランしており、DMA が機能していないことが判明しました。
fsl_sai.c の割り込みコールバック関数 fsl_sai_isr() では、xcsr と tcr4 の値が出力されます。詳細は以下を参照してください。
fsl-sai 30c30000.saiscsr :ステータス:0xd0170c01
fsl-sai 30c30000.sai isr: 送信インダランを検出しました、tcr4: 0x18010f3a
不具合が発生した際、前述の印刷処理によって画面が繰り返し更新された。
3. 2の知見に基づくと、tcr4のbit[28]は=1、 FCONTが有効です。
4. 私の問題について:オーディオファイルの再生がフリーズします(FIFOアンダーラン、DMAが動作しない、停止)。私が望む解決策は、FIFOアンダーランが発生した場合、ハードウェアデータを保持し、リセットせずに現在の状態を移動させ、DMAは正常に動作することです。バッファにデータが利用可能になったとき(アプリケーションがmmapを使用してデータを埋めたとき)、 DMA(FIFOからのDMA要求に基づく)はデータをFIFOに移動し、オーディオファイルの再生を継続できるようにします。これは実現可能でしょうか?