I am working on simple character device driver. I have implemented read and write functions in the module, the problem is when I try to read the device file using cat /dev/devicefile
it is going into infinite loop i.e. reading the same data repeatedly. Can someone suggest me any solution to this problem? Below is my driver code.
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/string.h>
#include<asm/uaccess.h>
#include<linux/init.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("character device driver");
MODULE_AUTHOR("Srinivas");
static char msg[100]={0};
static int t;
static int dev_open(struct inode *, struct file *);
static int dev_rls(struct inode *, struct file *);
static ssize_t dev_read(struct file *, char *,size_t, loff_t *);
static ssize_t dev_write(struct file *, const char *, size_t,loff_t *);
static struct file_operations fops =
{
.read = dev_read,
.open = dev_open,
.write = dev_write,
.release = dev_rls,
};
static int himodule( void )
{
t = 0;
t = register_chrdev(0, "chardevdriver", &fops);
if (t < 0)
printk(KERN_ALERT"device registration failed\n");
else
printk(KERN_ALERT"device registered successfully\n");
printk(KERN_ALERT"major number is %d", t);
return 0;
}
static void byemodule(void)
{
unregister_chrdev(t, "chardevdriver");
printk(KERN_ALERT"successfully unregistered\n");
}
static int dev_open(struct inode *inod, struct file *fil)
{
printk(KERN_ALERT"inside the dev open");
return 0;
}
static ssize_t dev_read(struct file *filp, char *buff, size_t len, loff_t *off)
{
short count = 0;
while (msg[count] != 0) {
put_user(msg[count], buff++);
count++;
}
return count;
}
static ssize_t dev_write(struct file *filp, const char *buff, size_t len, loff_t *off)
{
short count = 0;
printk(KERN_ALERT"inside write\n");
memset(msg,0,100);
printk(KERN_ALERT" size of len is %zd",len);
while (len > 0) {
msg[count] = buff[count];
len--;
count++;
}
return count;
}
static int dev_rls(struct inode *inod,struct file *fil)
{
printk(KERN_ALERT"device closed\n");
return 0;
}
module_init(himodule);
module_exit(byemodule);
.read
function should also correctly process its len
and off
arguments. The simplest way to implement reading from memory-buffered file is to use simple_read_from_buffer
helper:
static ssize_t dev_read(struct file *filp, char *buff, size_t len, loff_t *off)
{
return simple_read_from_buffer(buff, len, off, msg, 100);
}
You can inspect code of that helper (defined in fs/libfs.c
) for educational purposes.
BTW, for your .write
method you could use simple_write_to_buffer
helper.
You are not respecting the buffer size passed into the dev_read
function, so you may be invoking undefined behaviour in cat
. Try this:
static ssize_t dev_read( struct file *filp, char *buff, size_t len, loff_t *off )
{
size_t count = 0;
printk( KERN_ALERT"inside read %d\n", *off );
while( msg[count] != 0 && count < len )
{
put_user( msg[count], buff++ );
count++;
}
return count;
}
This problem can be solved by correctly setting *off
(fourth parameter of my_read()
).
You need to return count for the first time and zero from second time onwards.
if(*off == 0) {
while (msg[count] != 0) {
put_user(msg[count], buff++);
count++;
(*off)++;
}
return count;
}
else
return 0;
来源:https://stackoverflow.com/questions/31563107/cat-function-calling-read-infinite-times