2012-02-24 11 views
0

私はドライバ開発の初心者です。ioctlを持つシンプルなcharドライバを作成しようとしています。これは、ユーザプロセスがcharドライバが最後に読み込んだ時間書きます。 Linux Charドライバ: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 - ユーザーの私のchar型のデバイスをテストするプログラム:

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は私のchar型のデバイスをテストするプログラムです。プログラムはブロックread_deltaの値を出力した後でブロックし、ioctlをブロックすると仮定しています。私のコードで何が間違っていますか?

+0

あなたは何かが間違っていると思わせる(NB:。?あなたはEFAULTを返すべきではありませんが、中にENOTTY ) –

+0

あなたのプログラムを実行するときにカーネルログには何が表示されますか?ユーザー空間プログラムがブロックされているとき、/ proc//stackが何を表示しますか?(ここでは ""あなたのioctlを使ったプロセス)? – Roland

+0

dmesgで何を見ていますか?ブロックするとCtrl + Cでプログラムを終了できますか? – utopiabound

答えて

1

コード内のセマフォのアップ/ダウンには何の問題もありません。プログラムがブロックしている可能性が最も高い場所は、down_interruptible()の呼び出しです。 control-cを押すと、down_interruptibleが強制的に復帰し、dmesgやコンソールやsyslogに「私は起動しました」というプリントが表示されます。次に、あなたのドライバーの他のものがそのセマフォを持っているかどうかを調べる作業です。

私に起こっているもう1つの考え方... printfはバッファされています。したがって、GET_LAST_WRITE_TIME ioctlが返され、出力がstdoutバッファーにあり、実際にプログラムがいくつかのコードでさらに停止している可能性があります。 「ライト・デルタ...この可能性を排除する(printfの後にfflush(標準出力)を追加することをお勧めします

マイケル

関連する問題