2015-07-22 2 views
0

Я работаю над простым драйвером персонального устройства. Я реализовал функции чтения и записи в модуле, проблема в том, что когда я пытаюсь прочитать файл устройства с помощью cat /dev/devicefile, он переходит в бесконечный цикл, т. Е. Несколько раз повторяя одни и те же данные. Может ли кто-нибудь предложить мне какое-либо решение этой проблемы? Ниже приведен код драйвера.Функция cat call read() бесконечное время

#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); 
+0

Существует всеобъемлющий пример символьного устройства файлы здесь: [Charcter Device Files] (http://www.tldp.org/LDP/lkmpg/2.4/html/c577.htm) – paddy

ответ

1

Вы не уважая размер буфера передается в функцию dev_read, так что вы можете быть применение к неопределенному поведению в cat. Попробуйте это:

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; 
} 
+0

спасибо за ответ, но его не работает – don

3

.read функция также должна корректно обрабатывать его len и off аргументы. Самый простой способ осуществить чтение из памяти буферным файла использовать simple_read_from_buffer помощника:

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); 
} 

Вы можете инспектировать код этого хелпера (определенный в fs/libfs.c) для образовательных целей.

BTW, для вашего .write способ вы можете использовать simple_write_to_buffer вспомогательный.

1

Эта проблема может быть решена путем правильной установки *off (четвертый параметр my_read()).

Вам необходимо вернуть счет в первый раз и ноль со второго раза.

if(*off == 0) { 
    while (msg[count] != 0) { 
     put_user(msg[count], buff++); 
     count++; 
     (*off)++; 
    } 
    return count; 
} 
else 
return 0; 
Смежные вопросы