Linux操作系統(tǒng)下的PCI驅(qū)動(dòng)開(kāi)發(fā)
3.2 設(shè)備的打開(kāi)及操作
通過(guò)上述步驟,系統(tǒng)內(nèi)核就可以發(fā)現(xiàn)并打開(kāi)設(shè)備了。設(shè)備打開(kāi)模塊中主要完成檢查讀寫(xiě)模式以及申請(qǐng)對(duì)設(shè)備的控制權(quán)等工作。同時(shí)可分配并填private_data數(shù)據(jù)結(jié)構(gòu)、申請(qǐng)PCI設(shè)備I/O資源的占用、申請(qǐng)中斷、注冊(cè)中斷處理程序。
Linux是以操作文件的方式來(lái)操作設(shè)備的,也就是通過(guò)系統(tǒng)定義的file_operation結(jié)構(gòu)體向Linux文件系統(tǒng)注冊(cè)一些操作設(shè)備的函數(shù)。其file_operation結(jié)構(gòu)體的定義如下:
當(dāng)應(yīng)用程序?qū)υO(shè)備文件進(jìn)行諸如open、close、read、write等操作時(shí),Linux內(nèi)核將通過(guò)file_operation結(jié)構(gòu)訪問(wèn)驅(qū)動(dòng)程序提供的函數(shù)。
簡(jiǎn)單的讀寫(xiě)任務(wù)直接用read、write函數(shù)就可以完成,而復(fù)雜的控制則需要使用ioctl函數(shù)。ioctl函數(shù)是設(shè)備驅(qū)動(dòng)程序中對(duì)設(shè)備的I/O通道進(jìn)行管理的函數(shù),可以對(duì)設(shè)備的一些特性進(jìn)行控制。因此,為實(shí)現(xiàn)對(duì)PCI設(shè)備各種I/O資源的訪問(wèn)和實(shí)現(xiàn)不同的傳輸方式,通常都需要使用ioc-tl函數(shù),驅(qū)動(dòng)程序的ioctl控制命令差不多完全是用一個(gè)switch語(yǔ)句來(lái)實(shí)現(xiàn)的,可實(shí)現(xiàn)初始化信息的初始化控制、讀寫(xiě)配置空間、讀寫(xiě)I/O端口地址空間、讀寫(xiě)I/O內(nèi)存空間、DMA傳輸?shù)榷喾N控制操作。
3.3 中斷處理
Linux將中斷處理程序分解為頂半部和底半部?jī)蓚€(gè)半部。驅(qū)動(dòng)程序在打開(kāi)設(shè)備時(shí),為系統(tǒng)安裝了中斷處理程序,當(dāng)硬件設(shè)備觸發(fā)中斷時(shí),中斷處理程序首先調(diào)用頂半部程序以判斷中斷類(lèi)型,對(duì)中斷類(lèi)型的判斷可通過(guò)訪問(wèn)PCI設(shè)備處理中斷的寄存器來(lái)實(shí)現(xiàn)。當(dāng)有中斷信號(hào)來(lái)臨時(shí),驅(qū)動(dòng)程序?qū)⒅袛嗵幚砣蝿?wù)排進(jìn)任務(wù)隊(duì)列中進(jìn)行“登記”并清除中斷標(biāo)志,這樣做的目的是占用較少的內(nèi)核時(shí)間,然后再通過(guò)調(diào)度底半部來(lái)運(yùn)行,這樣,內(nèi)核負(fù)責(zé)底半部的函數(shù)就會(huì)處理任務(wù)隊(duì)列中的中斷任務(wù)??梢哉f(shuō),底半部幾乎做了中斷處理程序所有的事情。
驅(qū)動(dòng)程序在設(shè)備驅(qū)動(dòng)對(duì)象數(shù)據(jù)結(jié)構(gòu)中為中斷處理定義了一個(gè)任務(wù)隊(duì)列Task_DpcForIsr,并將其rouTIne參數(shù)設(shè)置為負(fù)責(zé)底半部的函數(shù),data參數(shù)設(shè)置為傳遞給底半部函數(shù)的參數(shù),這樣,當(dāng)系統(tǒng)獲得中斷信號(hào)時(shí),驅(qū)動(dòng)程序就可將中斷處理任務(wù)排進(jìn)該任務(wù)隊(duì)列中,以提供給底半部應(yīng)用。
3.4 釋放設(shè)備模塊及卸載
釋放設(shè)備模塊主要負(fù)責(zé)釋放對(duì)設(shè)備的控制權(quán),同時(shí)釋放所占用的內(nèi)存和中斷等。具體來(lái)說(shuō),首先是釋放對(duì)設(shè)備的控制權(quán)。即對(duì)設(shè)備控制權(quán)的釋放,這只需簡(jiǎn)單地將控制設(shè)備控制權(quán)的信號(hào)量釋放即可。在Linux下可使用up,其調(diào)用形式是up(sem),它可遞增信號(hào)量的值,并換醒所有正在等待信號(hào)量轉(zhuǎn)為可用狀態(tài)的進(jìn)程。其次是釋放由open分配的、保存在filp->private_data中的所有內(nèi)容,將其值設(shè)為NULL。接著釋放中斷。最后釋放PCI設(shè)備I/O資源的占用權(quán)。對(duì)PCI設(shè)備的I/O端口資源而言,實(shí)現(xiàn)I/O端口資源占有權(quán)的釋放是通過(guò)release_region函數(shù)來(lái)完成的,而對(duì)于I/O內(nèi)存資源,則需要使用iounmap函數(shù)同時(shí)釋放其內(nèi)存映射。
linux操作系統(tǒng)文章專(zhuān)題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論