【发布时间】:2013-06-27 10:54:08
【问题描述】:
我正在编写一个驱动程序,该驱动程序执行对已映射(在驱动程序打开中)的内存位置的读取和写入:
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 "偏移量: %llu\n", *offset);
并且偏移量始终为 0....
我的代码有什么问题?有什么想法吗?
我通过
更改了从读取功能访问文件的位置filp-> f_pos = integer_different_values.
并且没有读数被带到映射的不同内存位置。 也就是说,“f_pos”发生了变化,但不会像访问内存块一样访问文件(这是持有的方法)。
如果我增加使用“contador”成就访问的内存位置,则可以正确读取。
我怀疑定义了函数 device_read / write 但函数的方法中没有实现 loff_t * pos 字段。 如果我调用从应用程序读取的函数,带有5个参数,编译器不会发出警告并且执行正常(但显然考虑到前3个参数)
因此,我不能从应用程序传递给函数 device_read / write driver,offset 作为第 4 个参数。
调用方法的正确方法如下:
loff_t offset = 16;
loff_t * off = &offset;
通过这种方式,您将偏移值传递给一个名为 off(它正在请求函数原型)的指针
非常感谢您的帮助!
【问题讨论】:
-
这是字符设备吗?据我所知,他们不允许搜索,所以偏移参数有点多余。
-
是的,它是一个字符设备驱动程序,我想在 ioread 和 iowrite 函数中使用 de offset:ioread32(contador + *offset); iowrite32(contador + *offset);
-
这听起来像是一个 XY 问题。撇开字符设备不可搜索的问题不谈,为什么要在 IO 读/写函数中使用该偏移量?
-
因为内存中有ipcore寄存器,是可读写的,例如每个寄存器有32bits大小,第一个寄存器写入接受某种类型的数据,结果在寄存器中得到偏移量= 0x044
-
抱歉,我认为我的问题不太清楚。我的意思是,你为什么让用户空间程序直接写入寄存器空间?您的内核驱动程序不应该抽象设备细节并提供某种 API,而不是让用户空间程序直接写入寄存器吗?
标签: c linux kernel driver linux-device-driver