<del id="dhfrq"></del>

    1. <tr id="dhfrq"></tr>
      成人午夜激情在线观看,国产精品一线天粉嫩av,99精品国产综合久久久久五月天 ,一卡2卡三卡4卡免费网站,国产高清在线男人的天堂,五月天国产成人AV免费观看,67194熟妇在线观看线路,成人无码潮喷在线观看
      現在位置:范文先生網>理工論文>電子通信論文>采用VXD技術實現實的通信

      采用VXD技術實現實的通信

      時間:2023-02-21 00:14:28 電子通信論文 我要投稿
      • 相關推薦

      采用VXD技術實現實的通信

        摘要:討論Windows虛擬設備驅動(VXD)技術,并采用此項技術示范性地做出應用于PC串口實時通信的虛擬驅動程序,找到一種可以在PC中實現實時通信的途徑。
        關鍵詞:VXD實時串口通信
        
        引言
        
        在微軟的視窗操作系統中,系統內核掌管所有的應用程序,通過獨特的任務調度算法實現CPU的分時多任務處理方式。多任務處理對大多數用戶可能是件好事,但是對那些想把實時通信建立在Windows操作系統上的特殊用戶來說,操作界面的圖形化并不比MS-DOS的單任務更具吸引力。在視窗操作系統里可以進行實時通信和控制碼?答案是:VXD技術可以幫我們在獲取友好的人機界面的同時還擁有很強的實時性。
        
        1VXD技術解析
        
        VXD技術可追溯到Windows3.1,它的引入就是要讓操作系統實現多工以及硬件資源的共享。為了支持多個MS-DOS任務同時執行,Windows98讓每個MS-DOS應用程序在各自的虛擬機(VM)上運行,各自互不相干;而所有的Widnows應用程序卻都在一個虛擬機上運行。圖1所示的結構框圖很好地說明了Windows98的整體架構。
        
        圖1中,由眾多的VXD組成系統級代碼處于最底層。其中,處于中心地位的是一名為VMM32的VXD,它負責協調和管理所有的VXDs。其它VXDs則通過消息機制(這個消息機制由VMM32.VXD來維護)彼此聯系。由所有VXDs開放出的服務接口(API)組成了一個服務網,它們彼此通過合作的方式,提供Windows98的系統底層驅動服務。
        
        從以上Windows98系統架構可以看出,要想在視窗平臺下獲取很強的實時性,僅靠提升應用程序線程優先級的方法是不夠的。因為Win32應用程序代碼屬于Ring3級,而VXD代碼則屬于Ring0級;采用VXD撰寫的實時通信程序可以完全不受代碼限制,可以直接對硬件進行操作。VXD的這個特點正是實時通信建立所必須的。
        
        設計實時通信的VXD前,先解釋以下幾個問題:
        
        ①VMM32使用VPICD.VXD虛擬化每個硬件和軟件中斷。VMM32為每個虛擬機(VM)維護一個IDT結構,當中斷發生時,CPU先保護中斷現場,然后經由當前VM的IDT把這個中斷引導至相應的中斷處理程式。
        
        中斷的虛擬化,使我們有機會給每個中斷提供新的中斷處理函數,并可以讓多個硬件共享同一個中斷號。VPICD.VXD為我們提供這些服務。
        
        ②VMM有兩個調度器,用以在多個線程和VMs之間實現搶占式多工。主調度器負責選定下一個將被執行的線程。這個選擇可以是一個,也可以是多個。然后,主調度器把選擇結果送給所謂的時間片調度器,并由后者完成各個應用程序間的時間片分配。調度器也時應用程序經由呼叫Win32線程優先調整API(如SetThreadPriority和SetPriorityClass等)做出回應。當中斷發生時,VMM32自動提升中斷處理函數所在VM之優先級,保證中斷處理函數能及時被執行。
        
        ③VXD和Win32應用程序可直接通信。Win32應用程序可通過一個系統API(DevicelOControl(…))來呼叫位于底層的VXD為其服務。在呼叫VXD前,首先必須調用CreatFile(…)這個API加載該VXD(如果該VXD是一個靜態VXD,則不用加載)。所有的呼叫動作其實都通過VMM32完成。VXD也可以通過消息方式和位于上層的Win32應用程序通信。She11.VXD為所有希望以消息機制和Win32應用程序通信的VXD提供了這一服務。
        
        以上是編寫一個串口通信驅動需要的系統層面知識。對于Windows底層的了解。
        
        2用VXD實現一個實時串口通信驅動
        
        接下來用VXD技術實現一個實時串行通信的驅動。這個VXD是一個動態(Dynamic)VXD,當它的服務被呼叫時,VMM32會動態加載這個VXD。作者采用的工具是C+98DDK。當然也可以使用其它的工具,如MASM6.11(或更高版本)、VtoolsD。用C搭配DDK完成VXD構建的好處是,可以使用C語言完成絕大部分的程序,程序比較容易閱讀和維護。
        
        用C來實現一個VXD驅動,需要準備如下條件:一個.ASM的匯編語言接口文件(在其中定義VXD要處理的系統消息和輸出API),一個.C的函數實現文件(在其中完成自己函數實體),一個.DEF的定義文件(在其中定義VXD中各個段的別名并匯成一個DDB)和一個.MAK檔(用來編譯并連接生成VXD,可有可無)。在這里,僅給出用C實現的函數檔。至于其它的文件,可以從本文所列的參考書目或其它文獻中找到相關文檔的說明。
        
        這個串口通信驅動程序的功能是:實時送出一個Byte的數據,實時接收一個Byte的數據。作為演示之用,并沒有加入其它代碼。該VXD驅動主要由如下3個系統消息(由VMM32來維護和管理)處理函數組成,其代碼如下:
        
        (1)OnSysDynamic
        
        
        
        DeviceInit()函數
        
        BOOLOnSysDynamicDeviceInit()
        
        {//OnSysDynamicDeviceInit
        
        irqhandle=VPICD_Virtualize_IRQ((DWORD)(&irq4));
        
        if(irqhandle==0){
        
        returnFALSE;
        
        }
        
        returnTRUE;//OnSysDynamicDeviceInit
        
        }
        
        該函數用來完成VXD初始化所做的工作。在本例中,由于實時監視串口中斷的需要,要給COM1的中斷安裝一個自定義的斷服務函數。98DDK已經提供了這個函數的C語言版,其原型是HIRQstaticVPICD_Virtualize_IRQ(PVIDpvid),在vpicd.h中。該函數需要一個指針作為參數(指向名為VPICD_IRQ_Descriptor的結構體),函數傳回一個指向該虛擬IRQ的句柄(該句柄在后來的VPICD服務中需要提供)。VPICD_IRQ_Descriptor結構體的組成為:
        
        typedefstructVPICD_IRQ_Descriptor{
        
        USHORTVID_IRQ_Number;//IRQ號(0~15)
        
        USHORTVID_Options;//標志位選項
        
        ULONGVID_Hw_Int_Proc;//硬件中斷服務程序的地址
        
        ULONGVID_Virt_Int_Proc;//虛擬中斷服務程序
        
        ULONGVID_Mask_Change_Proc//MaskChange調用例程
        
        ULONGVID_IRET_Proc;//IRET調用例程
        
        ULONGVID_IRET_Time_Out;//在Vm的進程優先級提升之前的最大等待時間
        
        ULONGVID_Hw_Int_Ref;//硬件中斷服務程序的數據存放地址
        
        }VID;
        
        其中只用到三位。在本例中需要聲明一個名為irq4的全局變量為VID結構,并付給如下初值:VIDirq4={4,0,hwproc,0,0,0,0,500,0},表示將要虛擬化IRQ4,改變其中斷處理函數為voidhwproc(void),該函數的原型如下:
        
        voidhwproc(void){
        
        _asm{
        
        movdx,0x3f8
        
        inal,dx
        
        movbyteptr[readin],al
        
        clc
        
        }
        
        return;
        
        }
        
        在這個中斷處理中,僅僅從COM1的數據寄存器(地址為3F8h)中讀取接收到的數值,并把該數值存放在一個類型為BYTE、名為readin的內存中。
        
        (2)OnSysDynamicDeviceExit()函數
        
        BOOLOnSysDynamicDeviceExit()
        
        {
        
        VPICD_Force_Default_Behavior(irqhandle);
        
        //解除IRQ4虛擬化
        
        returnTRUE;
        
        }//OnSysDynamicDeviceExit
        
        該數提供了用于善后處理VXD在卸載時需要完成的事件。在本例中,和VXD初始化對應,需要解除對COM1的中斷IRQ4的虛擬化。作者也是用98DDK在vpicd.h中提供的外包函數voidstatic_inlineVPICD_Force_Default_Behavior(HIRQhirp)。該函數唯一需要的參數便是使用VPICD_Virtualize_IRQ函數傳回的IRQ句柄。
        
        (3)OnDeviceIoControl()函數
        
        DWORDOnDeviceIoControl(PDIOCPARAMETERSp){
        
        Switch(p->dwIoCon
        
        
        
        trolCode)
        
        {
        
        case1://端口寫功能
        
        if(!p->lpvOutBuffer||p->cbOutBuffer<1)
        
        {//輸出緩存的有效性檢查
        
        returnERROR_INVALID_PARAMETER;
        
        }
        
        if(serial_out((DWORD)(p->lpvInBuffer)))
        
        {//數據發送
        
        *(BYTE*)(p->lpvOutBuffer)=*(BYTE*)(p->lpvInBuffer);
        
        }
        
        else{
        
        *(BYTE*)(p->lpvOutBuffer)=0;
        
        }
        
        open_int();//打開com1中斷
        
        return0;
        
        case2://端口讀功能
        
        if(*(BYTE*)reading==0x00)
        
        {//數據讀入
        
        *(BYTE*)(p->lpvOutBuffer)=0x00;
        
        return0;
        
        }
        
        *(BTYE*)(p->lpvOutBuffer)=*(BYTE*)(readin);
        
        return0;
        
        }
        
        return0;
        
        }
        
        return0;
        
        }
        
        OnDeviceIoControl函數用來處理Win32應用程序對VXD的呼叫。Win32應用程序的呼叫會讓VMM32送給該VXD一個系統信息,并傳遞進一個DIOCPARAMETERS結構的指針。該結構里包含Win32應用程序呼叫時傳遞進來的各個參數。這個結構的組成如下:
        
        TypedefstunctDIOCParams{
        
        DWORDInternall;//指向客戶寄存器的指針
        
        DWORDVMHande;//該VM的句柄
        
        DWORDInternal2;//指向DDB結構的指針
        
        DWORDdwIoConrolCode;//DeviceIoControl例程中呼叫的控制碼
        
        DWODlpvInBuffer;//DeviceIoControl例程呼叫所傳遞進來的輸入緩沖區地址
        
        DWORDcbInBuffer;//輸入緩沖區的大小
        
        DWORDlpvOutBuffer;//DeviceIoControl例程呼叫所傳遞進來的輸出緩沖區地址
        
        DWORDcbOutBuffer;//輸出緩沖區的大小
        
        DWORDlpcbBytesReturned;//拷貝到輸出緩沖區中的字節數(可以為NULL)
        
        DWORDlpOverlapped;//DeviceIoControl例程呼叫所傳遞進來的重疊I/O塊結構
        
        DWORDhDevice;//Ring3層呼叫應用程序句柄
        
        DWORDtagProcess;//例程標簽
        
        }
        
        DIOPARAMETERS;
        
        其中,dwIoControlCode指明了Win32應用程序需要VXD提供的哪一項服務。在本例中采用一個switch-case語句作為服務入口,如下所示。其中服務1為讓串口送出一個字節,服務2為讀取一個已經由串口接收的字節。函數open_int()是用來初始化串口以便接收字節數據;函數BOOLserial_out(DWORDpBuffer)是讓串口發出一個字節。它們的函數體分別如下:
        
        BOOLserial_
        
        
        
        out(DWORDpBuffer){
        
        if(pBuffer==NULL){
        
        returnFALSE;
        
        }
        
        _asm{
        
        pushfd
        
        cli
        
        pusheax
        
        pushedx
        
        movdx,0x3fb;設置COM1的波特率
        
        moval,0x83
        
        outdx,al
        
        movdx,0x3f8
        
        moval,12
        
        outdx,al
        
        movdx,0x3f9
        
        moval,0
        
        outdx,al
        
        movdx,0x3fb;設置COM1的線控項
        
        moval,3
        
        outdx,al
        
        movdx,0x3f9;CMM1關中斷
        
        moval,0
        
        outdx,al
        
        movdx,0x3fa;關閉com1的FIFO功能
        
        moval,0
        
        outdx,al
        
        movdx,0x3f8;字節發送
        
        moval,byteptr[pBuffer]
        
        outdx,al
        
        popedx
        
        popeax
        
        popfd
        
        sti
        
        }
        
        returnTRUE;
        
        }
        
        serial_out這個函數體的實現是用匯編語言實現的。因為涉及到很多的端口提供以及CPU的標志(flag)和壓棧操作,因此考慮到用匯編語言編寫會簡化代碼。因為此串口傳輸中,用到了關閉中斷的指令(cli),所以,當寫操作所要求完成的任務很多時,此關中斷指令會讓程序的實時性很好地體現出來,但cli指令有效時間過長會導致系統問題,所以還是要謹慎使用。
        
        Voidopen_int(void){
        
        _asm{
        
        movdx,0x3f9;COM1開中斷
        
        moval,0x05
        
        outdx,al
        
        }
        
        return;
        
        }
        
        open_int函數用來把PC串口的中斷設備按照需要設立起來。函數體很簡單,僅改變了地址為3F9h的內容,意為設置Rxdataready和Linestatus中斷位,以便讓CPU可以及時在COM1的中斷服務程序里讀取串口接收到的字節。
        
        以上涉及到串口輸入和輸出的函數體實現代碼中,用到了PC16550UART的資料。
        
        至此,一個可用于實時串口通信的VXD驅動程序已經完成。由于篇幅所限,不能將其它必要的文檔一同提出來討論。
        
        3Win32客戶測試程序
        
        有了上述VXD驅動程序,還需要搭配一個Win32客戶程序來進行測試。在網絡補充版中,給出一個筆者在VC6下編制的一個控制臺應用程序片斷,以供參考。
        
        現在編制VXD驅動還沒有一個集成開發環境(IDE)。本文的驅動程序是用VC6.0自帶的編譯器編譯的。由于要編譯匯編文檔,所以還需要把一個MASM匯編器(要求6.0以上版本)及其相關文檔拷貝到VC6.0的vc98\u30446目錄下。
        
        
        
        
        4結論
        
        通過以上對VXD技術的簡要分析以及一個用VXD實現的通信驅動可以看出,在Windows操作系統中,采用VXD技術,可以很好地克服由多工帶來的時延問題,很好地解決了在Windows平臺下實時通信的問題。
        
        
        
        
        
        

      【采用VXD技術實現實的通信】相關文章:

      SWIFT全球清算系統采用PKI技術08-05

      高科技:郵政發展的保證——采用高技術促進郵政通信發展探析08-06

      采用多框架技術實現在線考場恢復系統08-06

      采用虛擬儀器技術的油品含水量檢測系統08-06

      通信技術專業就業前景08-20

      光纖通信技術及運用08-18

      通信技術自我鑒定11-22

      通信技術求職信04-08

      通信技術個人簡歷03-20

      主站蜘蛛池模板: 无人去码一码二码三码区| 国产尤物精品自在拍视频首页| 老司机性色福利精品视频| 粉嫩在线一区二区三区视频| 亚洲欧洲日产国无高清码图片| 亚洲国产精品一区二区三| 亚洲人妻中文字幕一区| 精品国产一区二区三区卡| 中文字幕有码日韩精品| 男女啪啪高潮激烈免费版| 日本欧美一区二区三区在线播放| 日韩中文字幕综合第二页| 亚洲国产在一区二区三区| 国精品91人妻无码一区二区三区 | 国产精品午夜精品福利| 国产精品白丝久久AV网站| 美女人妻激情乱人伦| 日本一区二区三区专线| 国产精品午夜福利免费看| 亚洲日韩精品无码一区二区三区| 中文字幕无码专区一VA亚洲V专| 久久夜色撩人精品国产av| 亚洲aⅴ男人的天堂在线观看| 亚洲精品岛国片在线观看| 亚洲国产精品日韩在线| 亚洲国产日韩a在线播放| 在线涩涩免费观看国产精品| 国产精品va无码一区二区| 奇米四色7777中文字幕| 久久精品午夜视频| 国产熟女老阿姨毛片看爽爽| 欧美成人黄在线观看| 日韩国产成人精品视频| 俄罗斯老熟妇性爽xxxx| 麻豆国产va免费精品高清在线| 欧美 亚洲 另类 丝袜 自拍 动漫| 亚洲夂夂婷婷色拍ww47| 国产国产成人精品久久蜜| 亚洲成在人天堂一区二区| 亚洲精品成人一二三专区| 男女激情一区二区三区|