色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ISA數(shù)據(jù)采集卡的WDM驅(qū)動(dòng)程序?qū)崿F(xiàn)

          ISA數(shù)據(jù)采集卡的WDM驅(qū)動(dòng)程序?qū)崿F(xiàn)

          作者: 時(shí)間:2006-05-07 來(lái)源:網(wǎng)絡(luò) 收藏

          摘要:ISA設(shè)計(jì)在WINOWS新的驅(qū)動(dòng)程序模型WDM(WINDOWS DRIVER MODEL)中沒(méi)有獲得很好的支持,使用WDM實(shí)現(xiàn)需要一些特殊處理。主要討論老式ISA設(shè)備的WDM驅(qū)動(dòng)程序的設(shè)計(jì)與實(shí)現(xiàn)。

          本文引用地址:http://cafeforensic.com/article/241591.htm

          關(guān)鍵詞:Windows驅(qū)動(dòng)程序模型(WDM) 工業(yè)標(biāo)準(zhǔn)結(jié)構(gòu)(ISA) 數(shù)據(jù)采集

          WDM作為微軟為WINDOWS 2000及以后版本準(zhǔn)備的新驅(qū)動(dòng)模型,它可以在WINDOWS 98及以后的操作系統(tǒng)上共享。這種具有跨平臺(tái)性的設(shè)備驅(qū)動(dòng)模型可以大大簡(jiǎn)化驅(qū)動(dòng)程序的開(kāi)發(fā)工作。WDM支持PNP(即插即用),為用戶(hù)的PNP設(shè)備驅(qū)動(dòng)完成了大量的底層工作。這也使得WDM對(duì)各種老設(shè)備,特別是那些不具有即插即用特性硬件的支持明顯的不足。在科研和工控中,最常用的數(shù)據(jù)采集卡通常都是基于PC總線(xiàn)的不能為PNP提供硬件支持的ISA設(shè)備。為這類(lèi)硬件編寫(xiě)非WDM驅(qū)動(dòng)程序只能局部支持PNP特性,而且需要做大量額外的工作如:必須檢測(cè)硬件,為硬件創(chuàng)建設(shè)備對(duì)象(用于代表硬件),配置并初始化硬件使其正常工作,這些工作非常復(fù)雜。利用WDM可以避免這些麻煩。

          1 WDM的結(jié)構(gòu)

          WDM實(shí)際上是一個(gè)編寫(xiě)驅(qū)動(dòng)程序的規(guī)范。其驅(qū)動(dòng)程序結(jié)構(gòu)的特點(diǎn)和WINDOWS程序設(shè)計(jì)的消息驅(qū)動(dòng)機(jī)制很相像,采用IRP驅(qū)動(dòng)機(jī)制。WINDOWS 98和WINDOWS 2000處理IRP的方式一樣,本質(zhì)卻完全不同。

          WINDOWS 2000主要由I/O管理器來(lái)管理驅(qū)動(dòng)程序的行為,管理的方法就是給驅(qū)動(dòng)程序發(fā)送各種IRP,同時(shí)I/O管理器還負(fù)責(zé)傳遞這個(gè)設(shè)備的用戶(hù)請(qǐng)求給驅(qū)動(dòng)程序。驅(qū)動(dòng)程序不能直接操作硬件設(shè)備,而是通過(guò)一個(gè)叫做HAL(硬件設(shè)備抽象層)的層來(lái)訪(fǎng)問(wèn)底層設(shè)備。HAL完成對(duì)各種硬件差異的屏蔽。Windows 98內(nèi)核與Windows 2000內(nèi)核有很大的差別。Windows 98操作系統(tǒng)的內(nèi)核稱(chēng)為虛擬機(jī)管理器(VMM)。虛擬設(shè)備驅(qū)動(dòng)程序(VxD)則使設(shè)備虛擬化,從而與虛擬機(jī)管理器形成虛擬機(jī)。Windows 9x的內(nèi)核不支持IRP,它通過(guò)模擬的方法支持WDM和IRP。Windows 98包含了NTKERN.VXD(VMM32.VXD)系統(tǒng)模塊,該模塊含有大量Windows NT內(nèi)核支持函數(shù)的Windows實(shí)現(xiàn)。NTKERN.VXD使用與Windows 2000相同的方式創(chuàng)建IRP并發(fā)送IRP到WDM驅(qū)動(dòng)程序。也就是說(shuō),Windows 98是使用VxD技術(shù)實(shí)現(xiàn)WDM的。盡管Windows 98和Windows 2000的內(nèi)核完全不同,但是WDM的結(jié)構(gòu)在Windows 98和2000下可以認(rèn)為是完全相同的。

          WDM驅(qū)動(dòng)程序面對(duì)的主要內(nèi)容是一系列內(nèi)核驅(qū)動(dòng)對(duì)象。這些對(duì)象包括驅(qū)動(dòng)對(duì)象、設(shè)備對(duì)象,還有一系列的資源抽象對(duì)象如中斷對(duì)象、適配器對(duì)象(處理DMA操作)、內(nèi)核模式派發(fā)器對(duì)象、控制器對(duì)象、推遲過(guò)程對(duì)象、定時(shí)器對(duì)象、設(shè)備隊(duì)列對(duì)象、回調(diào)對(duì)象等。其中驅(qū)動(dòng)對(duì)象由I/O管理器負(fù)責(zé)創(chuàng)建和管理。設(shè)備對(duì)象代表用戶(hù)需要操作的物理或者是邏輯設(shè)備。設(shè)備對(duì)象負(fù)責(zé)管理自己設(shè)備所需要的各種資源對(duì)象。這些資源對(duì)象有的代表真正的物理設(shè)備如中斷對(duì)象、適配器對(duì)象、定時(shí)器對(duì)象;有的對(duì)象則是邏輯對(duì)象,它們是操作系統(tǒng)實(shí)現(xiàn)自己的特性所必需的,如推遲過(guò)程調(diào)用就是與操作系統(tǒng)的搶占式多任務(wù)的實(shí)現(xiàn)有關(guān)。WDM驅(qū)動(dòng)程序利用IRP和這些對(duì)象完成硬件設(shè)備的抽象化,并對(duì)應(yīng)用程序提供統(tǒng)一操作接口。這就是所謂的WDM規(guī)范。

          WDM驅(qū)動(dòng)程序的結(jié)構(gòu)很簡(jiǎn)單。它的主體是一個(gè)入口函數(shù)DriverEntry。DriverEntry的第一個(gè)參數(shù)是指針,指向一個(gè)剛被初始化的驅(qū)動(dòng)程序?qū)ο?,該?duì)象代表驅(qū)動(dòng)程序。WDM驅(qū)動(dòng)程序的DriverEntry例程完成這個(gè)對(duì)象的初始化并返回。WDM驅(qū)動(dòng)程序的DriverEntry例程的主要工作是把各種函數(shù)指針填入驅(qū)動(dòng)程序?qū)ο蟆_@些指針對(duì)操作系統(tǒng)指明了驅(qū)動(dòng)程序容器中各種子例程的位置。它包括下面這些指針成員:

          ·DriverUnload指向驅(qū)動(dòng)程序的清除例程。I/O管理器會(huì)在卸載驅(qū)動(dòng)程序前調(diào)用該例程。通常WDM驅(qū)動(dòng)程序的DriverEntry例程一般不分配任何資源,所以DriverUnload例程也沒(méi)有什么清除工作要做。

          ·DriverExtension->AddDevice指向驅(qū)動(dòng)程序的AddDevice函數(shù)。AddDevice函數(shù)是WDM驅(qū)動(dòng)程序的一個(gè)特殊函數(shù),PNP管理器為每個(gè)設(shè)備實(shí)例調(diào)用該函數(shù)。它創(chuàng)建一個(gè)設(shè)備對(duì)象并把它連接到該驅(qū)動(dòng)程序的設(shè)備堆棧中。在這個(gè)函數(shù)里,設(shè)備對(duì)象被創(chuàng)建,設(shè)備需要的中斷、DMA等資源被掛接到這個(gè)設(shè)備對(duì)象上,相應(yīng)地處理函數(shù),如中斷服務(wù)例程等也被指定。

          ·DriverStartIo,如果驅(qū)動(dòng)程序使用標(biāo)準(zhǔn)的串行IRP,則必須使用這個(gè)函數(shù),使它指向驅(qū)動(dòng)程序的StarIo例程。

          ·MajorFunction是一個(gè)指針數(shù)組,它主要處理各種用戶(hù)的I/O請(qǐng)求IRP。默認(rèn)情總況下,用戶(hù)的所有I/O請(qǐng)求都會(huì)由I/O管理器返回失敗。驅(qū)動(dòng)程序?yàn)橐幚淼腎RP指定相應(yīng)的派遣函數(shù)。

          此外,還有一些重要的例程如用于處理中斷操作中斷服務(wù)例程,為了提高系統(tǒng)中斷處理效率的中斷服務(wù)推遲調(diào)用例程等。

          驅(qū)動(dòng)程序的其余部分就是前面所指定的那些例程的實(shí)現(xiàn)。

          2 為ISA設(shè)備分配資源

          雖然WDM驅(qū)動(dòng)程序可以簡(jiǎn)化很多工作,但是給ISA設(shè)備編寫(xiě)WDM驅(qū)動(dòng)程序也有困難。這個(gè)困難是ISA設(shè)備所需資源的分配問(wèn)題。根據(jù)PNP的規(guī)范,支持PNP的設(shè)備如PCI總線(xiàn)設(shè)備有相應(yīng)的寄存器標(biāo)識(shí)自己和自己可以接受的資源,如中斷、端口范圍、內(nèi)存范圍等,并且有相應(yīng)的邏輯支持配置資源。這使得操作系統(tǒng)啟動(dòng)過(guò)程中可以動(dòng)態(tài)地規(guī)劃調(diào)整各個(gè)設(shè)備的資源而不需要用戶(hù)的干預(yù)。為了使ISA設(shè)備具有這種PNP的特性, 可以通過(guò)PNP管理器和INF文件完成ISA設(shè)備的自動(dòng)資源分配。PNP管理器(PNP AMNAGER)依賴(lài)INF文件完成PNP管理。INF文件為設(shè)備、設(shè)備驅(qū)動(dòng)程序、操作系統(tǒng)的安裝過(guò)程提供信息(包括PNP MANAGER)。為了兼容非PNP設(shè)備,INF文件支持幾個(gè)命令為設(shè)備分配資源。這些信息初提供給NPN管理器,并且被PNP管理器用來(lái)與系統(tǒng)其它部分協(xié)商以完成非PNP設(shè)備的自動(dòng)資源分配。LOGCONFIG為設(shè)備制定一個(gè)可選的資源設(shè)定。還有相應(yīng)的IRQCONFIG、IOCONFIG、DMACONFIG、MEMCONFIG子命令,它們?yōu)樵O(shè)備指定具體的可選資源。語(yǔ)法如下:

          [log-config-section-name>]

          ConfigPririty=priority-value>

          [DMAConfig=dma-list>]

          [IOConfig=io-range-list]

          [IRQConfig=irq-list>]

          [MemConfig=mem-range-list>]

          其中CONFIGPRIOITY命令指定這個(gè)LOGCONFIG項(xiàng)的優(yōu)先級(jí)。其余子命令表示設(shè)備選用的硬件資源。下面是一個(gè)例子:

          [CX2590.Install]

          ……;其它命令

          LogConfig=CX2590_DMA;指定配置項(xiàng)的名稱(chēng)

          [CX2590_DMA];配置項(xiàng)的名稱(chēng)

          ConfigPriority=NORMAL;配置的優(yōu)先級(jí)

          IOConfig=4@300-3ff%3ff(3ff::);指定IO范圍

          IRQConfig=4,5,9,10,11 ;指定可選的中斷

          DMAConfig=0,1,2,3 ;指定可選的DMA

          在INF文件中加入LOGCONFIG命令可以解決ISA總線(xiàn)設(shè)備資源的自動(dòng)分配問(wèn)題,就可以為ISA總線(xiàn)設(shè)備編寫(xiě)WDM驅(qū)動(dòng)程序。

          3 一個(gè)ISA設(shè)備WDM驅(qū)動(dòng)程序的實(shí)現(xiàn)

          使用Numega公司的開(kāi)發(fā)工具DriverStudio 2.01可以大大地簡(jiǎn)化驅(qū)動(dòng)程序的開(kāi)發(fā)過(guò)程。DriverStudio開(kāi)發(fā)通用內(nèi)核模式的開(kāi)發(fā)包是DriverWorks。DriverWorks是一個(gè)面向?qū)ο蟮墓ぞ甙K庋b了比較底層的繁復(fù)操作,提供給開(kāi)發(fā)者一個(gè)簡(jiǎn)潔的界面。同時(shí),DriverWorks和Visual C++有很多的接口:DriverWorks專(zhuān)門(mén)為Visual C++提供了一個(gè)專(zhuān)門(mén)開(kāi)發(fā)WDM驅(qū)動(dòng)程序的WIZARD。在WIZARD指導(dǎo)下,開(kāi)發(fā)者可以很容易地生成一個(gè)驅(qū)動(dòng)程序的框架。開(kāi)發(fā)者要作的工作就是根據(jù)特定硬件編寫(xiě)相應(yīng)的代碼。

          WIZARD生成的框架不僅包括設(shè)定設(shè)備的資源如中斷、IO端口范圍、內(nèi)存范圍;還包括自動(dòng)生成驅(qū)動(dòng)程序與應(yīng)用程序的接口命令及處理這些命令的處理函數(shù),生成標(biāo)準(zhǔn)驅(qū)動(dòng)程序的標(biāo)準(zhǔn)驅(qū)動(dòng)程序例程;包括DriverEntry驅(qū)動(dòng)程序入口例程、UnLoad卸載例程、Dispach標(biāo)準(zhǔn)派發(fā)器例程、StartIO標(biāo)準(zhǔn)I/O傳輸例程、中斷處理例程等。對(duì)于WDM驅(qū)動(dòng)程序,包括生成驅(qū)動(dòng)程序接口(WDM專(zhuān)有),設(shè)備的符號(hào)連接,I/O傳輸方式以及WDM電源管理和處理PNP請(qǐng)求的IRP處理子程序。WIZARD完成后的代碼主要包括兩類(lèi),一類(lèi)是驅(qū)動(dòng)對(duì)象,它構(gòu)成一個(gè)驅(qū)動(dòng)程序的框架;另一類(lèi)是驅(qū)動(dòng)程序的設(shè)備對(duì)象。驅(qū)動(dòng)程序?qū)ο筘?fù)責(zé)創(chuàng)建并管理驅(qū)動(dòng)程序設(shè)備對(duì)象。設(shè)備對(duì)象負(fù)責(zé)管理硬件的各種資源如I/O、IRQ、DMA。它還負(fù)責(zé)處理各種IRP的例程。設(shè)備對(duì)象是系統(tǒng)所有I/O操作的基石,一個(gè)驅(qū)動(dòng)程序必須有一個(gè)或一個(gè)以上的設(shè)備對(duì)象才真正有意義。驅(qū)動(dòng)對(duì)象和設(shè)備對(duì)象的關(guān)系很象WINDOWS系統(tǒng)中進(jìn)程和線(xiàn)程的關(guān)系:進(jìn)程是可執(zhí)行代碼(就是線(xiàn)程)的框架。如果說(shuō)驅(qū)動(dòng)對(duì)象是WINDOWS中的進(jìn)程,那么設(shè)備對(duì)象就像進(jìn)程中的線(xiàn)程,它們完成實(shí)現(xiàn)的I/O操作。設(shè)備對(duì)象使用保護(hù)成員變量來(lái)管理設(shè)備的資源,使用成員函數(shù)來(lái)處理各種IRP請(qǐng)求,并由這些函數(shù)完成實(shí)現(xiàn)的I/O操作。

          筆者開(kāi)發(fā)的高速旋轉(zhuǎn)機(jī)械監(jiān)控與故障診斷系統(tǒng)采用的是北京大恒公司的具有FIFO(隊(duì)列形式實(shí)現(xiàn)的緩存)的8路數(shù)據(jù)采集卡AC 1810。它的特點(diǎn)是由硬件自動(dòng)完成采用操作:當(dāng)FIFO半滿(mǎn)的時(shí)候,系統(tǒng)產(chǎn)生中斷通知用戶(hù)取走數(shù)據(jù);同時(shí),硬件繼續(xù)自動(dòng)采樣FIFO的另一關(guān)。驅(qū)動(dòng)程序的主要工作包括設(shè)備I/O讀操作和中斷服務(wù)操作。下面是WIZARD生成的驅(qū)動(dòng)對(duì)換和設(shè)備對(duì)象的定義(只取主要部分):

          // 驅(qū)動(dòng)對(duì)象

          class AC_1810 : public Kdriver

          {

          SAFE_DESTRUCTORS

          public:

          virtual NTSTATUS

          DriverEntry(PUNICOE-STRING

          RegistryPath);

          //驅(qū)動(dòng)程序的入口函數(shù)

          virtual NTSTATUS

          AddDevice(PDEVICE_OBJECT Pdo);

          //完成設(shè)備對(duì)象和驅(qū)動(dòng)對(duì)象的連接

          ……

          };

          //設(shè)備對(duì)象

          class AC_1810Device : public KpnpDevice

          {

          // Constructors

          public;

          AC-1810Device(PDEVICE_OBJECT Pdo,

          ULONG Unit);//構(gòu)造函數(shù)完成資源配置

          ……

          public:

          AC_1810Device(PDEVICE_OBJECT Pdo,

          ULONG Unit);//構(gòu)造函數(shù)完成資源配置

          ……

          public:

          BOOLEAN Isr_Irq(void);// IRQ中斷服務(wù)例程

          Virtual NTSTATUS Create(KIrp I);

          //標(biāo)準(zhǔn)IRP處理函數(shù)

          virtual NTSTATUS Close(KIrp I);

          // COMMENT_ONLY

          virtual NTSTATUS Read(KIrp I);

          // COMMENT_ONLY

          virtual VOID StarIo(KIrp I);

          // 開(kāi)始I/O傳輸

          VOID CancelQueuedIrp(KIrp I);

          // 判斷傳輸IPR是否被取消

          VOID Invalidate(void);

          // 釋放資源例程

          virtual NTSTATUS DefaultPnp(KIrp I);

          // 處理默認(rèn)的PNP操作

          virtual NTSTATUS DefaultPower(KIrp I);

          // 管理電源

          void SerialRead(KIrp I);

          //完成實(shí)際的I/O操作

          NTSTATUS IOCTL_SETUP_Handler(KIrp I);

          //采樣參數(shù)設(shè)定

          NTSTATUS IOCTL_REW_Handler(KIrp I);

          // 開(kāi)始/停止采樣

          ……

          protected:

          KioRange m_IoPotrRange0

          // 管理I/O資源

          Kinterrupt m_Irq;

          // 管理中斷資源

          ……

          };

          在實(shí)際操作過(guò)程中,采用中斷讀數(shù)的方法。在驅(qū)動(dòng)程序中設(shè)置了兩個(gè)緩沖區(qū),一個(gè)前臺(tái)緩沖區(qū),一個(gè)后臺(tái)緩沖區(qū)(用作后備緩沖區(qū)),系統(tǒng)總是先使用前臺(tái)緩沖區(qū)。當(dāng)前臺(tái)緩沖區(qū)已滿(mǎn)而仍然未被讀出,系統(tǒng)觸發(fā)中斷時(shí),此時(shí)使用后臺(tái)緩沖區(qū)。讀數(shù)的方法很簡(jiǎn)單,系統(tǒng)先讀前臺(tái)緩沖區(qū)的數(shù)據(jù),只有當(dāng)前臺(tái)緩沖區(qū)未滿(mǎn)而后臺(tái)緩沖區(qū)滿(mǎn)的時(shí)候才讀后臺(tái)緩沖區(qū)。這樣可以保證采樣數(shù)據(jù)序列的時(shí)間順序。

          具體實(shí)現(xiàn)如下:

          // ISR例程,完成數(shù)據(jù)從FIFO中讀出

          BOOLEAN AC_1810Device::Isr_Irq(void)

          {

          //是否觸發(fā)不斷?未觸發(fā)則返回,判斷兩個(gè)緩沖區(qū)情況,都滿(mǎn)則返回

          ……

          // 前臺(tái)緩沖區(qū)未滿(mǎn),使用前臺(tái)緩沖區(qū)

          if(m_pBuffer->numused MAX_READ_BUF){

          for(int i=0;iBLOCK_SIZE;i++){

          m_pBuffer_>buff[m_pBuffer->numused+i]=READ_FIFO;

          }

          m_pBuffer->numused +=BLOCK_SIZE;

          }

          else

          //完成其它情況的判斷

          ……

          return TRUE;// 中斷成功返回

          }

          當(dāng)應(yīng)用程序使用標(biāo)準(zhǔn)Win32 API對(duì)設(shè)備進(jìn)行讀操作的時(shí)候,I/O管理器通知驅(qū)動(dòng)程序并觸發(fā)對(duì)Read函數(shù)的調(diào)用。對(duì)于通常的串行設(shè)備,在Read函數(shù)的最后排隊(duì)IRP請(qǐng)求,此時(shí)系統(tǒng)就可以觸發(fā)StartIO例程,并且保證這個(gè)過(guò)程是串行處理的。

          // 讀例程,處理IRP_MJ_READ

          NTSTATUS AC_1810 Device::Read(KIrp I)

          {

          // 檢查輸入的合法性

          if (I.ReadSize ()BLOCK_SIZE){

          // 不合法返回錯(cuò)誤代碼

          I.Information()=0;

          Return I.PnpComplete(this,STATUS_INVALID_PARAMETER);

          }

          // 讀0字節(jié),永遠(yuǎn)成功

          if (I.ReadSize() = =0){

          I.Information () = 0;

          return

          I.PnpComplete(this,STATUS_SUCCESS);

          }

          // 排隊(duì)這個(gè)IRP觸發(fā)StarIO,完成數(shù)據(jù)傳輸

          return QueueIrp(I,LinkTo(CancelQueuedIrp));

          }

          // StartIo例程,完成I/O操作

          VOID AC_1810 Device::StartIo(KIrp I)

          {

          // 檢測(cè)這個(gè)IRP是否被取消

          if(!I.TestAndSetCancelRoutine(LinkTo(CancelQueuedIrp),NULL,CurrentIrp()) )

          {

          return;//取消則返回

          }

          switch (I.MajorFunction()) {

          case IRP_MJ_READ:

          //這個(gè)函數(shù)按邏輯完成讀操作

          SerialRead(I);

          Breadk

          ……

          // 開(kāi)始處理下一個(gè)IRP

          PnpNextIrp(I);

          break;

          }

          }

          ISA卡的WDM驅(qū)動(dòng)程序的主體部分就完成了。它具有PNP功能,可以方便地安裝卸載。在中斷到來(lái)的時(shí)候,系統(tǒng)使用兩個(gè)緩沖區(qū)完成數(shù)據(jù)的傳輸,可以避免數(shù)據(jù)丟失。

          以上驅(qū)動(dòng)程序是使用Numega公司的DriverSutdio 2.01版,結(jié)合Visual C++ 6.0,Microsoft Windows 2000 sp1 DDk開(kāi)發(fā)調(diào)試通過(guò),并且成功地應(yīng)用到實(shí)驗(yàn)室開(kāi)發(fā)的高速旋轉(zhuǎn)機(jī)械實(shí)時(shí)狀態(tài)監(jiān)控與故障診斷系統(tǒng)中,該系統(tǒng)界面友好高度可靠。同時(shí)由于加入了PNP的支持,使得該系統(tǒng)的硬件安裝卸載非常簡(jiǎn)便。這種技術(shù)可取代傳統(tǒng)的以DOS為核心的工業(yè)用監(jiān)控與故障診斷系統(tǒng),具有廣闊的應(yīng)用前景。

          linux操作系統(tǒng)文章專(zhuān)題:linux操作系統(tǒng)詳解(linux不再難懂)

          c++相關(guān)文章:c++教程




          評(píng)論


          相關(guān)推薦

          技術(shù)專(zhuān)區(qū)

          關(guān)閉