基于PCI總線(xiàn)的數(shù)字衛(wèi)星解調(diào)卡驅(qū)動(dòng)程序開(kāi)發(fā)
KconnonDmaBuffer是DMA通用緩沖區(qū)對(duì)象。驅(qū)動(dòng)中,此類(lèi)可在On Start Device中由成員函數(shù)Initialize初始化。通用緩沖區(qū)是外部設(shè)備和驅(qū)動(dòng)程序之間的一段物理上連續(xù)的虛擬內(nèi)存,這個(gè)內(nèi)存是從系統(tǒng)中分配出來(lái)的,是非常珍貴的資源,任何時(shí)候都可以被他的設(shè)備和驅(qū)動(dòng)程序存取。通用緩沖區(qū)包括緩沖區(qū)空間大小、虛擬地址、邏輯地址等信息。由于通用緩沖區(qū)是非常珍貴的資源,所以它的大小也受到限制。為此,驅(qū)動(dòng)時(shí)應(yīng)對(duì)每個(gè)DMA請(qǐng)求進(jìn)行分段,并為每個(gè)段提供一個(gè)傳輸段描述符數(shù)組。而且,當(dāng)設(shè)備不支持分散/集中時(shí),這個(gè)數(shù)組中的描述符只能有一個(gè)。每個(gè)描述符包含一個(gè)物理地址和相應(yīng)的字節(jié)數(shù),其結(jié)構(gòu)如下:
其中的物理地址即邏輯地址,字節(jié)數(shù)則是相應(yīng)的邏輯地址范圍的長(zhǎng)度。
KdmaTransfer為DMA傳輸對(duì)象,用來(lái)管理內(nèi)存和設(shè)備之間的數(shù)據(jù)傳輸,但此時(shí)的DMA適配器必須可用。適配器對(duì)象可用來(lái)通知傳輸數(shù)據(jù)的類(lèi)型和使用的DMA通道等。驅(qū)動(dòng)中,此類(lèi)可在OnStart Device中由成員函數(shù)Initialize初始化。在DMA傳輸中,數(shù)據(jù)可直接傳輸?shù)较到y(tǒng)物理內(nèi)存中。管理這些內(nèi)存的方式有Common Buffer和Packet兩種。第一種方式是在物理內(nèi)存中預(yù)先開(kāi)辟一段連續(xù)的內(nèi)存空間,CPU和PCI都可以對(duì)其進(jìn)行訪(fǎng)問(wèn),且在一次DMA傳輸過(guò)程中,物理地址保持不變,該方式適合傳輸大量數(shù)據(jù)和連續(xù)的DMA傳輸;而在Packet方式中,由于其內(nèi)存物理地址不確定,因此適合間斷性的DMA傳輸。
(2)回調(diào)函數(shù)
由于DMA傳輸采用分段傳輸,所以,每當(dāng)準(zhǔn)備傳輸一個(gè)新段時(shí),KDmaTransfer的對(duì)象將通知驅(qū)動(dòng)程序調(diào)用回調(diào)例程?;卣{(diào)函數(shù)的原型由typedef DMAREADY_CALLBACK指定,使用宏DEVMEMBER_DMAREADY可聲明回調(diào)函數(shù)基類(lèi)的成員函數(shù)。通過(guò)判斷成員函數(shù)Bytes Remaining可判斷傳輸是否完成。若返回值為0,則調(diào)用成員函數(shù)Terminate以完成相應(yīng)的IRP,否則,回調(diào)函數(shù)繼續(xù)傳輸。
(3)中斷服務(wù)
本驅(qū)動(dòng)需要處理兩種中斷,第一種是本地中斷,它是當(dāng)FIFO輸出半滿(mǎn)信號(hào)時(shí)由FPGA通過(guò)LINT#信號(hào)發(fā)給PCI9054的中斷信號(hào);第二種中斷是DMA傳輸結(jié)束時(shí)由DMA中斷控制器產(chǎn)生的。這兩種中斷可以通過(guò)對(duì)DMA的中斷控制寄存器的特定位處理來(lái)區(qū)分。判斷是否是本地中斷時(shí),可以通過(guò)判斷DMA中斷控制寄存器的第15位是否為1來(lái)確定,如果INTCSR[15]=1,則為本地中斷;判斷是否是DMA中斷則可通過(guò)判斷DMA中斷控制寄存器的第23位是否為1來(lái)確定,如果INTCSR[23]=1,則為DMA中斷。不同的中斷,其處理方式不同。
3.3 驅(qū)動(dòng)程序的創(chuàng)建及安裝文件的修改
為了正確的創(chuàng)建WDM驅(qū)動(dòng)程序,首先要建立WDM編程環(huán)境,并創(chuàng)建自己的庫(kù)文件。參考文件中提供了一種WDM編程環(huán)境的建立方法,但是,按照書(shū)中的方法經(jīng)常不能成功的建立編程環(huán)境,為此,筆者根據(jù)自己的經(jīng)驗(yàn)介紹一種簡(jiǎn)單易行的方法:
(1)首先安裝DDK;
(2)在開(kāi)始菜單中選擇Compuware Driver Studio\Develop下的DDK Build Setting;
(3)在打開(kāi)的對(duì)話(huà)框中的DDK Root Directory中設(shè)置DDK的根目錄(如E:\WINDDK\2600),然后點(diǎn)擊Launch Program,并打開(kāi)Compuware DriverStudio的Driver Works文件夾中Source里的VdwLibs.dsw文件。
(4)選擇Build菜單中的Set Active Project Configuration,并在彈出的對(duì)話(huà)框中選擇合適的Project configurations。而對(duì)于現(xiàn)行的32位機(jī),它不需要像Win32 AMD64 Free等這樣的工程;
(5)選好一個(gè)工程后,點(diǎn)擊OK,然后點(diǎn)擊Build with BUILD.EXE即可生成所需的庫(kù)。然后再根據(jù)自己的需要重新選擇新的Project configurations,以進(jìn)行庫(kù)的創(chuàng)建。
筆者的這種方法在于使用DDK Build Setting的Launch Program打開(kāi)VdwILibs.dsw,編譯沒(méi)有出現(xiàn)錯(cuò)誤,書(shū)中的方法則是先打開(kāi)VC++,然后打開(kāi)VdwLibs.dsw,選擇Batch Build下的Rebuild All創(chuàng)建庫(kù),但是筆者試了幾次均不成功。
庫(kù)文件生成之后,即可打開(kāi)創(chuàng)建好的驅(qū)動(dòng)程序,并在VC++的菜單中打開(kāi)DDK Build Setting,再在DDK Root Directory中設(shè)置DDK的路徑為實(shí)際安裝的路徑,之后點(diǎn)擊Build圖標(biāo),就可以生成BPSKDRIVER.sys文件了。另外,驅(qū)動(dòng)的類(lèi)型可以自己設(shè)定,Windows系統(tǒng)定義了一系列的設(shè)備類(lèi)名和GUID,找到驅(qū)動(dòng)工程文件中后綴名為.inf的安裝文件,將其內(nèi)容修改成與硬件信息一致就可以了。然后將此文件拷貝到工程中的i386文件夾中。至此,一個(gè)完整的驅(qū)動(dòng)就創(chuàng)建成功了。
4 結(jié)束語(yǔ)
本驅(qū)動(dòng)現(xiàn)在已經(jīng)經(jīng)過(guò)測(cè)試,工作正常。并已經(jīng)應(yīng)用于數(shù)字衛(wèi)星解調(diào)卡中。WDM編程環(huán)境的創(chuàng)建具有筆者自己的見(jiàn)解,并且可以實(shí)現(xiàn)一次創(chuàng)建即成功,希望對(duì)同類(lèi)驅(qū)動(dòng)程序的開(kāi)發(fā)具有借鑒作用。
評(píng)論