2011-09-09 1 views
12

나는 Linux Device Drivers, 3rd edition의 3.5 장을 연구 중이다. 장치가 열려있는 동안 장치를 나타내는 struct inode *inodescull_open에 전달, 내 이해에서리눅스 장치 드라이버 프로그래밍에서 struct inode와 struct 파일을 사용하여 데이터를 전달하는 이유

int scull_open(struct inode *inode, struct file *filp) 
{ 
    struct scull_dev *dev; 

    dev = container_of(inode->i_cdev, struct scull_dev, cdev); 
    filp->private_data = dev; /* for other methods */ 

    } 
    return 0;   
} 

:이 부분은 우리가 open 함수에 struct inode *inode에서 자신을 정의 된 사용자 정의 구조를 검색하는 방법을 소개합니다. 그런 다음, 사용자 정의 구조 devfilp->private_data로 추출 전달 그래서 같은 scull_read 등의 다른 방법을 사용할 수 있습니다 : 우리는 이미 scull_setup_cdevhere에 초기화하는 동안 struct scull_dev *dev 있다고 실현 될 때까지

ssize_t scull_read(struct file *filp, char _ _user *buf, size_t count, 
       loff_t *f_pos) 
{ 
    struct scull_dev *dev = filp->private_data; 
    /* other codes that uses *dev */ 
} 

이 나에게 좋은 것 같다.

나는 우리가, 전역 변수 다음 scull_readstruct scull_dev *dev을 할 수 있으며, 다른 방법은 결국 inodefile를 사용하여 모든 통과를 거치지 않고 그것에 액세스 할 수 있습니다 생각 때문에 오히려 혼란 스러워요.

제 질문은 전역 변수로 바꾸는 것이 가장 좋습니다.

누구든지이 메서드를 사용하여 데이터를 전달할 수있는 몇 가지 실용적인 예를 제공 할 수 있습니까?

+4

전체 구현을 볼 수 있습니다. –

+0

그래,하지만 작가를 가르치는 동안 왜 특정 기능의 사용이 무엇인지 말해야 만한다. – mrigendra

답변

8

스레드 안전성! 두 스레드/프로세스가 드라이버를 동시에 사용한다면?

+1

서로 다른 단일 스레드 프로세스의 스레드. (대부분의 사람들은 순진하게 "스레드"가 아니라 "프로세스"라고 부릅니다.) –

+1

고마워요,하지만 저는 여전히 의심의 여지가 있습니다. 'open()','read()','write()'등과 같은 시스템 호출을 통해 드라이버와 통신 할 수있는 간단한 사용자 프로그램 (open_device.c라고 부르 자)이 있다고 가정 해 봅시다. 한 번에 ** 드라이버 하나에 ** open_device.c 만 사용하여 스레드 안전 문제를 처리해야합니까? ** 2 ** 또는 ** ** ** open_device.c를 사용하여 드라이버에 액세스하는 경우에만 스레드 안전 문제가 발생합니까? –

+1

구조체의 수명은 시스템 호출간에 지속됩니까? 그렇다면 첫 번째 파일을 닫기 전에 두 번째 파일을 열면 프로그램이 중단됩니다. –

0

개인 데이터를 사용하여 실제 장치를 저장하는 것을 피할 수 있습니다. 이는 다른 데이터를 필요로하는 개인 데이터가 필요한 경우 일반적으로 선택됩니다. 이 경우 scull_read 루틴에서 부 번호를 검색해야합니다. 그것은 다음과 같이 될 것입니다 :

ssize_t scull_read(struct file *filp, 
        char __user* buf, 
        size_t count, 
        loff_t * f_pos) { 

    int minor = MINOR(filp->f_dentry->d_inode->i_rdev); 
    printk("reading on minor number %d\n", minor); 
    /* use dev[minor] in ur code */ 
    return 0; 
} 
0

나는 그게 안전상의 문제라고 생각하지 않습니다. 그것은 더 많은 디자인 선택과 같습니다. 실수가 아니라면 scull_dev에서 세마포어를 위 아래로 이동하여 스레드 안전성을 얻습니다. 코드를 파헤 치면 사용 된 모든 down_interruptible()을 열고 읽고 쓰는 것을 볼 수 있습니다.

나는 저자 1) scull_dev 접근 직접 doesnot이 좋지 믿는다) 방법 private_data를 사용하는 방법을 우리에게 보여주고 싶은 것 같아요. 포인터가 각 연산에 ​​보내지는 구조체 파일에 scull_dev에 포인트를두면 각 연산은 전역 변수를 사용하지 않고도 액세스 할 수 있습니다.

10

주된 이유는 드라이버가 둘 이상의 장치를 관리 할 수 ​​있기 때문입니다. 예를 들어, /dev/scull2/dev/scull3이 ... 그리고 이들 각각이 다른 scull_dev는 그것과 관련된 것 (mknod) 여러 장치 /dev/scull1을 만들 수 있습니다.

전역 변수를 사용하면 1로 제한됩니다. 그리고 드라이버가 이러한 장치를 하나만 지원한다고해도 코드의 미래를 보장하지 않는 이유는 거의 없습니다.

0

스컬 드라이버 별도 scull_dev를 각각 갖는 4 개 미성년자로 구현되어 각 scull_dev "은 구조체 cdev"은 그 안에 포함 갖는다. 이제 사용자가/dev/scull0에서 scull0을 열었다 고 가정 해 봅시다. open() 함수에서 올바른 scull_dev 구조체를 가리킬 필요가 있습니다. scull_dev 구조체는 동적으로 할당됩니다.

당신은이 질문/답변이 전역 변수 나쁜와 다른 방법이없는 경우를 제외하고는 사용해서는 안됩니다 이유에서 당신에게 교훈하자 여기 https://github.com/mharsch/ldd3-samples/blob/master/scull/main.c#L450