基于PCI Express總線(xiàn)的雷達數據記錄器驅動(dòng)程序開(kāi)發(fā)
AddDevice是WDM驅動(dòng)程序另一個(gè)入口函數,當DriverEntry初始化成功后,PnP管理器會(huì )調用AddDevice創(chuàng )建一個(gè)FDO,然后把總線(xiàn)驅動(dòng)程序創(chuàng )建的PDO連接到FDO上,同時(shí)還會(huì )創(chuàng )建一個(gè)設備擴展對象。本文在設備擴展對象中保存了DMA緩存地址、設備寄存器地址和一些標志位。AddDevice還寄存了一個(gè)設備接口,以便應用程序打開(kāi)設備。
接著(zhù),PnP管理器向驅動(dòng)程序堆棧發(fā)送一個(gè)PnP啟動(dòng)消息,它是一個(gè)主功能代碼為IRP_MN_START_DEVICE的IRP。驅動(dòng)程序并不處理該IRP,只是將它傳遞給總線(xiàn)驅動(dòng)程序處理并等待該IRP的處理結果,總線(xiàn)驅動(dòng)程序將獲得的設備資源(中斷、DMA通道、內存和I/O資源等)保存在IRP中并通知驅動(dòng)程序取出這些信息保存在設備擴展對象中。于是,驅動(dòng)程序就可以根據這些信息對PEX8311進(jìn)行操作了。
4.2 數據傳輸初始化
數據傳輸初始化是在DispatchIoControl派遣例程中實(shí)現的。功能驅動(dòng)程序正常裝入后,應用程序就可以發(fā)出DeviceIoControl請求初始化數據傳輸。初始化包括接收用戶(hù)程序傳來(lái)的事件句柄、分配DMA緩存、設置中斷寄存器。
驅動(dòng)程序采用事件方式與應用程序進(jìn)行通信。應用程序中用CreateEvent創(chuàng )建事件hEvent,再調用DeviceIoControl函數將它傳給驅動(dòng)程序,驅動(dòng)程序響應該請求,從輸入緩沖區中取出這個(gè)事件句柄存在設備擴展對象中。當驅動(dòng)程序將該事件設置為信號狀態(tài)時(shí),應用程序就可以得到通知。
驅動(dòng)程序通過(guò)函數AllocateCommonBuffer分配的一段非分頁(yè)、連續的DMA緩存,用于緩存從PEX8311傳來(lái)的雷達數據。為了使應用程序能夠直接訪(fǎng)問(wèn)DMA緩存,本文通過(guò)函數MmMapLockedPages把這段內存映射到應用程序。每次DMA讀取512KB數據,本文分配了60段512KB的連續DMA緩存,驅動(dòng)程序依次將每次讀取的數據存在這些連續的緩存中,而應用程序按相同的順序取出數據存在SCSI硬盤(pán)上。即使應用程序在下次LINT#中斷到來(lái)時(shí)還沒(méi)及時(shí)將緩存中數據寫(xiě)到SCSI硬盤(pán)上,驅動(dòng)程序也會(huì )啟動(dòng)DMA將新數據存在下一段緩存中,不會(huì )丟失數據。
驅動(dòng)程序設置PEX8311的中斷寄存器,允許LINT#中斷和PCI中斷。允許LINT#中斷可以使LINT#信號處于可用狀態(tài),而允許PCI中斷可以將LINT#中斷和DMA中斷路由到計算機系統,操作系統就能調用中斷服務(wù)程序響應中斷。
4.3 數據傳輸模塊
數據傳輸模塊主要包括中斷服務(wù)例程(ISR)和DPC例程(DpcForIrq)。前者響應LINT#中斷和DMA中斷,后者啟動(dòng)DMA傳輸并在數據傳完后通知應用程序讀取DMA緩存中的數據。因為ISR運行于較高的硬件中斷級別[5](DISPATCH_LEVEL),它會(huì )阻塞所有的進(jìn)程,而DpcForIrq運行在軟件中斷級別,不會(huì )阻塞所有進(jìn)程,所以應該盡量減少I(mǎi)SR的運行時(shí)間,而在DpcForIrq中完成耗時(shí)的操作。本文在ISR中只判斷中斷類(lèi)型,ISR的流程如圖3所示:

圖3 ISR流程圖
在調試中發(fā)現:當PEX8311的LINT#中斷信號有效時(shí)間超過(guò)8us時(shí),會(huì )造成死機。但系統繁忙時(shí),計算機會(huì )因為中斷有效時(shí)間太短而響應不了中斷。為解決這一問(wèn)題,使LINT#的有效時(shí)間加長(cháng)到32us,驅動(dòng)程序在剛進(jìn)入ISR時(shí),先禁止PCI中斷,LINT#中斷便不能傳到計算機系統,也就不會(huì )造成死機,ISR也有足夠的時(shí)間讀中斷寄存器的值進(jìn)行判斷。
數據傳輸初始化工作完成后,當有LINT#中斷時(shí),系統調用ISR。ISR中先判斷是LINT#中斷,于是將標志m_LINT設置為true,接著(zhù)調用IoRequestDpc ()將一個(gè)DPC對象放入DPC隊列中,最后,中斷服務(wù)程序退出。
然后,系統取出DPC對象,在DISPATCH_LEVEL的級別下執行DpcForIrq。因為m_LINT為true,說(shuō)明是FIFO存滿(mǎn)數據,DpcForIrq設置DMA參數并啟動(dòng)DMA讀數據。然后DpcForIrq退出。當PEX8311完成DMA傳輸后會(huì )產(chǎn)生DMA中斷,中斷服務(wù)程序按相同的方式執行,此時(shí)m_LINT被設置為false,說(shuō)明是PEX8311完成DMA傳輸而產(chǎn)生的DMA中斷,驅動(dòng)程序在DpcFor_Irq中用事件通知應用程序讀取DMA緩存中的數據寫(xiě)到SCSI硬盤(pán)上。如果應用程序不退出,驅動(dòng)程序會(huì )一直按上述方式循環(huán)運行。當應用程序退出時(shí),驅動(dòng)程序關(guān)閉中斷并釋放DMA緩存。
4.4 驅動(dòng)程序調試
本文采用Microsoft隨DDK一起發(fā)布的調試工具WinDbg調試驅動(dòng)程序。WinDbg是一種內核模式和用戶(hù)模式調試器,可以用來(lái)分析故障轉儲文件和執行驅動(dòng)程序代碼。調試需要兩臺計算機:目標機(雷達數據記錄器)和主機(運行Windbg的機器),它們用串口線(xiàn)連接,主機控制和監視目標機上的活動(dòng)。設置好主機和目標機后,通過(guò)WinDbg的命令窗口可以設置斷點(diǎn)、觀(guān)察調試輸出信息或分析目標機藍屏后產(chǎn)生的故障轉儲文件。
測試時(shí):外部中斷頻率可以提高到200Hz以上,每次中斷讀取512KB數據。通過(guò)分析,測試數據完全正確。經(jīng)反復測試,記錄器穩定記錄速度可達100MB/S以上。
由于只采用了兩個(gè)SCSI硬盤(pán)以及系統運行效率的限制,數據記錄速度沒(méi)有達到PEX8311的理論傳輸速度。若增加SCSI硬盤(pán)數量和升級硬件,記錄速度還有很大提升空間。
5 總結
本文詳細的介紹了基于PCI Express總線(xiàn)的雷達數據記錄器驅動(dòng)程序的開(kāi)發(fā)。本文創(chuàng )新點(diǎn)為:針對雷達數據記錄器和PEX8311的特點(diǎn)設計了高效的驅動(dòng)程序,它具有易操作、移植性強的優(yōu)點(diǎn)。該驅動(dòng)程序已成功地應用于某雷達原始數據記錄器中。 合成孔徑雷達相關(guān)文章:合成孔徑雷達原理
評論