基于嵌入式Linux系統(tǒng)設(shè)備驅(qū)動(dòng)程序的開(kāi)發(fā)
引言
Linux是一個(gè)遵循POSIX標(biāo)準(zhǔn)的免費(fèi)操作系統(tǒng)。具有BSD和SYSV的擴(kuò)展特性。與其他操作系統(tǒng)相比,嵌入式Linux系統(tǒng)以其可應(yīng)用于多種硬件平臺(tái)、內(nèi)核高效穩(wěn)定、源碼開(kāi)放、軟件豐富、網(wǎng)絡(luò)通信和文件管理機(jī)制完善等優(yōu)良特性而正被作為研究熱點(diǎn),越來(lái)越多的研究人員采用Linux平臺(tái)來(lái)開(kāi)發(fā)自己的產(chǎn)品。Linux設(shè)備驅(qū)動(dòng)程序在Linux內(nèi)核源代碼中占有很大比例,從2.0、2.2到 2.4版本的內(nèi)核,源代碼的長(zhǎng)度日益增加,其實(shí)主要是設(shè)備驅(qū)動(dòng)程序在增加。
設(shè)備驅(qū)動(dòng)程序的編寫
設(shè)備驅(qū)動(dòng)程序是linux內(nèi)核的一部分,是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口,它由一組函數(shù)和一些私有數(shù)據(jù)組成,是連接應(yīng)用程序與具體硬件的橋梁。Linux的一個(gè)基本特點(diǎn)是它對(duì)硬件設(shè)備的管理抽象化,系統(tǒng)中的每一個(gè)設(shè)備都用一個(gè)特殊的文件來(lái)表示。所有的硬件設(shè)備都像普通的文件一樣看待,使用與操作系統(tǒng)相同的標(biāo)準(zhǔn)系統(tǒng)來(lái)進(jìn)行打開(kāi)、讀寫和關(guān)閉。
在Linux 操作系統(tǒng)下有3類主要的設(shè)備文件類型:塊設(shè)備、字符設(shè)備、網(wǎng)絡(luò)設(shè)備。字符設(shè)備是指存取時(shí)沒(méi)有緩存的設(shè)備??上裎募粯釉L問(wèn)字符設(shè)備,字符設(shè)備驅(qū)動(dòng)程序負(fù)責(zé)實(shí)現(xiàn)這些行為。系統(tǒng)的控制臺(tái)和并口就是字符設(shè)備的例子,它們可以很好地用“流”來(lái)描述。塊設(shè)備是文件系統(tǒng)的宿主,如磁盤。 Linux允許像字符設(shè)備那樣讀取塊設(shè)備——允許一次傳輸任意數(shù)目的字節(jié)。結(jié)果是,字符設(shè)備和塊設(shè)備讀取數(shù)方式一致。而網(wǎng)絡(luò)設(shè)備不同于字符設(shè)備和塊設(shè)備, 它面向的上一層不是文件系統(tǒng)而是網(wǎng)絡(luò)協(xié)議層,是通過(guò)BSD套接口訪問(wèn)數(shù)據(jù)。與設(shè)備相對(duì)應(yīng)的是三類設(shè)備驅(qū)動(dòng)程序,字符設(shè)備驅(qū)動(dòng)程序、塊設(shè)備驅(qū)動(dòng)程序、網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序。
字符設(shè)備驅(qū)動(dòng)程序、塊設(shè)備驅(qū)動(dòng)程序與網(wǎng)絡(luò)設(shè)備驅(qū)動(dòng)程序的結(jié)構(gòu)體是不同的。
在linux 源代碼linux/ include / linux/ fs. h中定義了字符設(shè)備和塊設(shè)備驅(qū)動(dòng)程序中必須使用的file_operations結(jié)構(gòu),每個(gè)設(shè)備驅(qū)動(dòng)都實(shí)現(xiàn)這個(gè)接口所定義的部分或全部函數(shù)。隨著內(nèi)核的不斷升級(jí), file_operations結(jié)構(gòu)也越來(lái)越大,不同的版本的內(nèi)核會(huì)稍有不同。file_operations定義如下:
struct file_operations{
int( * lseek) ( struct inode * , struct file * , off_t , int) ; int( *release) ( struct inode * , struct file * ) ;
int( * read) ( struct inode * , struct file * , char * , int) ; int( * fsync) ( struct inode *, struct file * ) ;
int( *write) ( struct inode * , struct file * , const char *, int) ; int( * fasync) ( struct inode * , struct file *, int) ;
int( * readdir) ( struct inode , struct file , void * , dilldir) ; int( *check_media_change) ( kdev_t dev) ;
int(*select) ( struct inode *, struct file * , int, select_table * ) ; int( * revalidate) ( kdev_t dev) ; };
int ( * ioctl) ( struct inode * , struct file *, unsigned int, unsigned long) ;
int( *mmap) ( struct inode * , struct file * , struct vm_area_struct * ) ;
int( * open) ( struct inode *, struct file *) ;
應(yīng)用程序只有通過(guò)對(duì)設(shè)備文件的open、release、read、write、ioctl等才能訪問(wèn)字符設(shè)備和塊設(shè)備。用戶自己定義好 file_operations結(jié)構(gòu)后,編寫出設(shè)備實(shí)際所需要的各操作函數(shù),對(duì)于不需要的操作函數(shù)用NULL初始化,這些操作函數(shù)將被注冊(cè)到內(nèi)核,當(dāng)應(yīng)用程序?qū)υO(shè)備相應(yīng)的設(shè)備文件進(jìn)行文件操作時(shí),內(nèi)核會(huì)找到相應(yīng)的操作函數(shù),并進(jìn)行調(diào)用。如果操作函數(shù)使用NULL,操作函數(shù)就進(jìn)行默認(rèn)處理。
對(duì)于字符設(shè)備而言,llseek( ),read( ),write(),ioctl( ),open( ),release( )這些函數(shù)是不可缺的;對(duì)于塊設(shè)備,open( ),release( ),ioctl(),check_media_change( ),revalidate( )是不可缺少的。
網(wǎng)絡(luò)設(shè)備結(jié)構(gòu)體 net_device 定義在 includelinuxnetdevice.h 里,如下所示:
struct net_device
{
char name ; int (*init)(struct
net_device *dev);
unsigned short flags ; int (*open)
(struct net_device *dev);
unsigned long base_addr; int
(*stop)(struct net_device *dev)
unsigned int irq ; int
(*hard_start_xmit)(struct sk_buff *skb,
unsigned char dev_addr; struct
net_device *dev);
unsigned char addr_len; int
(*set_mac_address)( struct net_device
unsigned long trans_start; *dev,void* addr);
……
}
定義好net_device結(jié)構(gòu)體后,根據(jù)實(shí)際情況編寫操作函數(shù),其中hard_start_xmit()函數(shù)是用來(lái)發(fā)送數(shù)據(jù)的,set_mac_address()是進(jìn)行網(wǎng)絡(luò)參數(shù)設(shè)置的。
linux相關(guān)文章:linux教程
評(píng)論