Technexion ディストリビューションに基づく Angtsrom 組み込み Linux カーネル v.2.6.37 を使用しています。DM3730 SoC、TDM3730 モジュール、カスタム ベースボード。CodeSourcery ツールチェーン v. 2010-09.50
これが私のシステムのデータフローです: http://i.stack.imgur.com/kPhKw.png
FPGA は増分データを生成し、カーネルは GPMC DMA 経由でそれを読み取ります。GPMC パック サイズ = 512 データ サンプル。バッファ サイズ = 61440 32 ビット サンプル (= 60 RAM ページ)。
DMA バッファは dma_alloc_coherent によって割り当てられ、mmap() 呼び出しによってユーザー空間にマップされます。ユーザー アプリケーションは、DMA バッファからデータを直接読み取り、fwrite() 呼び出しを使用して NAND に保存します。ユーザーは一度に 4096 サンプルのデータを読み取ります。
そして、ファイルに何が表示されますか? http://i.stack.imgur.com/etzo0.png 赤線はリングバッファの最初の境界を意味します。おっと!小さなパック (~16 サンプル) は境界の後に隠れ始めます。それらの値は正確に = 対応するバッファ位置の「古い」値です。しかし、なぜ?16 サンプルは、DMA パック サイズおよびユーザー読み取りパック サイズよりもはるかに小さいため、ポインターの不一致はあり得ません。
mmap() 機能がどこかに隠れていると思います。MAP_LOCKED、MAP_POPULATE、MAP_NONBLOCK など、mmap() のさまざまなフラグを試しましたが、成功しませんでした。私はこの振る舞いを完全に誤解しています:(
PS mmap() とゼロコピー アクセスの代わりにカーネルから copy_to_user() を使用している場合、そのような動作はありません。