2010-04-14 118 views
0

我一直在寫設備dev/my_inc這意味着取一個正整數N表示爲一個ASCII字符串,並將其存儲在內部。從設備讀取任何數據應產生整數(N + 1)的ASCII字符串表示。Linux設備驅動程序 - 我的device_read()有什麼問題?

但是,當我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稱爲:

[email protected]:/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; 
} 
+0

msg和msg_ptr在哪裏定義/初始化? 爲什麼在打印出msg之前,甚至已經設置了它? myinc_value的值是什麼? 你是什麼意思「我只獲得myinc_value輸出的第一個字節到我的shell,即使我的循環結束時有bytes_read == 2」 - 兩個字符不足以代表一個字節,而 - 任何情況下 - 你打印一個十進制格式的int,所以打印一個字節的概念是沒有意義的。 還要記住,你並沒有終止返回的字符串。 – Dipstick 2010-04-14 12:31:34

+0

msg和msg_ptr在我的頭文件中被定義爲char *類型。在device_open()調用中,myinc_value被初始化爲一個起始值(由一個宏定義),然後將myinc_value的ascii等價物複製到msg中。 例如:myinc_value初始化爲整數47.字符串「47」被複制到由msg指向的緩衝區中。 device_read()將myinc_value讀入值並遞增,並將字符串「48」放入msg中。當我cat/dev/my_inc時,它輸出沒有換行符的'4'(可能是因爲忘記終止字符串),這是我的msg緩衝區的第一個字符(字節)。 – Rob 2010-04-14 19:35:44

回答

2

這可能是put_user()被定義爲一個宏,以便在

if(put_user(c, buffer++)) 

後增量操作員搞砸了 - 儘管我不知道它是如何解釋你所看到的。

無論如何,使用copy_to_user()複製整個消息會更加方便和高效。

+0

不知道這是如何解釋我看到的,但使用copy_to_user()解決了我的問題。謝謝! – Rob 2010-04-19 01:15:02

1

原因無它,只顯示1個字節是因爲在將它設置爲等於c之前,您正在遞增msg_ptr。它需要是c = * msg_ptr ++;或c = * msg_ptr; msg_ptr ++;使增量分配後會發生