《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 業(yè)界動(dòng)態(tài) > Windows9x/NT及2000下中斷驅(qū)動(dòng)程序的統(tǒng)一化處理

Windows9x/NT及2000下中斷驅(qū)動(dòng)程序的統(tǒng)一化處理

2009-05-06
作者:楊 波 張玘 戴 路 李 劍

  摘? 要: 針對(duì)Windows9x/NT及Windows2000操作系統(tǒng),,利用Windriver工具包,,實(shí)現(xiàn)了在多種操作系統(tǒng)下對(duì)硬件中斷驅(qū)動(dòng)程序進(jìn)行統(tǒng)一化處理,保證了程序在不同的操作系統(tǒng)下良好的移植性和兼容性,,并給出了用C語(yǔ)言編寫的程序?qū)嵗?/P>

  關(guān)鍵詞: Windows9x/NT/2000? 虛擬設(shè)備驅(qū)動(dòng)程序(VxD)? Windriver工具包? 中斷驅(qū)動(dòng)程序的統(tǒng)一化處理

?

  Windows以其友好的圖形用戶界面,,使得它不僅成為辦公管理首選的操作系統(tǒng),也日益受到工程技術(shù)人員的關(guān)注,逐漸取代DOS而成為主流的工程應(yīng)用控制平臺(tái),。但是,,Windows系統(tǒng)為了保證平臺(tái)的安全與完整性,對(duì)系統(tǒng)底層操作采取了屏蔽的策略,,利用VxD將用戶與硬件隔離開來(lái),。 在Windows9x(95、97,、98)下,,用戶如果需要實(shí)現(xiàn)對(duì)硬件的中斷、DMA或存儲(chǔ)空間物理地址等資源進(jìn)行訪問(wèn),,必須通過(guò)設(shè)備驅(qū)動(dòng)程序來(lái)進(jìn)行硬件操作;而在WindowsNT下,,即使是簡(jiǎn)單的I/O操作,也需要編寫驅(qū)動(dòng)程序方能與硬件打交道,。

  Windows操作系統(tǒng)的主流目前是Windows9x和WindowsNT,,而已經(jīng)推出的Windows2000是以WindowsNT為主要框架的。由于Windows9x和WindowsNT兩者在系統(tǒng)核心上有質(zhì)的不同,,所以即使對(duì)于同樣一個(gè)硬件,,在兩者下的驅(qū)動(dòng)程序也有很大的區(qū)別。因此,,一般而言,,需要針對(duì)不同的操作系統(tǒng)編寫不同的驅(qū)動(dòng)程序。

  兼容X86指令的微機(jī)CPU運(yùn)行時(shí)有4個(gè)優(yōu)先級(jí),,Ring0~Ring3,。操作系統(tǒng)與驅(qū)動(dòng)程序運(yùn)行在Ring0級(jí),可以對(duì)所有硬件資源進(jìn)行控制;用戶程序運(yùn)行在Ring3級(jí),,對(duì)資源控制受到一些限制,。而對(duì)于Ring0級(jí)的驅(qū)動(dòng)程序而言,它的編寫和調(diào)試通常需要對(duì)操作平臺(tái)的運(yùn)行機(jī)制有較深的了解,,從而要求程序開發(fā)者掌握Windows9x,、NT及Windows2000的內(nèi)核管理機(jī)制,對(duì)于開發(fā)人員來(lái)講這有相當(dāng)大的難度,。 在這里,,筆者使用了美國(guó)Jungo公司出品的WinDriver工具包,利用其繞過(guò)了對(duì)操作系統(tǒng)內(nèi)核的學(xué)習(xí)掌握這個(gè)難點(diǎn),,并且在不更改程序代碼的前提下,,完成了在多個(gè)操作系統(tǒng)下對(duì)硬件中斷的一致處理,很方便地解決了硬件與程序在不同系統(tǒng)下的移植問(wèn)題,。

1 Windows下硬件中斷的管理機(jī)制

  在多任務(wù)的環(huán)境里,,硬件設(shè)備中斷管理程序是非常重要的系統(tǒng)級(jí)程序。它不僅要把硬件發(fā)生的中斷時(shí)間傳給相應(yīng)的驅(qū)動(dòng)程序,還要允許某些設(shè)備驅(qū)動(dòng)程序處理它們特殊的中斷服務(wù),。在Windows平臺(tái)下,,VPICD(虛擬可編程中斷控制器)就是這樣的硬件設(shè)備管理程序,,它負(fù)責(zé)管理所有的硬件中斷時(shí)間,。VPICD通過(guò)一個(gè)缺省機(jī)制觸發(fā)駐留在VM(虛擬機(jī))內(nèi)的中斷處理函數(shù)。它完全允許VxD根據(jù)其需要而重載中斷處理函數(shù),。PC機(jī)的硬件中斷需要確定硬件中斷的IRQS(中斷申請(qǐng)?zhí)?,,對(duì)一個(gè)特定的IRQ中斷源,VPICD或提供缺省的中斷處理函數(shù),,或允許其它VxD重載中斷處理函數(shù),。

  VPICD提供的缺省中斷處理是:首先置中斷禁止,再觸發(fā)相應(yīng)VM中的中斷處理函數(shù),。因?yàn)閂PICD實(shí)現(xiàn)了對(duì)PPIC(物理可編程中斷控制器,,如8259中斷控制器)的虛擬化,所以當(dāng)VM中的中斷處理函數(shù)發(fā)送EOI(中斷處理結(jié)束指令)時(shí),,VPICD即對(duì)PPIC發(fā)EOI指令,。最后,VPICD控制處理函數(shù)的返回操作,,恢復(fù)中斷,,并置VM狀態(tài)為VM進(jìn)入中斷前的狀態(tài)。當(dāng)VPICD對(duì)某些中斷的缺省處理不夠充分或則不太合適時(shí),,就需要親手編寫一個(gè)VxD,,在其中實(shí)現(xiàn)中斷的虛擬化。VxD將決定如何處理硬件中斷以及如何調(diào)用VM中的中斷處理函數(shù),。

  下面將要詳述的WinDriver對(duì)中斷處理作了很好的封裝,,將對(duì)VPICD和VM的控制和處理以及某些特殊的驅(qū)動(dòng)要求封裝在經(jīng)過(guò)嚴(yán)格調(diào)試的WinDriver.vxd和WinDriver.sys中,并對(duì)調(diào)用驅(qū)動(dòng)程序的API(應(yīng)用編程接口)函數(shù)進(jìn)行了系統(tǒng)集成,,讓使用者直接面對(duì)用高級(jí)語(yǔ)言集成好的類庫(kù)和函數(shù)接口,,從而大大降低了程序開發(fā)的難度,縮短了開發(fā)周期,。

2 WinDriver工具包簡(jiǎn)介

  WinDriver是美國(guó)Jungo公司出品的用于編寫驅(qū)動(dòng)程序的一種工具包,,主要針對(duì)ISA/PCI插卡,4.2版本以后還提供了USB的開發(fā)工具,。最新版本4.40版所編寫的程序兼容性十分強(qiáng)大,,包括了Windows9x、Windows NT,、Windows2000,、Windows CE、Linux、Solaris(Intel),、VxWorks (Intel) ,、OS/2等諸多操作平臺(tái)。WinDriver主要包括一個(gè)WinDriverWizard,、一個(gè)WinDriver發(fā)行包,、多個(gè)公用程序以及大量的例程。

  (1)WinDriverWizard

  這是一個(gè)友好的Windows向?qū)Ы缑?。運(yùn)行WinDriverWizard,,它可以讓你立即接觸到硬件而不用寫一句有關(guān)的代碼。這種便利來(lái)自于它的自動(dòng)檢測(cè)功能,。對(duì)于ISA插卡,,用戶可以直接利用它來(lái)讀寫卡上的內(nèi)存、I/O地址,、寄存器以及偵聽中斷,。對(duì)于PCI插卡,除了上面的基本功能外,,還可以方便地讀寫PCI的配置信息,。

  在此之后,通過(guò)選擇“GenerateCode”選項(xiàng),,WinDriverWizard會(huì)為你的插卡產(chǎn)生基本的程序代碼,。4.2版本以后還提供了多種編程語(yǔ)言選擇,幾乎包括了所有流行的編程語(yǔ)言,,如VC4?觸VC6,、Borland C++Builder3?觸4、Pascal,、Delphi,、Linuxmake、Solariesmake等等,。這就讓用戶不必去學(xué)新的編程語(yǔ)言,,很容易地直接上手。

  (2)公用程序

  WinDriver提供了pci_scan,、pci_dump,、pci_diag、isapnp_scan,、wdreg,、wddebug等多個(gè)公用程序。pci_scan可以給出安裝的PCI卡及系統(tǒng)為它們分配資源的列表;pci_dump則負(fù)責(zé)得到已安裝的PCI卡的系統(tǒng)配置信息;pci_diag兼有兩者功能;isapnp_scan為用戶指出了即插即用的ISA插卡的有關(guān)信息;wdreg為用戶提供了修改注冊(cè)表的工具,,可以用來(lái)方便地安裝用戶編寫的程序;wddebug則是一個(gè)用于調(diào)試用戶程序的有效工具,。

  (3)大量例程

  WinDriver提供了許多例程,,使用者可以利用它們來(lái)產(chǎn)生自己驅(qū)動(dòng)程序的基本框架。與此同時(shí),,在WinDriver提供的在線幫助里,,可以查到許多WinDriver封裝好的功能函數(shù)。這些函數(shù)能夠方便地實(shí)現(xiàn)中斷處理,、DMA傳輸,、I/O操作、內(nèi)存映射以及即插即用等功能,。而且對(duì)于常用的PCI橋芯片,,如PLX9050,、PLX9060,、PLX9080、AMCC5923,、AMCC5933,、V3、ALTERA,、GT64等等,,提供了特定的檢測(cè)程序和相應(yīng)的API函數(shù),大大減輕了用戶的編程難度,。

3 WinDriver的驅(qū)動(dòng)程序編程模式原理

  WinDriver編程有兩種模式,。一種模式是用戶模式,這種模式實(shí)際上不是讓用戶來(lái)編驅(qū)動(dòng)程序,,而是利用軟件自身提供的驅(qū)動(dòng)程序Windrvr.vxd和Windrvr.sys,,用戶所面對(duì)的只是驅(qū)動(dòng)程序給出的相應(yīng)功能接口;即使是這個(gè)接口,也用高級(jí)語(yǔ)言進(jìn)行了很好的封裝,,使用十分容易,。另一種模式是“核心插入”模式用KernelPlugIn方式進(jìn)行編程,形成.vxd和.sys文件,,這是真正意義上的驅(qū)動(dòng)程序,。當(dāng)用戶有特殊的速度要求時(shí),后者是較好的方式,。這種方式最快,,據(jù)Jungo公司的評(píng)測(cè)報(bào)告中講,可以在一秒鐘內(nèi)處理100,,000次中斷,,筆者在硬件中嘗試了一下10,000次中斷/秒,,獲得了成功,。

  對(duì)于對(duì)操作系統(tǒng)內(nèi)核了解不多的開發(fā)者,,用戶模式無(wú)疑是非常值得推薦的。本文重點(diǎn)即是放在這方面,。使用用戶模式,,這里要特別注意以下幾個(gè)功能函數(shù):

  (1) WD_Open()——獲得驅(qū)動(dòng)程序(指Windrvr.vxd或Windrvr.sys)的句柄,它實(shí)際上是調(diào)用了CreateFile()API函數(shù),,在程序開始時(shí)必須調(diào)用;

  (2) WD_Close()——釋放驅(qū)動(dòng)程序的句柄,,它實(shí)際上是調(diào)用了CloseHandle()API函數(shù),在程序結(jié)束時(shí)必須調(diào)用;

  (3) WD_CardRegister()——負(fù)責(zé)插卡登記項(xiàng)目的建立和資源分配,,資源包括I/O操作,、內(nèi)存分配、中斷處理等,。它調(diào)用了DeviceIOControl()API函數(shù);

  (4) WD_CardUnRegister()——負(fù)責(zé)插卡登記項(xiàng)目的刪除和資源釋放,,與前者相對(duì)應(yīng),也調(diào)用了DeviceIOControl()API函數(shù);

  (5) InterruptThreadEnable()-中斷使能,,使能后可以接收中斷信號(hào),,調(diào)用Interrupt_handler()函數(shù)對(duì)中斷進(jìn)行相應(yīng)處理。在其中集成了CreateThread()API函數(shù);

  (6) Interrupt_handler()-中斷處理函數(shù),,開發(fā)者在這里加入自己對(duì)硬件的控制代碼,。

  (7) InterruptThreadDisable()-使中斷無(wú)效的函數(shù),屏蔽掉中斷信號(hào),,不再對(duì)其進(jìn)行處理,。在其中集成了WaitForSingleObject()和CloseHandle()這兩個(gè)API函數(shù)。

4 具體示例

  下面給出一個(gè)用戶模式的具體示例,。用VisualC++6編譯調(diào)試通過(guò),,在Windows9x和WindowsNT下系統(tǒng)運(yùn)行良好,在Windows2000下也能夠穩(wěn)定運(yùn)行,。windrvr.h和windrvr.vxd,、windrvr.sys由軟件提供,這里就不詳述,。對(duì)于Windows9x系統(tǒng),,注意將windrvr.vxd拷貝到C:WindowsSystemVmm32目錄下;對(duì)于WindowsNT系統(tǒng),注意將windrvr.sys拷貝到C:WINNTSystem32DRIVERS目錄下,。Listen_Interupt.C程序框架如下,,該程序?qū)崿F(xiàn)了中斷12的截獲:

  Listen_Interupt.c源程序

?

  //應(yīng)包含的頭文件

  #include ″../../include/windrvr.h″

  #include ″../../include/windrvr_int_thread.h″

  #include

  //設(shè)置自己的中斷號(hào),這個(gè)例子為中斷12

  enum {MY_IRQ=12},;

  //建立全局的WinDriver句柄

  HANDLE hWD,;

  //建立中斷結(jié)構(gòu)

  WD_INTERRUPT Intrp;

  Static char line[256],;

  //中斷處理過(guò)程,,你可以用pData來(lái)傳遞從InterruptThreadEnable()得來(lái)的信息

??? VOID interrupt_handler(PVOID pData)

  {

?????? //在這里加入你要做的中斷處理代碼

?????? printf(″截獲中斷的數(shù)目為%dn″,,Intrp.dwCounter);

  }

  //主函數(shù)

  int main()

  {

?????? WD_CARD_REGISTER cardReg,;//建立插卡登記項(xiàng)目的一個(gè)實(shí)例

?????? WD_VERSION verBuf,;

?????? hWD=WD_Open();//獲得驅(qū)動(dòng)程序的句柄

  if(hWD==INVALID_HANDLE_VALUE)

  {

?????? printf(″打開WINDRVR出現(xiàn)錯(cuò)誤!n″),;

?????? return0,;

  }

  BZERO(verBuf);?

  WD_Version(hWD,,&verBuf),;?

  if(verBuf.dwVer

  {

?????? printf(″WINDRVR版本不正確,這里需要的版本為:%dn″,,WD_VER),;

?????? return0;

  }

  //初始化cardReg,,這是程序的重要部分

  BZERO(cardReg),;

  cardReg.Card.dwItems=1,;

  cardReg.Card.Item[0].item=ITEM_INTERRUPT,;

  cardReg.Card.Item[0].fNotSharable=True;

  cardReg.Card.Item[0].I.Int.dwInterrupt=MY_IRQ,;

  cardReg.Card.Item[0].I.Int.dwOptions=1,;

  cardReg.fCheckLockOnly=True;

  WD_CardRegister(hWD,,&cardReg),;

  if(cardReg.hCard==0)

  {

????????????? printf(″無(wú)法鎖定設(shè)備!″);

  }

  else

  {

????????????? HANDLE thread_handle,;

????????????? BZERO(Intrp),;

????????????? Intrp.hInterrupt=cardReg.Card.Item[0].I.Int.hInterrupt;

????????????? Intrp.Cmd=NULL,;

????????????? Intrp.dwCmds=0,;

????????????? Intrp.dwOptions=0;

????????????? printf(″開始中斷線程n″),;

????????????? //這里調(diào)用WD_IntEnable(),,并且建立一個(gè)中斷處理的線程

????????????? if(!InterruptThreadEnable(&thread_handle,hWD,,&Intrp,,&interrupt_handler,NULL))

????????????? {

???????????????????? printf(″中斷使能失敗!n″),;

????????????? }

????????????? else

????????????? {

???????????????????? //callyourdrivercodehere

??????????????????????????? printf(″敲回車鍵不再進(jìn)行中斷截獲n″),;

???????????????????? gets(line),;

???????????????????? //這里調(diào)用禁止截獲中斷的函數(shù):WD_IntDisable()

???????????????????? InterruptThreadDisable(&thread_handle);

???????????????????? }

???????????????????? //釋放所登記的資源

???????????????????? WD_CardUnregister(hWD,,&cardReg),;

???????????????????? }

???????????????????? //刪除驅(qū)動(dòng)程序的句柄。

???????????????????? WD_Close(hWD),;

???????????????????? return0,;

  }

  按照本文給出的技術(shù)方案,掌握必要的Windows編程技術(shù),,即可以成功地實(shí)現(xiàn)Windows環(huán)境下對(duì)硬件中斷的直接控制,,很方便地在不同系統(tǒng)下進(jìn)行移植。實(shí)踐證明,,這種方法是切實(shí)可行,,行之有效的。

?

參考文獻(xiàn)

1 張玘,,楊 波,,戴 路.Windows9x、NT及Windows2000下對(duì)硬件的直接操作訪問(wèn).微計(jì)算機(jī)信息,,2000(5)

2 楊強(qiáng),,李堂秋.Win9x虛擬設(shè)備驅(qū)動(dòng)程序編程指南. 北京:清華大學(xué)出版社,1999(6)

3 ArtBaker著,,科欣翻譯組譯.WindowsNT設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)指南.北京:機(jī)械工業(yè)出版社,,1997

4 Wrires, Ruediger R.Asche.What's New in Windows 95 for VxD.Microsoft Developer Network Technology Group,,1995
本站內(nèi)容除特別聲明的原創(chuàng)文章之外,,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn),。轉(zhuǎn)載的所有的文章,、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有,。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者,。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,,請(qǐng)及時(shí)通過(guò)電子郵件或電話通知我們,,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失,。聯(lián)系電話:010-82306118,;郵箱:[email protected]