2

ボード紹介:

基本的にDVBストリームをキャプチャしてテレビに表示するために使用されるST40チップを搭載したボードで作業しています。ボードは Linux OS で動作しています。

問題の説明:

O_DIRECT フラグを使用して、USB 上の大きなファイル (約 2 GB) からデータを読み取ろうとしています。関連するコード スニペットは次のとおりです。

char subblk[BLKSIZE];
open (filename2,O_CREAT|O_WRONLY|O_DIRECT,S_IRWXU|S_IRWXG|S_IRWXO);
read (fp,subblk,BLKSIZE);

エラー番号22で読み取りに失敗したと表示されます-"EINVAL 22 /* Invalid argument"

これがプログラミングの問題なのか、アーキテクチャに依存する問題なのかを明確にするために、デスクトップ システムで同じコードを実行したところ、まったく問題なく動作し、読み取った文字を印刷することができました。ST40 ボードで失敗する理由は何ですか?

4

3 に答える 3

10

ファイルシステムのブロック境界でバッファを整列する必要があります。これを実現するには、スタックで buffer を使用したり (例のように)、 を呼び出したりするべきではありませんが、 memalign ()malloc(BLKSIZE)を使用する必要があります。したがって、コードは次のようになります。

/* make sure BLKSIZE is defined as 512 */
char *subblk = memalign(BLKSIZE, BLKSIZE);
open (filename2,O_CREAT|O_WRONLY|O_DIRECT,S_IRWXU|S_IRWXG|S_IRWXO);
read (fp,subblk,BLKSIZE);

あなたのコードがデスクトップで動作している理由は、おそらく偶然のアライメントまたは異なるファイルシステムタイプ (アライメント要件なし) です。

于 2012-08-04T14:16:22.157 に答える
2

マニュアルページから引用するには:

O_DIRECT フラグは、ユーザー空間バッファーの長さとアドレス、および I/O のファイル オフセットにアラインメント制限を課す場合があります。Linux では、アラインメントの制限はファイル システムとカーネルのバージョンによって異なり、完全に存在しない場合があります。ただし、現在、アプリケーションが特定のファイルまたはファイル システムのこれらの制限を検出するための、ファイル システムに依存しないインターフェイスはありません。xfsctl(3) の XFS_IOC_DIOINFO 操作のように、一部のファイル システムはそれを行うための独自のインターフェースを提供します。

Linux 2.4 では、転送サイズ、ユーザー バッファーのアラインメント、およびファイル オフセットはすべて、ファイル システムの論理ブロック サイズの倍数でなければなりません。Linux 2.6 では、512 バイト境界へのアライメントで十分です。

subblkブロックは適切に配置されていますか? 両方のシステムのファイル システムやカーネルのバージョンは同じですか?

于 2012-05-09T09:31:42.920 に答える
1

O_DIRECTフラグは内部でDMAを使用し、カーネルではDMAが有効になっていません。これが私のデスクトップPCで動作していたが、ボードでは機能しなかった基本的な理由です。DMAが有効になっているカーネルとDMAが有効になっていないカーネルに異なるカーネルがありました。

于 2012-05-09T11:21:02.343 に答える