<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Windows98下硬件中斷驅(qū)動(dòng)程序的開發(fā)

          Windows98下硬件中斷驅(qū)動(dòng)程序的開發(fā)

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

          摘 要: 介紹了Windows98的內(nèi)核管理機(jī)制和應(yīng)用程序權(quán)限級(jí)別,簡(jiǎn)述了在Windows98下進(jìn)行虛擬驅(qū)動(dòng)程序開發(fā)的幾種工具和編程方法,并給出了借助VToolsD用C++語言編寫的處理硬件中斷的程序?qū)嵗?/p>本文引用地址:http://www.ex-cimer.com/article/241581.htm

          關(guān)鍵詞: 虛擬設(shè)備驅(qū)動(dòng)程序 VToolsD 中斷服務(wù)例程

          美國(guó)微軟公司出品的Windows98以其友好的圖形用戶界面,在我國(guó)贏得了廣泛的市場(chǎng)。在給廣大辦公環(huán)境工作人員帶來方便的同時(shí),也給不少工程技術(shù)人員帶來了一些麻煩。一些原本在DOS下很容易編出的控制硬件的程序,現(xiàn)在在Windows98下就不那么容易實(shí)現(xiàn)了。作為一個(gè)完善的操作系統(tǒng)也必須能控制硬件,象DOS那樣直接與硬件打交道是Windows98不提倡的。它需要開發(fā)專門的硬件設(shè)備驅(qū)動(dòng)程序,即通過一系列的虛擬設(shè)備驅(qū)動(dòng)程序來管理硬件,如:進(jìn)行中斷響應(yīng)、I/O端口讀寫或直接存儲(chǔ)器存?。―MA)。Windows98內(nèi)核管理機(jī)制非常復(fù)雜,因而編寫虛擬驅(qū)動(dòng)程序也變得十分困難,要想編寫虛擬驅(qū)動(dòng)程序,就必須對(duì)Windows98的內(nèi)核有所了解。

          1 Windows98的內(nèi)核管理機(jī)制

          在Windows95三年后推出的Windows98雖然擴(kuò)充了許多新的設(shè)備驅(qū)動(dòng)特性,如對(duì)AGP、USB、DVD的支持,但在內(nèi)核上卻和Windows95基本一樣,它們都是基于DOS內(nèi)核的操作系統(tǒng)。Windows98系統(tǒng)核心(Kernel)由虛擬機(jī)管理器(VMM)和VxD(Virtual Device Driver)的集合組成。Kernel提供了900多個(gè)服務(wù)函數(shù)來管理內(nèi)存、控制物理設(shè)備、處理中斷、創(chuàng)建網(wǎng)絡(luò)協(xié)議棧、管理文件系統(tǒng)等,這些服務(wù)函數(shù)都可以被自己寫的VxD調(diào)用。虛擬機(jī)(VM)是一個(gè)可運(yùn)行的任務(wù),包含應(yīng)用程序、支撐軟件、內(nèi)存和CPU寄存器。在Windows98下有系統(tǒng)虛擬機(jī)和DOS虛擬機(jī)兩種。虛擬機(jī)管理器(VMM)是在系統(tǒng)級(jí)核心運(yùn)行的32位保護(hù)模式操作系統(tǒng),它運(yùn)行于Ring0,而且不可重入。VMM主要功能是創(chuàng)建、運(yùn)行、監(jiān)控和終止虛擬機(jī)。VxD即虛擬設(shè)備驅(qū)動(dòng)程序,是用來擴(kuò)展Windows操作系統(tǒng)功能的一類程序。由于VxD運(yùn)行在系統(tǒng)的Ring0級(jí),擁有與操作系統(tǒng)同等的級(jí)別,所以我們可利用它來支持硬件設(shè)備的管理。虛擬可編程中斷控制器(VPICD)是負(fù)責(zé)管理所有硬件中斷事件的程序,它本身也是一種VxD,能提供缺省的中斷處理函數(shù)或者允許其它VxD重載中斷處理函數(shù)。

          2 Windows98下應(yīng)用程序權(quán)限級(jí)別

          Intel的80x86CPU系列芯片可在三種模式下工作:實(shí)模式、保護(hù)模式和V86模式。實(shí)模式是MS-DOS的運(yùn)行環(huán)境。Windows98只利用了兩種模式:保護(hù)模式和V86模式。保護(hù)模式給我們帶來很多優(yōu)越性,如應(yīng)用程序不再受1M內(nèi)存的限制,理論上,在保護(hù)模式下,CPU可以進(jìn)行4096M內(nèi)存的尋址。但在保護(hù)模式下,所有的應(yīng)用程序都有權(quán)限級(jí)別(Privilege Level)。權(quán)限級(jí)別按優(yōu)先次序分為四等:0、1、2、3。0級(jí)是最高級(jí)別,操作系統(tǒng)就運(yùn)行在0級(jí),運(yùn)行在Ring0級(jí)的應(yīng)用程序可以執(zhí)行所有的指令并可直接對(duì)硬件、中斷和文件系統(tǒng)進(jìn)行物理訪問。如果應(yīng)用程序擁有的權(quán)限級(jí)別是第3級(jí),那么它能執(zhí)行的指令是有限的,對(duì)硬件的很多直接操作是不能實(shí)現(xiàn)的。在Windows中,一般的應(yīng)用程序是運(yùn)行在Ring3級(jí)的(如用Visual C++、Borland C++、Visual Basic、Delphi、C++ Builder等SDK工具開發(fā)出的應(yīng)用程序)。它們享有的權(quán)限是最低的,受到了保護(hù)模式的摫;,它們沒有權(quán)限去繞過操作系統(tǒng)直接對(duì)硬件操作。

          有了權(quán)限級(jí)別,操作系統(tǒng)就有機(jī)會(huì)在中斷和I/O操作上產(chǎn)生撔檳鈹效果。由于操作系統(tǒng)的權(quán)限為0級(jí),它就可以捕獲權(quán)限不為0級(jí)的應(yīng)用程序的中斷和I/O請(qǐng)求,然后建立緩沖隊(duì)列,再一一進(jìn)行串行處理。為了使自己的應(yīng)用程序也能直接處理硬件,就需要編寫專門的VxD。由于VxD是作為操作系統(tǒng)的組件運(yùn)行于第0級(jí),因而可以利用它來捕獲特定的硬件操作,完成我們需要的任務(wù)。

          3 Windows98下虛擬設(shè)備驅(qū)動(dòng)程序的開發(fā)工具和基本編程方法

          微軟為驅(qū)動(dòng)程序的開發(fā)提供了設(shè)備驅(qū)動(dòng)程序工具箱(DDK),基于匯編語言的編程方式和許多VMM服務(wù)都使用寄存器的調(diào)用方式,確實(shí)非常難學(xué),沒有深厚的匯編語言和硬件基礎(chǔ)很難在短時(shí)間里開發(fā)出自己的VxD。

          美國(guó)Vireo Software公司推出的VToolsD為我們開發(fā)VxD提供了方便快捷的方法。程序員可利用C或C++語言編寫自己的VxD,而不必操心許多繁瑣的細(xì)節(jié)。它的基本編程方法是:用VToolsD自帶的Quick VxD程序快速生成程序框架,在VC++或Borland C++中打開此框架的工程文件,并寫進(jìn)特定的處理代碼,編譯后就可得到所需的VxD文件。

          4 一個(gè)中斷程序?qū)嵗?/b>

          用C或C++都可在VToolsD中進(jìn)行開發(fā),相比之下,由于VToolsD中封裝許多C++類庫,因而用C++語言進(jìn)行VxD的開發(fā)更加容易和方便。

          在我們開發(fā)的小型實(shí)時(shí)光譜能量輻射儀中利用北京眾人公司的PS-2129AD采集卡作為數(shù)據(jù)采集器件。卡上載有三路8253計(jì)數(shù)器,利用其中的兩路產(chǎn)生光電二極管陣列(SSPD)的驅(qū)動(dòng)信號(hào),另外一路讓它工作在方式0椉剖崾卸希康奔剖當(dāng)湮?,便产生中断,灾u卸銑絳蚶锝惺薟杉?。奔m兄卸蝦盼埂?/P>

          定義好設(shè)備屬性各參數(shù)后,在Quick VxD生成的頭文件中定義如下:

          #define DEVICE_CLASS AdcardDevice

          #define ADCARD_DeviceID UNDEFINED_DEVICE_ID

          #define ADCARD_Init_Order UNDEFINED_INIT_ORDER

          #define ADCARD_M(jìn)ajor 1

          #define ADCARD_M(jìn)inor 0

          #define MY_IRQ 9/*中斷號(hào)為9*/

          其中ADCARD為在QuickVxD的對(duì)話框中鍵入的設(shè)備名。VToolsD提供類VHardwareInt來實(shí)現(xiàn)對(duì)某個(gè)IRQ端口的虛擬化,并處理該IRQ端口上的硬件中斷。本實(shí)例中就用到這個(gè)類。

          類OnHaredwareInt的主要成員函數(shù)定義如下:

          VHardwareIn::VHardwareIn(int irq ,DWORD flags,DWORD timeout,PVOID refdata)

          irg 要虛擬化的IRQ,其值從0~15;

          flag 一般設(shè)置為0;

          timeout 從虛擬中斷申請(qǐng)(assert)到進(jìn)入VM中的虛擬中斷處理函數(shù)所允許的最大時(shí)延,設(shè)置0

          表示忽略 timeout;

          refdata refdata將存放在m_refdata變量中,在通知事件處理函數(shù)里,可以作為參考數(shù)據(jù)。

          VHardwareIn::OnHaredwareInt(VMHANDLE hVM)

          當(dāng)IRQ硬件中斷發(fā)生時(shí),VPICD將調(diào)用類VHardwareIn里的成員函數(shù)OnHaredwareInt,在調(diào)用OnHaredwareInt函數(shù)之前,VPICD首先發(fā)Cli指令,同時(shí)設(shè)置本IRQ的屏蔽位。所以可以在OnHaredwareInt函數(shù)里直接處理中斷服務(wù)。

          VHardwareIn::hook()

          hook成員函數(shù)把虛擬IRQ與OnHaredwareInt函數(shù)相勾連。通過重載OnHaredwareInt函數(shù)用來處理本IRQ的各種中斷事件。返回TRUE表示IRQ虛擬化成功,返回FALSE則表示IRQ虛擬化失敗。

          VHardwareIn::physicalUnmask()

          命令VPICD物理地不屏蔽本IRQ。

          VHardwareIn::sendPhysicalEOI()

          此成員函數(shù)通知VPICD中斷處理結(jié)束。VPICD將物理地不屏蔽本IRQ。

          在頭文件里派生類VHardwareIn,在派生類中定義構(gòu)造函數(shù),并重載OnHaredwareInt函數(shù)。

          class MyHwInt:public VHardwareIn

          {

          public: MyHwInt():VHardwareIn(MY_IRQ,0,0,0){}

          /*定義構(gòu)造函數(shù)*/

          virtual VOID OnHardwareInt(VMHANDLE)

          /*重載OnHaredwareInt函數(shù)*/

          };

          并在頭文件里定義一個(gè)派生類的實(shí)例,放在QuickVxD自動(dòng)生成的AdcardDevice類里:

          class AdcardDevice : public VDevice

          {

          public:

          virtual BOOL OnSysDynamicDeviceInit();

          /*用來動(dòng)態(tài)加載VxD*/

          virtual BOOL OnSysDynamicDeviceExit();

          /*用來動(dòng)態(tài)卸載VxD*/

          MyHwInt pMyIRQ; /*定義MyHwInt的一個(gè)實(shí)例*/

          };

          為了讓VxD能與Ring3級(jí)的應(yīng)用程序通訊,本實(shí)例中采用共享內(nèi)存的辦法。在源文件里定義一個(gè)內(nèi)存地址,Ring3級(jí)應(yīng)用程序通過讀取此內(nèi)存地址來得到AD卡的采集結(jié)果。

          源文件以下所示:

          #define DEVICE_M(jìn)AIN

          #include adcard.h

          Declare_Virtual_Device(ADCARD)

          #undef DEVICE_M(jìn)AIN

          PWORD pVal=(PWORD)0x9F000

          //定義一個(gè)內(nèi)存地址

          BOOL AdcardDevice:: OnSysDynamicDeviceInit()

          {

          pMyIRQ=new MyHwInt();

          /*創(chuàng)建類 MyHwInt的一個(gè)實(shí)例*/

          if(pMyIRQ->hook()) /*判斷本IRQ是否虛擬化成功*/

          {

          pMyIRQ->physicalUnmask(); //不屏蔽本IRQ return TRUE

          }

          else return FALSE;

          }

          BOOL AdcardDevice:: OnSysDynamicDeviceExit()

           {

          delete ppMyIRQ; //刪除類MyHwInt的實(shí)例 retuen TRUE

           }

          VOID MyHwInt::OnHardwareInt(VMHANDLE hVM)

          {

          ...... /*這里寫上處理中斷的代碼*/

           *pVal=_inp(0x0102) /*讀進(jìn)AD轉(zhuǎn)換結(jié)果,這里假定AD卡存放轉(zhuǎn)換結(jié)果的端口為0x0102*/

          sendPhysicalEOI();/*發(fā)中斷結(jié)束信號(hào)*/

          }

          用VC++打開此工程文件,編譯后就可得到adcard.vxd文件。

          在Ring3級(jí)的應(yīng)有程序中為了調(diào)用adcard.vxd,可在其源文件中添加以下語句:

          HANDLE HVXD

          HVXD=CreateFile(″\\\\.\\adcard.vxd″,0,0,0CREATE_NEW,

          FILE_FLAG_DELETE_ON_CLOSE,0);

          if(HVXD==INVALID_HANDLE_VALUE)

          ......

          CreateFile()的詳細(xì)用法可查閱VC++的幫助。這樣應(yīng)用程序中就加載了adcard.vxd文件。為了能使此應(yīng)用程序能得到AD卡的轉(zhuǎn)換結(jié)果,同樣也要在源文件里定義一個(gè)內(nèi)存地址:

          PWORD pVal=(PWORD)0x9F000;

          在需要得到轉(zhuǎn)換結(jié)果的地方加上以下語句即可:

          int data;

          data=*pVal;//假定把結(jié)果存在data變量里

          這樣一個(gè)中斷實(shí)例就完成了。

          以上實(shí)例我們已在VTOOlsD3.01和VC++6中調(diào)試通過,并已成功地在我們開發(fā)的小型實(shí)時(shí)光譜能量輻射儀中得到應(yīng)用。

          VxD作為現(xiàn)在流行的編程技術(shù)已逐漸受到廣泛的關(guān)注,在工程技術(shù)中必將有著廣闊的應(yīng)用前景。學(xué)習(xí)、使用此技術(shù)將在科學(xué)研究中給我們帶來便利。


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


          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();