2012-02-24 104 views
0

我是新驅動程序的開發,我試圖寫出具有讀寫控制,允許用戶進程得到我的字符設備驅動程序承擔了最後一次讀取的時間(的timespec)一個簡單的字符設備驅動程序寫。 - Linux的字符設備驅動程序:阻塞ioctl調用

long charmem_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { 
    struct charmem_dev *dev = filp->private_data; 

    if (down_interruptible(&dev->sem)) { 
     printk(KERN_WARNING "I got booted!!\n"); 
     return -ERESTARTSYS; 
    } 

    printk(KERN_WARNING "charmem: in ioctl; cmd = %d, arg = %d\n", (int)cmd, (int)arg); 
    switch(cmd) { 
     case IOCTL_GET_LAST_READ_TIME: 
      printk("charmem_ioctl: returning last read time delta, exiting...\n"); 
      up(&dev->sem); 
      return dev->last_read_delta.tv_nsec; 
      break; 

     case IOCTL_GET_LAST_WRITE_TIME: 
      printk("charmem_ioctl: returning last write time delta, exiting...\n"); 
      up(&dev->sem); 
      return dev->last_write_delta.tv_nsec; 
      break; 

     case IOCTL_RESET_READ: /*return read-pointer to the start of buffer*/ 
      dev->rp = dev->buffer; 
      break; 
     case IOCTL_RESET_WRITE: /*return write-pointer to the start of buffer*/ 
      dev->wp = dev->buffer; 
      break; 
     case IOCTL_LOAD_BUFFER_TO_CACHE: 
      load_buffer_to_cache(dev->buffer, dev->buffer_size); 
      break; 
     default: 
      printk("charmem_ioctl: invalid ioctl command, exiting...\n"); 
      up(&dev->sem); 
      return -EFAULT; 
    } 

    up(&dev->sem); 
    return 0; 
} 

struct file_operations charmem_fops = { 
    .owner = THIS_MODULE, 
    .llseek = no_llseek, 
    .read = charmem_read, 
    .write = charmem_write, 
    .unlocked_ioctl = charmem_ioctl, 
    .open = charmem_open, 
    .release = charmem_release, 
}; 

main.c,測試我的字符設備用戶程序:

int fd = 0, ret = 0; 
fd = open("/dev/charmem0", O_RDWR); 
if (fd < 0) { 
    printf("/dev/charmem0 unable to access (fd = %d)... EXITING\n", fd); 
    return -1; 
} 

ret = write(fd,msg1,10); 
ret = read(fd,user_buffer,10); 
read_delta = ioctl(fd, IOCTL_GET_LAST_READ_TIME); 
printf("read_delta : %d\n ", read_delta); 
write_delta = ioctl(fd, IOCTL_GET_LAST_WRITE_TIME); 
printf("write_delta : %d\n ", write_delta); 

main.c是測試我的炭設備中的程序;程序在打印出read_delta值後會阻止,並且我假定它在ioctl上阻塞。我在代碼中做錯了什麼?

+0

是什麼讓你覺得什麼是錯的(注:?你不應該返回EFAULT,但在ENOTTY默認情況下)。 – 2012-02-24 07:53:48

+0

你怎麼在內核日誌中看到,當你運行你的計劃嗎?當你的用戶空間程序被阻止,這是什麼的/ proc/ /堆棧顯示(其中「」被阻塞的PID號替換使用您的ioctl) – Roland 2012-02-25 06:01:33

+0

過程?你在dmesg的看見了什麼?你能CTRL-C,當它殺塊的程序? – utopiabound 2012-03-15 13:17:42

回答

1

我沒有看到你的代碼信號量的上升/下降的任何問題。您的程序阻止的最可能的地方是調用down_interruptible()。如果按下control-c,則會強制down_interruptible返回,並且您應該在dmesg或控制檯或系統日誌中看到「我已啓動」的printk。接下來的任務是弄明白驅動程序中的其他東西是否擁有該信號量。這發生在我

另外一個想法... printf的緩衝。因此,它可能是您的GET_LAST_WRITE_TIME IOCTL真的回來了,並且輸出在標準輸出緩衝區,你的程序實際上是停留在一些代碼進一步下跌。推薦的printf之後加入fflush(標準輸出)(「寫三角洲......消除這種可能性

邁克爾

相關問題