2011-09-09 22 views
12

我正在研究Linux Device Drivers, 3rd edition的第3.5章。本節介紹檢索我們在open函數定義自己從struct inode *inode自定義結構的方法:在Linux設備驅動程序編程中使用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;   
} 

從我的理解,該裝置被打開時,表示設備的struct inode *inode傳遞給scull_open。然後,自定義結構dev被提取出來並傳遞給filp->private_data這樣其他的方法,如scull_read可以使用它:

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_setup_cdevhere初始化過程中有一個struct scull_dev *dev

我,因爲我認爲我們可以struct scull_dev *dev一個全局變量,然後scull_read等方法,最終將有機會獲得它,而無需通過使用inodefile的所有傳球會比較混亂。

我的問題是,爲什麼我們不把它變成一個全局變量?

任何人都可以提供一些使用這種方法來傳遞數據的實際例子嗎?

+4

讓這個問題/答案是一個教訓,你爲什麼全局變量是不好的,不應該被除非有沒有其他方式使用。 –

+0

是的,但在教授作者時必須說明爲什麼以及特定功能的用途。 – mrigendra

回答

8

線程安全!如果兩個線程/進程同時使用該驅動程序會怎麼樣?

+1

即使線程在不同的單線程進程中。 (大多數人會天真地稱之爲「進程」而不是「線程」。) –

+1

謝謝,但我仍然有一些疑問。假設我有一個簡單的用戶程序(讓我們稱之爲'open_device.c')通過像open(),read(),write()等系統調用與我的驅動進行通信。我很確定,在一次只能使用**一個**'open_device.c'來訪問我的驅動程序,我是否仍然需要關心線程安全問題?只有當我使用** two **或** more **'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

我不認爲這是一個thead安全問題。它更像是一個設計選擇。如果我沒有弄錯,通過在scull_dev中記錄信號量來實現線程安全。如果你深入代碼,你可以看到打開,讀,寫所有使用down_interruptible()。

我想作者1)認爲直接訪問scull_dev看起來不太好2)想告訴我們如何使用private_data。通過將指向scull_dev的指針發送給每個操作的struct文件,每個操作都可以在不使用全局變量的情況下訪問它。

10

主要原因是讓您的驅動程序可以管理多個設備。例如,您可以創建(mknod)多個設備/dev/scull1,/dev/scull2,/dev/scull3 ...,然後這些設備中的每一個將與其關聯的不同scull_dev

對於全局變量,您僅​​限於一個。即使你的驅動程序只支持一個這樣的設備,沒有理由不設計代碼的未來證明。

0

scull驅動程序由4個未成年人實現,每個成員都有一個單獨的scull_dev,每個scull_dev都嵌入了「struct cdev」。現在讓我們說用戶已經從/ dev/scull0打開了scull0。在open()函數中,您需要指向正確的scull_dev結構。 scull_dev結構是動態分配的。

你可以看到全面落實這裏 https://github.com/mharsch/ldd3-samples/blob/master/scull/main.c#L450

相關問題