我正在编写一个驱动程序,它对已经映射(在驱动程序打开时)的内存位置执行读写操作:
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 driver,offset作为第4个参数。
调用该方法的正确方法如下:
loff_t offset = 16;
loff_t * off = &offset;
这样,您将偏移值传递给一个名为off的指针(它正在请求函数原型)
非常感谢你的帮助!
答案 0 :(得分:1)
您可以使用LDD3中所述的字符设备实现单独的搜索功能:http://tjworld.net/books/ldd3/#SeekingADevice。
您可以使用file_operations结构的llseek字段为原型分配搜索功能:
loff_t (*llseek) (struct file *, loff_t, int);
然后,用户应用程序或API将使用用户空间函数lseek()函数来执行它。
但是,如果您对除了从设备读取数据或向设备写入数据之外的副作用的寄存器执行操作,您应该使用ioctl()接口并提供API包装器。请参阅http://tjworld.net/books/ldd3/#TheIoctlMethod。