1

私は、(ドライバーを開いた状態で) マップされたメモリ位置への読み取りと書き込みを実行するドライバーをプログラミングしています:

request_mem_region(0x62200000,0x0006C,secuencial);

contador = ioremap_nocache(0x62200000,0x0006C   );

ここで、0x62200000,0x0006C は、メモリ内でインスタンス化された ipcore のメモリ位置とサイズです。「secuencial」はデバイス ドライバの名前です。

contador は void* です (仮想アドレスへのポインターです)

私のデバイスドライバーのコードの読み取りおよび書き込み関数によると:

static ssize_t device_read(struct file *filp, char *buffer,size_t length, loff_t * offset)  

static ssize_t device_write(struct file *filp, char *buffer,size_t length, loff_t * offset) 

そして私のファイル操作:

static struct file_operations fops = {
    .read    = device_read,
    .write   = device_write,
    .open    = device_open,
    .release = device_release
};

Cの私のプログラムから、私は自分のライブラリの関数を次のように使用します:

read (fd_secuencial,buffer_lectura,199, offset_read);

write( fd_secuencial,  msg,  10, offset_write);

変数は次のとおりです。

loff_t offset_read=0x00000004;
loff_t offset_write=0x00000044;

fd_secuencial は、open で取得したデバイス ドライバーへのファイル記述子です。

fd_secuencial = open("/dev/secuencial", O_RDWR | O_NOCTTY | O_NONBLOCK);

buffer と msg は、データを読み書きするためのバッファです。

問題は、オフセットがドライバーの読み取り/書き込み機能に決して来ないことです。

次のように印刷します: printk(KERN_ALERT "Offset: %llu\n", *offset);

オフセットは常に 0 です....

私のコードの何が問題になっていますか? 何か案は?

読み込み機能からファイルにアクセスする位置を変更しました

filp-> f_pos = integer_different_values​​. 

また、マップされた別のメモリ位置への読み取りは行われません。つまり、「f_pos」は変更されますが、メモリのブロックであるかのようにファイルにアクセスすることはありません (これは保持されたアプローチです)。

「コンタドール」の実績でアクセスするメモリの場所を増やすと、読み取り値が正しく取得されます。

関数 device_read / write が定義されていると思われますが、関数のメソッドに loff_t * pos フィールドが実装されていません。アプリケーションから読み取った関数を 5 つのパラメーターで呼び出すと、コンパイラーは警告を表示せず、実行は正常です (ただし、明らかに最初の 3 つのパラメーターが考慮されます)。

このため、アプリケーションから関数 device_read/write ドライバーに渡すことができず、4 番目のパラメーターとしてオフセットが指定されています。

メソッドを呼び出す正しい方法は次のとおりです。

loff_t offset = 16;
loff_t * off = &offset;

このようにして、off と呼ばれるポインター (関数プロトタイプを要求している) にオフセット値を渡します。

助けてくれてありがとう!

4

1 に答える 1

1

http://tjworld.net/books/ldd3/#SeekingADeviceの LDD3 で説明されているように、キャラクター デバイスで個別のシーク機能を実装できます。

file_operations 構造体の llseek フィールドを使用して、プロトタイプにシーク関数を割り当てることができます。

loff_t (*llseek) (struct file *, loff_t, int);

ユーザー アプリケーションまたは API は、ユーザー空間関数lseek()関数を使用してそれを実行します。

ただし、デバイスからのデータの読み取りまたはデバイスへのデータの書き込み以外の副作用を持つレジスタで操作を実行している場合は、おそらく ioctl() インターフェイスを使用して API ラッパーを提供する必要があります。http://tjworld.net/books/ldd3/#TheIoctlMethodを参照してください。

于 2013-06-30T06:41:37.837 に答える