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”发生了变化,但不会像访问内存块一样访问文件(这是持有的方法)。

如果我增加使用“contador”成就访问的内存位置,则可以正确读取。

我怀疑函数 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

您可以使用 LDD3 中所述的字符设备实现单独的搜索功能:http: //tjworld.net/books/ldd3/#SeekingADevice

您可以使用 file_operations 结构的 llseek 字段来为原型分配一个 seek 函数:

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

然后,用户应用程序或 API 将使用用户空间函数lseek()函数来执行它。

但是,如果您正在对具有副作用的寄存器执行操作,而不是从设备读取数据或将数据写入设备,您可能应该使用 ioctl() 接口并提供 API 包装器。请参阅http://tjworld.net/books/ldd3/#TheIoctlMethod

于 2013-06-30T06:41:37.837 回答