2012-02-24 3 views
0

저는 드라이버 개발을 처음 접했고 사용자 프로세스가 char 드라이버가 마지막으로 읽은 시간 (timespec)을 얻을 수있는 ioctl을 가진 간단한 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 내 문자 장치 테스트 사용자 프로그램 :

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

무엇을 (당신이 뭔가 잘못 생각 NB합니다 :.? 당신은 EFAULT를 반환하지해야하지만 ENOTTY에서 –

+0

프로그램을 실행할 때 커널 로그에 무엇이 나타 납니까? 사용자 공간 프로그램이 차단되면/proc//stack이 표시됩니다 (여기서 ""는 차단 된 프로그램의 PID 번호로 바뀝니다). 당신의 ioctl을 사용하는 프로세스)? – Roland

+0

dmesg에서 무엇을 보았습니까? 블록 할 때 Ctrl-C로 프로그램을 죽일 수 있습니까? – utopiabound

답변

1

코드에서 세마포의 위/아래에 아무런 문제가 나타나지 않습니다. 프로그램이 차단할 가능성이 가장 큰 장소는 down_interruptible() 호출입니다. Control-c를 누르면 down_interruptible이 강제로 반환되고 dmesg 또는 콘솔 또는 syslog에서 "부팅되었습니다"라는 인쇄물을 볼 수 있습니다. 그 다음 작업은 운전자가 그 세마포를 가지고있는 다른 것을 알아내는 것입니다.

다른 하나의 생각이 저에게 발생합니다 ... printf는 버퍼링됩니다. 따라서 GET_LAST_WRITE_TIME ioctl이 반환되고 출력이 stdout 버퍼에 있고 프로그램이 실제로 일부 코드에서 더 이상 작동하지 않을 수 있습니다. 이러한 가능성을 제거하기 위해 printf와 후 FFLUSH (표준 출력)를 추가 ("쓰기 델타을 ... 추천

마이클

관련 문제