Linux设备驱动程序 - 我的device_read()出了什么问题?

时间:2010-04-14 11:59:26

标签: linux-kernel driver device-driver

我一直在编写一个设备 dev / my_inc ,这意味着将一个正整数 N 表示为ASCII字符串,并将其存储在内部。从设备读取的任何内容都应生成整数(N + 1)的ASCII字符串表示形式。

然而,当我cat /dev/my_inc时,我似乎只是将myinc_value消息缓冲区的前半部分放回用户空间。

  • 如果myinc_value为48,则cat /dev/my_inc会产生4.

  • 如果myinc_value为489324,cat /dev/my_inc yields 489。

但是,bytes_read表示整个邮件已复制到用户空间。以下是 dmesg 的输出:

[54471.381170] my_inc opened with initial value 489324 = 489324.
[54471.381177] my_inc device_read() called with value 489325 and msg 489324.
[54471.381179] my_inc device_read() read 4.
[54471.381182] my_inc device_read() read 8.
[54471.381183] my_inc device_read() read 9.
[54471.381184] my_inc device_read() read 3.
[54471.381185] my_inc device_read() read 2.
[54471.381186] my_inc device_read() read 5. my_inc device_read() returning 7.
[54471.381192] my_inc device_read() called with value 489325 and msg 489325.

从shell调用时:

root@rbst:/home/rob/myinc_mod# cat /dev/my_inc
489

来源:

// Read from the device
//
static ssize_t device_read(struct file * filp, char * buffer, 
    size_t length, loff_t * offset)
{
    char c;
    int bytes_read = 0;
    int value = myinc_value + 1;

    printk(KERN_INFO "my_inc device_read() called with value %d and msg %s.\n", 
        value, msg);

    // Check for zero pointer
    if (*msg_ptr == 0) 
    {
        return 0;
    }
    // Put the incremented value in msg 
    snprintf(msg, MAX_LENGTH, "%d", value);

    // Copy msg into user space
    while (length && *msg_ptr) 
    {
        c = *(msg_ptr++);
        printk(KERN_INFO "%s device_read() read %c. ", DEV_NAME, c);
        if(put_user(c, buffer++))
        {
            return -EFAULT;
        }
        length--;
        bytes_read++;
    }

    // Nul-terminate the buffer
    if(put_user('\0', buffer++))
    {
        return -EFAULT;
    }
    bytes_read++;
    printk("my_inc device_read() returning %d.\n", bytes_read);
    return bytes_read;
}

2 个答案:

答案 0 :(得分:2)

可能是将put_user()定义为宏,以便

中的后增量运算符
if(put_user(c, buffer++))

正在搞砸 - 虽然我看不出它是如何解释你所看到的。

无论如何,使用copy_to_user()复制整个msg会更方便,更有效。

答案 1 :(得分:1)

它只显示1个字节的原因是因为在将msg_ptr设置为c之前递增它。它需要是c = * msg_ptr ++;或c = * msg_ptr; msg_ptr ++;以便在赋值后发生增量