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