真人一对一直播,chinese极品人妻videos,青草社区,亚洲影院丰满少妇中文字幕无码

0
首頁 精品范文 驅(qū)動(dòng)程序設(shè)計(jì)

驅(qū)動(dòng)程序設(shè)計(jì)

時(shí)間:2022-11-02 01:26:43

開篇:寫作不僅是一種記錄,更是一種創(chuàng)造,它讓我們能夠捕捉那些稍縱即逝的靈感,將它們永久地定格在紙上。下面是小編精心整理的12篇驅(qū)動(dòng)程序設(shè)計(jì),希望這些內(nèi)容能成為您創(chuàng)作過程中的良師益友,陪伴您不斷探索和進(jìn)步。

第1篇

關(guān)鍵詞:wince 驅(qū)動(dòng)程序;開發(fā);設(shè)計(jì)

1 引言

WINCE和Windows 98或Windows 2000不同,它可以工作在12種不同的處理器體系結(jié)構(gòu)、180余種CPU上;同時(shí),WINCE是一個(gè)實(shí)時(shí)操作系統(tǒng)(實(shí)時(shí)系統(tǒng)的意義就是輸入的指令不必進(jìn)入隊(duì)列就可以馬上處理,過去我們使用的DDS就是實(shí)時(shí)系統(tǒng)),可以滿足應(yīng)用程序所需要的實(shí)時(shí)性要求。

Windows CE的模塊化設(shè)計(jì)使得它能夠在大量的平臺上定制使用,從客戶電子設(shè)備到專用的工業(yè)控制器。由于它是模塊化的,因而我們可以使用滿足平臺系統(tǒng)需求的最小軟件模塊和組件集合來設(shè)計(jì)嵌入式系統(tǒng)平臺,從而使內(nèi)存用量最小,但最大可能地提高操作系統(tǒng)的性能。因此外圍擴(kuò)展設(shè)備就必須要有硬件驅(qū)動(dòng)才能正常工作。

和其它的操作系統(tǒng)一樣,Windows CE也提供設(shè)備驅(qū)動(dòng)軟件,這些軟件的目的是驅(qū)動(dòng)內(nèi)部和外圍的硬件設(shè)備,或?yàn)樗鼈兲峁┙涌凇TO(shè)備驅(qū)動(dòng)程序?qū)⒉僮飨到y(tǒng)和設(shè)備鏈接起來,使得操作系統(tǒng)能夠識別設(shè)備或者為應(yīng)用程序提供設(shè)備服務(wù)。

Windows CE支持廣泛的基于各種CE平臺的設(shè)備驅(qū)動(dòng)程序。也提供一些用于驅(qū)動(dòng)程序開發(fā)的模型(model) ,其中包括來自其它操作系統(tǒng)的驅(qū)動(dòng)程序模型(model),因?yàn)檫@些豐富多變的驅(qū)動(dòng)程序模型, Windows CE適應(yīng)大部分的內(nèi)部和外圍設(shè)備口Microsoft Windows CE設(shè)備驅(qū)動(dòng)程序工具包配備了文檔資料,這些文檔資料使得你能夠?yàn)閃indows CE創(chuàng)建設(shè)備驅(qū)動(dòng)程序。目前,Windows CE提供了四種設(shè)備模型,其中兩種是專用于Windows CE的模型,另外兩種外部模型來自其它操作系統(tǒng)。

2 驅(qū)動(dòng)程序開發(fā)簡介

2.1 開發(fā)工具

Windows CE驅(qū)動(dòng)可以使用Platform Builder或者Visual Studio開發(fā),但是開發(fā)人員一般都使用Platform Builder開發(fā)設(shè)備驅(qū)動(dòng)程序,對于部分驅(qū)動(dòng)也會使用Visual Studio開發(fā),應(yīng)用程序開發(fā)人員更多的使用Visual Studio開發(fā)驅(qū)驅(qū)動(dòng)程序。作為BSP(Board Support Package)的一部分進(jìn)行整體編譯開發(fā)。

2.2 驅(qū)動(dòng)分類

2.2.1 按加載方式和接口類型分類

1) 本機(jī)驅(qū)動(dòng)程序(Built-In Drivers)

通常由GWES加載,驅(qū)動(dòng)接口一般都是定制的(Custom Purpose)。

2) 流驅(qū)動(dòng)程序(Stream Drivers)

通常由Device Manager加載,驅(qū)動(dòng)接口是標(biāo)準(zhǔn)的流式接口。

3) 混和型驅(qū)動(dòng)程序

同時(shí)有定制式和流驅(qū)動(dòng)兩套驅(qū)動(dòng)接口,但是和系統(tǒng)交互只使用流式驅(qū)動(dòng)接口,比如PC卡槽驅(qū)動(dòng)。

2.2.2 按驅(qū)動(dòng)層次分類

1) 層次型驅(qū)動(dòng)程序(Layered Driver)

> MDD(Model Device Driver),與硬件無關(guān),面向上層應(yīng)用程序,一般由微軟建立統(tǒng)一框架;

> PDD(Platform Dependent Driver),針對具體硬件平臺的操作代碼,一般由驅(qū)動(dòng)開發(fā)商實(shí)現(xiàn)MDD和PDD之間通過標(biāo)準(zhǔn)的設(shè)備驅(qū)動(dòng)服務(wù)供應(yīng)商接口DDSI連接。

2) 獨(dú)立型驅(qū)動(dòng)程序(Monolithic Driver)

> 獨(dú)立驅(qū)動(dòng)程序包含了MDD面向上層應(yīng)用和PDD面向硬件平臺兩方面的代碼;

> 適用于操作不復(fù)雜的驅(qū)動(dòng);

> 減少了MDD和PDD傳遞之間傳遞信息的開銷,實(shí)時(shí)性更強(qiáng);

3 流驅(qū)動(dòng)程序的實(shí)現(xiàn)

    流驅(qū)動(dòng)程序必須實(shí)現(xiàn)一套標(biāo)準(zhǔn)接口,流驅(qū)動(dòng)程序適用于IO操作,這也是嵌入式系統(tǒng)中最常見的設(shè)備驅(qū)動(dòng),操作接口和文件系統(tǒng)操作相似,通過CreateFile,ReadFile,WriteFile,IOControl函數(shù)等來操作應(yīng)用程序和流驅(qū)動(dòng)交互,可以把設(shè)備當(dāng)作文件操作。

3.1 文件前綴名確定

    根據(jù)文件前綴名在系統(tǒng)中必須唯一這一特點(diǎn),在定義文件前綴名必須是三個(gè)字母,若有多個(gè)同類設(shè)備,由后綴一個(gè)阿拉伯?dāng)?shù)字區(qū)分,例如COM1,LPT3等等。文件前綴名將會在驅(qū)動(dòng)的標(biāo)準(zhǔn)接口函數(shù)中體現(xiàn),比如XXX_Init,XXX_Close等。

3.2 通用函數(shù)

    根據(jù)設(shè)備的不同,所需函數(shù)不同,通用函數(shù)如下所示:

1) XXX_Init:通知設(shè)備管理器為設(shè)備初始化分配資源;

2) XXX_Deinit:通知設(shè)備管理器回收設(shè)備初始化時(shí)分配的資源;

3) XXX_Open:打開設(shè)備。應(yīng)用程序調(diào)用CreateFile時(shí),通過文件系統(tǒng)映射為XXX_Open;

4) XXX_Close:關(guān)閉設(shè)備。應(yīng)用程序調(diào)用CloseFile時(shí),通過文件系統(tǒng)映射為XXX_Close;

5) XXX_PowerUp:設(shè)備上電時(shí),操作系統(tǒng)調(diào)用該函數(shù)完成必要的上電操作;

6) XXX_PowerDown:設(shè)備掉電時(shí),操作系統(tǒng)調(diào)用該函數(shù)完成必要的關(guān)機(jī)操作

7) XXX_Read:從打開的設(shè)備文件中讀取數(shù)據(jù),可以通過ReadFile映射;

8) XXX_Write:向打開的設(shè)備文件寫數(shù)據(jù),可以通過WriteFile映射;

9) XXX_Seek:文件定位,根據(jù)設(shè)備情況決定是否支持;

10) XXX_IOControl:IO操作擴(kuò)展,可以根據(jù)設(shè)備情況來決定支持何種特殊的操作模式。

3.3 DEF文件建立

    流驅(qū)動(dòng)一般以DLL形式存在,DEF文件定義了DLL需要導(dǎo)出的接口集,因此DEF文件的名稱與設(shè)備驅(qū)動(dòng)名稱相同。

3.4 寫注冊表

    在wince中任何設(shè)備的識別都是通過注冊表來實(shí)現(xiàn)的,因此必須在注冊表中添加具體的設(shè)備驅(qū)動(dòng)項(xiàng),以便系統(tǒng)識別。具體方法如下:

在注冊表中增加驅(qū)動(dòng)程序入口點(diǎn),找到注冊表項(xiàng),注冊項(xiàng)位于注冊表的Root Key下,一般為[HKEY_LOCAL_MACHINEDriversBuiltInSampleDrv],建立必要的子鍵和鍵值,“Prefix”和“DLL”是兩個(gè)重要,而且是必須的鍵,分別描述了設(shè)備前綴名和驅(qū)動(dòng)程序的動(dòng)態(tài)連接庫名,然后根據(jù)具體設(shè)備的需要建立驅(qū)動(dòng)程序需要的其子他鍵。

4 調(diào)試驅(qū)動(dòng)程序

驅(qū)動(dòng)程序編寫完畢后,就應(yīng)該進(jìn)行硬件的調(diào)試。具體方法如下:

4.1 調(diào)試區(qū)信息(Debug Zone)

調(diào)試區(qū)一般和WinCE的控制臺調(diào)試工具Cesh.exe配合調(diào)試,在不打斷OS運(yùn)行情況下,進(jìn)行驅(qū)動(dòng)的實(shí)時(shí)調(diào)試,利用宏開關(guān),可以選擇需要輸出的調(diào)試區(qū)信息,可以得到進(jìn)程,線程和調(diào)試狀態(tài)信息。并且可以利用IDE環(huán)境,動(dòng)態(tài)選擇開關(guān)調(diào)試區(qū)信息,但是打印驅(qū)動(dòng)程序輸出調(diào)試信。必須借助于至少一種外設(shè)顯示調(diào)試信息,比如串口或者網(wǎng)卡或者其他通過調(diào)用RETAILMSG或者DEBUGMSG完成,不影響OS的運(yùn)行,保證驅(qū)動(dòng)程序運(yùn)行的真實(shí)性,動(dòng)態(tài)輸出設(shè)備的狀態(tài)信息,調(diào)試相對簡單,也是最廣泛使用的一種調(diào)試方法。

4.2 核心調(diào)試工具(Kernel Debugger)

核心調(diào)試工具將會禁止所有硬件中斷,掛起操作系統(tǒng),因此可以單步調(diào)試OS或者核心代碼,可以訪問堆棧信息,但是必須在Platform的環(huán)境下,利用至少一種外設(shè)進(jìn)行通信。

4.3 硬件輔助調(diào)試方法

利用硬件調(diào)試工具可以觀察物理設(shè)備的真實(shí)狀態(tài),一般常用的方法可以利用JTAG工具實(shí)時(shí)查看CPU內(nèi)部寄存器,利用邏輯分析儀或者示波器實(shí)時(shí)查看物理外設(shè)的輸入輸出狀態(tài)。利用指示LED來顯示驅(qū)動(dòng)程序?qū)崟r(shí)狀態(tài)信息。

4.4 Visual Studio調(diào)試

可以利用VS內(nèi)置的調(diào)試工具進(jìn)行單步跟蹤,狀態(tài)調(diào)試等。

5 測試驅(qū)動(dòng)程序

驅(qū)動(dòng)程序經(jīng)過調(diào)試以后就需要對驅(qū)動(dòng)的功能進(jìn)行測試。其常用的方法如下:

1) 寫一個(gè)應(yīng)用程序來測試驅(qū)動(dòng)程序的正確性

2) 模擬各種可能發(fā)生的硬件輸入狀態(tài)來測試驅(qū)動(dòng)程序的正確性

3) 利用Windows CE自帶的測試工具CETK來測試驅(qū)動(dòng)程序的性能和完備性

6 驅(qū)動(dòng)程序的集合和

6.1 驅(qū)動(dòng)程序集成

驅(qū)動(dòng)程序經(jīng)過調(diào)試和測試確定其正確性后,就可以對驅(qū)動(dòng)程序進(jìn)行集成了。具體過程如下:

1) 在BSP的Driver目錄下建立新的驅(qū)動(dòng)文件夾MyDrv

2) 實(shí)現(xiàn)MyDrv驅(qū)動(dòng)以及相關(guān)的DEF文件

3) 如果需要用到硬件中斷資源,修改原BSP中的相關(guān)中斷處理函數(shù)OEMInterruptEnable,OEMInterruptDisable,OEMInterruptDone,OEMInterruptHandler

4) 在Platform.reg中,增加驅(qū)動(dòng)程序相關(guān)項(xiàng)

5) 在Platform.bib中,增加驅(qū)動(dòng)程序的相關(guān)注冊表項(xiàng)MyDrv.Dll$(_FLATRELEASEDIR)MyDrv.dll NK SH

6.2 驅(qū)動(dòng)程序

驅(qū)動(dòng)程序進(jìn)過集成以后就可以使用了,具體的過程如下所示:

1) 利用CAB Wizard生成.cab驅(qū)動(dòng)包

2) 直接提供驅(qū)動(dòng)程序文件夾以及相關(guān)注冊表項(xiàng)和修改說明

7 總結(jié)

本為詳細(xì)的介紹了,wince下驅(qū)動(dòng)開發(fā)的流程,介紹了驅(qū)動(dòng)程序開發(fā)到的詳細(xì)過程,并詳細(xì)說明了各個(gè)部分的實(shí)現(xiàn)和操作方法,使是初學(xué)者對wince下驅(qū)動(dòng)程序的開發(fā)流程和一般的開發(fā)工具有了初步的了解。

第2篇

關(guān)鍵字 Windows系統(tǒng) 驅(qū)動(dòng)程序 通知應(yīng)用程序 設(shè)計(jì) 方法

中圖分類號: TP316 文獻(xiàn)標(biāo)識碼:A

1 前言

操作系統(tǒng)的穩(wěn)定性及可移植性是務(wù)必要優(yōu)先確保的,為此Windows操作系統(tǒng)不支持應(yīng)用程序直接訪問系統(tǒng)的硬件資源,而是必須借助于相應(yīng)的設(shè)備驅(qū)動(dòng)程序。設(shè)備驅(qū)動(dòng)程序可以直接操作硬件,假如應(yīng)用程序和設(shè)備驅(qū)動(dòng)程序之間實(shí)現(xiàn)了雙向通信,也就達(dá)到了應(yīng)用程序控制底層硬件設(shè)備的目的。

2 通知應(yīng)用程序設(shè)計(jì)四種方法

鑒于設(shè)備驅(qū)動(dòng)程序通知應(yīng)用程序的重要性,本人結(jié)合一些經(jīng)驗(yàn),對它進(jìn)行了總結(jié),歸納出5種方法摘要:異步過程調(diào)用(APC)、事件方式(VxD)、消息方式、異步I/O方式和事件方式(WDM)。下面分別說明這幾種方式的原理。

2.1 異步過程調(diào)用(APC)

Win32應(yīng)用程序使用CreateFile()函數(shù)動(dòng)態(tài)加載設(shè)備驅(qū)動(dòng)程序,然后定義一個(gè)回調(diào)函數(shù)backFunc(),并且將回調(diào)函數(shù)的地址%26amp;backFunc()作為參數(shù),通過DeviceIoControl()傳送給設(shè)備驅(qū)動(dòng)程序。回調(diào)函數(shù)的輸入?yún)?shù)是由設(shè)備驅(qū)動(dòng)程序填入的,回調(diào)函數(shù)在這里主要是對消息進(jìn)行處理。

2.2 事件方式(VxD)

首先,Win32應(yīng)用程序創(chuàng)建一個(gè)事件的句柄,稱其為Ring3句柄。由于虛擬設(shè)備驅(qū)動(dòng)程序使用事件的Ring0句柄,因此,需要?jiǎng)?chuàng)建Ring0句柄。用LoadLibrary()函數(shù)加載未公開的動(dòng)態(tài)鏈接庫Kernel32.dll,獲得動(dòng)態(tài)鏈接庫的句柄。然后,調(diào)用GetProcAddress(), 找到函數(shù)OpenVxDHandle()在動(dòng)態(tài)鏈接庫中的位置。接著,用OpenVxDHandle()函數(shù)將Ring3事件句柄轉(zhuǎn)化為Ring0事件句柄。Win32應(yīng)用程序用CreateFile()函數(shù)加載設(shè)備驅(qū)動(dòng)程序。

2.3 消息方式

Win32應(yīng)用程序調(diào)用CreateFile()函數(shù)動(dòng)態(tài)加載虛擬設(shè)備驅(qū)動(dòng)程序。加載成功后,通過調(diào)用DeviceIoControl()函數(shù)將窗體句柄傳送給VxD,VxD利用這個(gè)句柄向窗體發(fā)消息。當(dāng)條件滿足時(shí),VxD調(diào)用SHELL_PostMessage()函數(shù)向Win32應(yīng)用程序發(fā)送消息。SHELL_PostMessage()函數(shù)的第一個(gè)參數(shù)為Win32窗體句柄,第二個(gè)參數(shù)為消息ID號,第三、四個(gè)參數(shù)為發(fā)送給消息處理函數(shù)的參數(shù),第五、六個(gè)參數(shù)為回調(diào)函數(shù)和傳給它的參數(shù)。Win32應(yīng)用程序收到消息后,對消息進(jìn)行處理。

2.4 事件方式(WDM)

Win32應(yīng)用程序首先創(chuàng)建一個(gè)事件,然后將該事件句柄傳給設(shè)備驅(qū)動(dòng)程序,接著創(chuàng)建一個(gè)輔助線程,等待事件的有信號狀態(tài),自己則接著干其他事情。設(shè)備驅(qū)動(dòng)程序獲得該事件的句柄后,將它轉(zhuǎn)換成能夠使用的事件指針,并且把它寄存起來,以便后面使用。

3 結(jié)語

在目前流行的Windows操作系統(tǒng)中,設(shè)備驅(qū)動(dòng)程序是操縱硬件的最底層軟件接口。它向上提供和硬件無關(guān)的用戶接口,向下直接進(jìn)行I/O、硬件中斷、DMA和內(nèi)存訪問等操作。它將應(yīng)用程序和硬件細(xì)節(jié)屏蔽開來,使軟件不依靠于硬件并且可在多個(gè)不同的平臺之間移植。這4種方法都經(jīng)過實(shí)際測試。測試結(jié)果表明,它們都能夠達(dá)到設(shè)備驅(qū)動(dòng)程序通知應(yīng)用程序的目的。

參考文獻(xiàn)

[1] 李和平. 基于DSP的ICT圖像重建系統(tǒng)探究. 北京摘要: 北京航空航天大學(xué)機(jī)械工程及自動(dòng)化學(xué)院, 2002

第3篇

【關(guān)鍵詞】USB 設(shè)備驅(qū)動(dòng) Linux

1 USB總線原理

USB 協(xié)議是1994年底由康柏、IBM、英特爾等幾家公司聯(lián)合提出來的外部總線接口協(xié)議。USB就是英文中Universal Serial Bus(通用串行總線)的縮寫。USB總線具有其他總線所不具備的如:熱插拔、數(shù)據(jù)傳輸可靠、擴(kuò)展方便、成本低等一系列特點(diǎn),因此在嵌入式系統(tǒng)中被廣泛使用。

一個(gè)USB系統(tǒng)一般是由一個(gè)USB主機(jī)控制器、一個(gè)或多個(gè)USB集線器和一個(gè)或多個(gè)USB設(shè)備節(jié)點(diǎn)組成。USB系統(tǒng)的物理連接具有層次性。USB總線連接USB設(shè)備和USB主機(jī),是一種星型拓?fù)浣Y(jié)構(gòu)。USB的拓?fù)浣Y(jié)構(gòu)如圖1所示。

在一個(gè)USB系統(tǒng)傳輸數(shù)據(jù)的過程中有兩個(gè)非常重要的概念,就是USB傳輸模式和USB描述符。USB傳輸模式是指USB設(shè)備傳輸數(shù)據(jù)的形式。USB設(shè)備支持四種傳輸模式:控制傳輸模式、同步傳輸模式、中斷傳輸模式和批量傳輸模式。控制傳輸模式是用來處理USB主端口到USB從端口的數(shù)據(jù)傳輸,主要是設(shè)備控制指令、設(shè)備查詢狀態(tài)指令和確認(rèn)指令。同步傳輸模式是指傳輸和時(shí)間關(guān)系密切的信息所使用的一種傳輸方式,是一種周期的、連續(xù)的單向傳輸方式。中斷傳輸模式這類傳輸模式主要用于傳輸非周期性的、自然發(fā)生的、數(shù)據(jù)量很小的信息,這類數(shù)據(jù)傳輸?shù)姆较蚴菑脑O(shè)備到主機(jī),適用于鍵盤、鼠標(biāo)、操縱桿等設(shè)備上。最后一種是批量傳輸模式,該模式適用于大量的、對時(shí)間沒有要求的數(shù)據(jù)傳輸,如U盤或者移動(dòng)硬盤等設(shè)備。

USB設(shè)備在邏輯上分為幾個(gè)層次,分別是設(shè)備層(Device)、配置層(Config)、接口層(Interface)、端點(diǎn)層(Endpoint)。各個(gè)層次都有與之相對的描述符,分別是設(shè)備描述符、配置描述符、接口描述符和端點(diǎn)描述符。

2 Linux下的USB驅(qū)動(dòng)框架

USB設(shè)備的設(shè)備描述符在Linux系統(tǒng)中用usb_device_descriptor結(jié)構(gòu)體表示,它描述了USB設(shè)備的一般信息。配置描述符用usb_config_descriptor結(jié)構(gòu)體表示,它給出了USB設(shè)備的配置信息。接口驅(qū)動(dòng)程序是在一個(gè)配置內(nèi)給出一個(gè)接口信息,它在Linux中由usb_interface_descriptor結(jié)構(gòu)體表示。端口描述符被主機(jī)用來決定每個(gè)端口的帶寬需求,它在Linux系統(tǒng)中由usb_endpoint_descriptor結(jié)構(gòu)體表示。

編寫一個(gè)USB驅(qū)動(dòng)程序,是從usb_driver結(jié)構(gòu)體開始的。Linux中模塊加載函數(shù)調(diào)用usb_register()和usb_unregister()從而對usb_driver結(jié)構(gòu)體進(jìn)行加載與卸載。如果某個(gè)設(shè)備信息與該驅(qū)動(dòng)中usb_device_id usb_mouse_id_table 結(jié)構(gòu)體的信息相一致,則會調(diào)用usb_driver中探測成員函數(shù)probe(),將初始化USB斷點(diǎn)信息,并對設(shè)備做一些初始化工作,分配urb結(jié)構(gòu)體,準(zhǔn)備數(shù)據(jù)傳輸。其urb處理大致框架結(jié)構(gòu)如圖2所示。

當(dāng)鼠標(biāo)設(shè)備在用戶空間打開時(shí),將提交 probe 函數(shù)構(gòu)建的 urb 請求塊,urb 將開始為傳送數(shù)據(jù)而忙碌了。urb 請求塊就像一個(gè)裝東西的“袋子”,USB 驅(qū)動(dòng)程序把“空袋子”提交給 USB core,然后再交給主控制器,主控制器把數(shù)據(jù)放入這個(gè)“袋子”后再將裝滿數(shù)據(jù)的“袋子”通過 USB core 交還給 USB 驅(qū)動(dòng)程序,這樣一次數(shù)據(jù)傳輸就完成了。

3 結(jié)束語

由于USB簡單方便快捷等優(yōu)點(diǎn),許多外接設(shè)備會越來越青睞USB接口,這是一種發(fā)展的趨勢。Linux系統(tǒng)具有開源、安全等特性,用戶也在急劇增加。屆時(shí),會有越來越多的USB驅(qū)動(dòng)加入Linux內(nèi)核之中。

參考文獻(xiàn)

[1]Jonathan Corbet,Alessandro Rubini,Greg Kroah-Hartman等.LINUX設(shè)備驅(qū)動(dòng)程序[M].北京:中國電力出版社,2006.

[2]Universal Serial Bus Specification Compaq,Intel,Mi―crosoft,NEC Revision 1.1.September 23,1998.

[3]溫卡特斯瓦蘭.精通Linux驅(qū)動(dòng)程序開發(fā)[M].北京:人民郵電出版,2009.

[4]胡曉軍,張愛成.USB接口卡發(fā)技術(shù)[M].西安:西安電子科技大學(xué)出社,2005:15-17.

作者簡介

徐海林(1989-),男,江蘇省南通市人。現(xiàn)為安徽理工大學(xué)計(jì)算機(jī)科學(xué)與工程學(xué)院學(xué)生。

第4篇

關(guān)鍵詞:PCI總線設(shè)備驅(qū)動(dòng)程序WDM模式DriverStudio

PCI總線規(guī)范是為提高微機(jī)總線的數(shù)據(jù)傳輸速度而制定的一種局部總線標(biāo)準(zhǔn)。在設(shè)計(jì)自行開發(fā)的基于PCI總線的數(shù)據(jù)傳輸設(shè)備時(shí),需要開發(fā)相應(yīng)的設(shè)備驅(qū)動(dòng)程序。通常開發(fā)PCI設(shè)備驅(qū)動(dòng)程序有多種模式,在Windows2000環(huán)境下,主要采用WDM模式。本文針對自行開發(fā)的基于PCI總線的CCD視頻信號傳輸控制卡,編寫了符合WDM模式的驅(qū)動(dòng)程序。

1WDM模式驅(qū)動(dòng)程序

1.1WDM模式(WindowsDriverModel)

Windows2000對驅(qū)動(dòng)程序的編寫不再基于以往的Win3.x和Win9x下的VxD(虛擬設(shè)備驅(qū)動(dòng)程序)結(jié)構(gòu),而是基于一種新的驅(qū)動(dòng)模型——WDM(WindowsDriverModel)。

WDM為Windows98/2000/XP操作系統(tǒng)的設(shè)備驅(qū)動(dòng)程序的設(shè)計(jì)提供了統(tǒng)一的框架。WDM來源于WindowsNT的分層32位設(shè)備驅(qū)動(dòng)程序模型(layered32-bitdevicedrivermodel)。它支持更多的特性,如即插即用(PnP)、電源管理、WMI和NT事件。

1.2設(shè)備驅(qū)動(dòng)程序

設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)的一個(gè)組成部分,它由I/O管理器(I/OManager)管理和調(diào)動(dòng)。Windows2000操作系統(tǒng)下的I/O管理器功能描述如圖1所示。

I/O管理器每收到一個(gè)來自用戶應(yīng)用程序的請求就創(chuàng)建一個(gè)I/O請求包(IRP)的數(shù)據(jù)結(jié)構(gòu),并將其作為參數(shù)傳遞給驅(qū)動(dòng)程序。驅(qū)動(dòng)程序通過識別IRP中的物理設(shè)備對象(PDO)來區(qū)別是發(fā)送給哪一個(gè)設(shè)備。IRP結(jié)構(gòu)中存放請求的類型、用戶緩沖區(qū)的首地址、用戶請求數(shù)據(jù)的長度等信息。驅(qū)動(dòng)程序處理完這個(gè)請求后,在該結(jié)構(gòu)中填入處理結(jié)果的有關(guān)信息,調(diào)用IoCompleteRequest將其返回給I/O管理器,用戶應(yīng)用程序的請求隨即返回。訪問硬件時(shí),驅(qū)動(dòng)程序通過調(diào)用硬件抽象層的函數(shù)實(shí)現(xiàn)。

1.3DriverStudio工具簡介

NuMegaLab公司開發(fā)的DriverStudio是一整套開發(fā)、調(diào)試和檢測Windows平臺下設(shè)備驅(qū)動(dòng)程序的工具軟件包。它把DDK(DeviceDevelopmentKit)封裝成完整的C++函數(shù)庫,根據(jù)具體硬件通過向?qū)煽蚣艽a,并且提供了一套完整的調(diào)試和性能測試工具SoftICE、DriverMonitor等。

2應(yīng)用實(shí)例

本文利用PCI專用接口芯片PCI9052設(shè)計(jì)了一個(gè)數(shù)據(jù)傳輸控制卡。卡上主要的芯片有PCI9052、FIFO(CY7C4221)、CPLD(MAX7064S)和A/D轉(zhuǎn)換器(MAX1197)。傳輸卡硬件框圖如圖2所示。面陣CCD得到的視頻信號經(jīng)過調(diào)理電路,生成的視頻調(diào)理信號通過A/D轉(zhuǎn)換器進(jìn)行數(shù)字化處理,送入FIFO中。在CPLD的控制下,數(shù)據(jù)經(jīng)過PCI9052送入PCI總線,再傳送到計(jì)算機(jī)內(nèi)存中,并顯示在監(jiān)視器上。驅(qū)動(dòng)程序必須實(shí)現(xiàn)如下幾個(gè)基本功能:(1)硬件中斷;(2)能支持應(yīng)用程序獲取數(shù)據(jù);(3)能根據(jù)外部FIFO(CY7C4221)的狀態(tài)啟動(dòng)或停止突發(fā)傳輸。

在數(shù)據(jù)輸入過程中,最重要的是對數(shù)據(jù)進(jìn)行實(shí)時(shí)控制,因此需要硬件中斷。在中斷程序中,根據(jù)外部FIFO狀態(tài)完成數(shù)據(jù)的讀入。

2.1用DriverWizard生成驅(qū)動(dòng)程序框架

DriverStudio中的DriverWorks軟件為開發(fā)WDM程序提供了一個(gè)完整的框架。它包含一個(gè)可快速生成WDM驅(qū)動(dòng)程序框架的代碼生成向?qū)Чぞ逥riverWizard,而且還帶有許多類庫。在用DriverWizard生成的程序框架中寫入相對于設(shè)備的特定代碼,編譯后即可得到所需的驅(qū)動(dòng)程序。

在利用DriverWorksV2.7的向?qū)riverWizard完成驅(qū)動(dòng)程序的框架時(shí)共有11個(gè)步驟,其中關(guān)鍵步驟有:

(1)在第四步中選中PCI,并在VendorID和DeviceID中分別輸入廠商號和設(shè)備號,還需填入PCISubsystemID和PCIRevisionID。這四項(xiàng)可以用網(wǎng)上的免費(fèi)軟件PCITree或PCIView瀏覽PCI設(shè)備,用這兩個(gè)軟件也可以得到BAR0~BAR5的資源分配情況和中斷號。

(2)第七步IRP隊(duì)列排隊(duì)方法,它決定了驅(qū)動(dòng)程序檢查設(shè)備的方式。本設(shè)計(jì)選SystemManaged,則所有的IRP排隊(duì)都由系統(tǒng)(即I/O管理器)完成。

(3)第九步是最關(guān)鍵的一步。首先在Resources中添加資源,在name中輸入變量名,在PCIBaseAddress中輸入0~5的序列號。0~5和BAR0~BAR5一一對應(yīng)。在設(shè)置中斷對話框中,在name欄寫入中斷服務(wù)程序的名稱,選中創(chuàng)建中斷服務(wù)程序ISR?穴CreateISR?雪,不選創(chuàng)建延遲程序調(diào)用DPC(CreateDPC),選中MakeISR/DPCclassfunctions,使ISR/DPC成為設(shè)備類的成員函數(shù)。

其次選中Buffer以選取讀寫方式,用于描述與I/O操作相關(guān)的數(shù)據(jù)緩沖區(qū)。本設(shè)計(jì)需要快速傳送大量數(shù)據(jù),因此采用DirectI/O方式。

(4)在第十步中,需要加入與應(yīng)用程序或者其他驅(qū)動(dòng)程序通信的I/O控制代碼參量。

2.2驅(qū)動(dòng)程序模塊框圖和代碼分布

PCI設(shè)備驅(qū)動(dòng)程序模塊包括配置空間的訪問模塊、IO端口模塊、內(nèi)存讀寫模塊和終端模塊等。各模塊之間是對等的。驅(qū)動(dòng)程序模塊框圖如圖3所示。

驅(qū)動(dòng)程序初始化模塊代碼段放在#pragmacode_seg(″INT″)和#pragmacode_seg()之間。在系統(tǒng)初始化完成后,這部分代碼從內(nèi)存中釋放,防止占用系統(tǒng)寶貴的內(nèi)存資源。#pragmacode_seg()之后是驅(qū)動(dòng)程序和系統(tǒng)的許多模塊的實(shí)現(xiàn)部分。這部分在驅(qū)動(dòng)程序運(yùn)行后不會從內(nèi)存中釋放。

2.3驅(qū)動(dòng)程序主要模塊的實(shí)現(xiàn)

(1)配置空間的訪問模塊

DriverWorks的KPciConfiguration類封裝了訪問PCI設(shè)備配置空間的所有操作。首先初始化這個(gè)類的實(shí)例:

KpciConfigurationPciConfig()m_Lower.TopOfStack());

/?觹m_Lower是KpnpLowerDevice類的對象。m_LowerTopOfStack()返回當(dāng)前設(shè)備堆棧頂部的設(shè)備對象。*/

初始化完后可以直接利用成員函數(shù)ReadHeader/WriteHeader函數(shù)訪問所有的配置寄存器。

為了確定映射空間的類型和大小,先向目標(biāo)基地址寄存器寫入0Xffffffffh,然后回讀該寄存器的值。如果最低位為1,表示映射于I/O空間,反之為存儲空間;如果映射于存儲空間,從第四位開始計(jì)算0的個(gè)數(shù)可以確定內(nèi)存空間的大小;如果是I/O方式,從第二位開始計(jì)算0的個(gè)數(shù)可確定I/O空間的大小,最大為256字節(jié)。如果設(shè)備的存儲空間超過256字節(jié),要實(shí)現(xiàn)設(shè)備的整個(gè)存儲部分的訪問,就必須采用內(nèi)存映射。

(2)I/O操作模塊

Driverworks的KIoRange類封裝了I/O端口訪問的操作。部分代碼如下:

{……

KIORangeDevIoPort();//創(chuàng)建實(shí)例

NTSTATUSstatus=DevIoPort().Initialize(pResListTranslated,pResListRaW,PciConfig.BaseAddressIndexToOrdinal(0));

/*第一個(gè)參數(shù)為轉(zhuǎn)換后的資源列表指針;第二個(gè)參數(shù)為原始資源列表指針;第三個(gè)參數(shù)中的0為I/O口對應(yīng)的基地址,用來轉(zhuǎn)換成特定端口資源的序數(shù)?*/

If(NT_SUCCESS(status))

{……

DevIoPort.inb(0,LineBuf1,10);

/*成功初始化后可分別用KIoRange類的成員函數(shù)inb(/outb)從端口中讀/寫字節(jié)*/

}

else{Invalidate();returnstatus;

/*未能初始化成功,錯(cuò)誤信息在status中*/

{

……}

(3)內(nèi)存讀寫模塊

DriverWorks的KMemoryRange類封裝了端口訪問的操作。

status=m_M(jìn)emoryRange().Initialize(pResListTranslated,pResListRaw,PciConfig.BaseAddressIndexToOrdinal(0));

此函數(shù)的參數(shù)、意義及具體用法與I/O端口的操作基本相同。

內(nèi)存對象也用來發(fā)送控制字,以控制CPLD的開始和停止等。實(shí)際上控制字是通過PCI9052發(fā)送的。該控制字地址已被映射成PCI的內(nèi)存空間。所以定義一個(gè)指向內(nèi)存空間的內(nèi)存對象,通過該對象即可發(fā)送控制字。

(4)中斷模塊

在中斷模塊,首先要激活PCI9052中斷使能位,然后判斷硬件中斷響應(yīng)是否產(chǎn)生,如果有,則進(jìn)行突發(fā)傳輸,讀入FIFO中的數(shù)據(jù)。

BOOLEANTranCard::Isr_M(jìn)yIrq(void)

{if(//中斷未產(chǎn)生)

{……

returnFALSE;}

else

{/*如果產(chǎn)生硬件中斷,設(shè)置命令寄存器,進(jìn)行突發(fā)數(shù)據(jù)傳輸*/

returnTRUE;}

}

為了將硬件中斷與編寫的中斷服務(wù)程序連接在一起,采用InitializeAndConnect方法,部分代碼如下:

NTSTATUSTranCardDevice?押?押OnStartDevice(KIrpI)

{……

status=m_M(jìn)yIrq.InitializeAndConnect(

pResListTranlated,

LinkTo(Isr_M(jìn)yIrq),

This;)

……}

2.4驅(qū)動(dòng)程序的調(diào)用

編寫驅(qū)動(dòng)程序本身不是最終目的,最終目的是調(diào)用驅(qū)動(dòng)程序管理資源,并為用戶應(yīng)用程序使用。驅(qū)動(dòng)程序加載以后,它的許多進(jìn)程處于Idle狀態(tài),實(shí)際上需要用戶應(yīng)用程序去調(diào)用激活。應(yīng)用程序利用Win32API直接調(diào)用驅(qū)動(dòng)程序,實(shí)現(xiàn)驅(qū)動(dòng)程序和應(yīng)用程序的信息交互。

首先用CreateFile()打開設(shè)備,獲得一個(gè)指向設(shè)備對象的句柄。使用CreateFile函數(shù)時(shí)應(yīng)注意:由于驅(qū)動(dòng)程序是*.sys,所以第一個(gè)參數(shù)應(yīng)該是這個(gè)設(shè)備對象的標(biāo)志連接(symboliclink)。該標(biāo)志連接名有一個(gè)設(shè)置數(shù)據(jù)文件搜索路徑的數(shù)字號,而這個(gè)數(shù)字號通常是零。如果這個(gè)連接名是″TranCard″,則傳遞給CreateFile的宇符串就是:″\\\\.\\TranCard0″。例如:

HANDLEhDevice=CreateFile(″\\\\.\\TranCard0″)GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL?,OPEN_EXISTING,0,NULL);

然后用DeviceIoControl()進(jìn)行數(shù)據(jù)的傳送。最后用CloseHandle()關(guān)閉設(shè)備句柄。

下面是應(yīng)用DeviceIoControl()程序片段。

{……

m_b=DeviceIoControl(hDevice,TRANCARD_IOCTL_

RECEIVE(buffer,sizeof,buffer,NULL,0,&buffersize,NULL);

……}

2.5驅(qū)動(dòng)程序的調(diào)試

采用SoftICE、DriverMonitor作為調(diào)試工具,基本調(diào)試過程如下:(1)使用symbolloader加載驅(qū)動(dòng)程序,然后使用SoftICE跟蹤調(diào)試,確認(rèn)驅(qū)動(dòng)程序正常加載;(2)對核心的中斷響應(yīng)程序代碼,用SoftICE中的Genint命令產(chǎn)生虛擬中斷,單步跟蹤中斷;(3)硬件發(fā)送大量的數(shù)據(jù),通過查看內(nèi)存的數(shù)據(jù),確認(rèn)數(shù)據(jù)傳輸是否正確。

第5篇

關(guān)鍵詞:光纜檢測;USB;接口;CY7C68013

引言

隨著人們對通信的要求越來越高,光通信以其獨(dú)特的優(yōu)勢而越來越普及,與此同時(shí)光纜檢測也變得非常重要,為適應(yīng)對預(yù)設(shè)光纜線路的可用狀態(tài)實(shí)時(shí)監(jiān)測和管理需求,要求光纜線路監(jiān)測系統(tǒng)能夠?qū)︻A(yù)設(shè)通信光纜進(jìn)行拓?fù)涔芾怼⒏婢芾怼⒔y(tǒng)計(jì)分析管理、安全管理、資源管理和系統(tǒng)自維護(hù)。

光纜檢測系統(tǒng)和計(jì)算機(jī)之間的接口設(shè)計(jì)是該系統(tǒng)的一個(gè)重要組成部分。RS-232接口曾經(jīng)取得過巨大成功,但是隨著計(jì)算機(jī)與設(shè)備的發(fā)展,RS-232串行端口逐漸成為通信的瓶頸。而USB則突破原有接口的限制,不僅具備較高的通信速率,而且其彈性化設(shè)計(jì)可以取代各種設(shè)備所使用的接口,在計(jì)算機(jī)接口中也占據(jù)著越來越明顯的優(yōu)勢。

Cypress公司的CY7C68013芯片內(nèi)部是增強(qiáng)型51單片機(jī),控制簡單,并實(shí)現(xiàn)了標(biāo)準(zhǔn)的USB1.1和USB2.0協(xié)議,而且成本較低,用于光纜檢測系統(tǒng)是一個(gè)很好的選擇,然而,其實(shí)現(xiàn)架構(gòu)較為復(fù)雜。本文重點(diǎn)分析和討論了其固件程序、驅(qū)動(dòng)程序等開發(fā)過程,實(shí)踐表明,本文的方法達(dá)到了預(yù)期設(shè)計(jì)目的,效果較好。

光纜檢測系統(tǒng)

圖1是光纜線路檢測硬件模塊框圖,由DTE接口單元、主控處理單元和PSTN接口單元組成。

DTE接口單元:提供了RS-232接口,USB接口。USB符合1.1和2.0協(xié)議。

主控處理單元:是系統(tǒng)的核心模塊。主要功能為:從DTE接口單元接收命令,并通過調(diào)制解調(diào)后發(fā)送到遠(yuǎn)端監(jiān)測站;從PSTN接口接收遠(yuǎn)端監(jiān)測站的信號,解調(diào)后發(fā)送到DTE。

PSTN接口單元:提供了分別用于輪詢和中斷兩路PSTN標(biāo)準(zhǔn)接口。

本文采用從底層到上層的結(jié)構(gòu)來敘述如何使USB設(shè)備完成光纜檢測系統(tǒng)和計(jì)算機(jī)之間數(shù)據(jù)傳輸?shù)幕竟δ堋?/p>

USB設(shè)備接口設(shè)計(jì)

USB設(shè)備接口設(shè)計(jì)主要包含兩方面的內(nèi)容:USB芯片和光纜檢測系統(tǒng)之間的接口;USB芯片和計(jì)算機(jī)之間的接口設(shè)計(jì)。其中USB芯片和光纜檢測系統(tǒng)之間的接口可分為固件配置程序設(shè)計(jì)和接口時(shí)序設(shè)計(jì);USB芯片和計(jì)算機(jī)之間的接口可分為驅(qū)動(dòng)程序設(shè)計(jì)以及驅(qū)動(dòng)程序和應(yīng)用程序之間的通信。

固件配置程序

USB傳輸類型包括中斷傳輸(interrupt)、批量傳輸(bulk)、等時(shí)傳輸(iso)、控制傳輸(control)四種類型,四種類型的相關(guān)特性:數(shù)據(jù)最大長度、數(shù)據(jù)周期性、發(fā)生錯(cuò)誤是否重傳、可得到的最大帶寬等都存在較大區(qū)別。根據(jù)光纜檢測系統(tǒng)和計(jì)算機(jī)之間數(shù)據(jù)交互的特點(diǎn),CY7C68013被配置為slave、異步、bulk模式。圖2是固件程序的框架結(jié)構(gòu),只完成數(shù)據(jù)讀寫的功能,不對數(shù)據(jù)進(jìn)行任何處理。

要實(shí)現(xiàn)最基本的數(shù)據(jù)讀寫功能只需要在TD_Init函數(shù)中進(jìn)行配置,由于篇幅原因這里僅列舉比較重要的一些寄存器的配置情況(表1)。

這里僅僅配置了端點(diǎn)2和端點(diǎn)6,端點(diǎn)2配置為寫設(shè)備地址,端點(diǎn)6配置為讀設(shè)備地址,兩個(gè)端點(diǎn)都設(shè)置為4個(gè)緩沖區(qū),緩沖區(qū)大小設(shè)置為512bytes,兩個(gè)端口都設(shè)置為自動(dòng)方式,這樣設(shè)置可以使得讀寫數(shù)據(jù)非常方便,大大減少開發(fā)時(shí)間和復(fù)雜性。

接口時(shí)序設(shè)計(jì)

異步slavefifo寫時(shí)序設(shè)計(jì)

外部主控器進(jìn)程如下:

IDLE:當(dāng)寫事件發(fā)生時(shí),轉(zhuǎn)到狀態(tài)1。

狀態(tài)1:指向IN FIFO,激活FIFOADR[1:O],轉(zhuǎn)向狀態(tài)2。

狀態(tài)2:如果FIFO滿標(biāo)志為1(1:FIFO不滿;0:FIFO滿),則轉(zhuǎn)向狀態(tài)3,否則停留在狀態(tài)2。

狀態(tài)3:傳送總線驅(qū)動(dòng)數(shù)據(jù)。傳送一個(gè)數(shù)據(jù),激活SLWR,轉(zhuǎn)向狀態(tài)4。

狀態(tài)4:如果有更多的數(shù)據(jù)要寫,則轉(zhuǎn)向狀態(tài)2,否則轉(zhuǎn)向IDLE。

實(shí)現(xiàn)異步從屬FIFO讀和實(shí)現(xiàn)異步從屬FIFO寫大同小異,這里不再贅述。

驅(qū)動(dòng)程序設(shè)計(jì)

驅(qū)動(dòng)程序設(shè)計(jì)主要包括驅(qū)動(dòng)程序設(shè)計(jì)、用來安裝驅(qū)動(dòng)程序的inf文件設(shè)計(jì)。Cypress公司為了使用戶使用簡單,已經(jīng)完成了大部分工作,用戶只需要對其驅(qū)動(dòng)程序和inf文件作一些必要的修改就可以實(shí)現(xiàn)需要的功能。用戶可以去掉Cypress公司提供的部分不需要的功能,同時(shí)需要對USB設(shè)備描述符、配置描述符、接口描述符、端點(diǎn)描述符和串描述符進(jìn)行修改。

固件驅(qū)動(dòng)程序的功能是使計(jì)算機(jī)認(rèn)識自己的USB設(shè)備,因此需要對設(shè)備進(jìn)行固件程序配置,固件配置程序可以在Cypress公司提供的框架下進(jìn)行修改,主要是對端點(diǎn)和選擇模式相關(guān)的寄存器進(jìn)行配置,然后通過提供的hex2c將生成的十六進(jìn)制文件轉(zhuǎn)換為一個(gè)數(shù)組,并將該數(shù)組替換驅(qū)動(dòng)程序中的firmware[],用DDK進(jìn)行編譯產(chǎn)生固件驅(qū)動(dòng)程序。計(jì)算機(jī)通過搜索注冊表中的設(shè)備VID和PID來識別USB,如果存在EEPROM或者是FLASH,則這個(gè)VID和PID可以開發(fā)人員自己定制。如果沒有EEPROM則VID必須為04b4,PID必須為8613,否則設(shè)備將無法被識別。

下載固件驅(qū)動(dòng)程序后,需要下載通用驅(qū)動(dòng)程序,通用驅(qū)動(dòng)程序可以完成需要設(shè)備完成的一系列功能。通用驅(qū)動(dòng)程序可以直接使用Cypress公司提供的通用驅(qū)動(dòng)程序。配置的時(shí)候VID和PID必須和inf文件中通用驅(qū)動(dòng)程序的VID和PID一致。

lnf文件的編寫

所有的USB設(shè)備都至少具有一個(gè)VID和PID,VID和PID通過設(shè)備描述符表提交給Windows系統(tǒng),同時(shí),Windows系統(tǒng)使用INF文件將某一個(gè)VID和PID綁定到某一設(shè)備驅(qū)動(dòng)程序。這樣,Windows系統(tǒng)在知道了設(shè)備的VID和PID后,就通過存儲在INF文件中的信息查找該設(shè)備的驅(qū)動(dòng)程序。第一次安裝后,VID和PID信息就保存在注冊表中,以后當(dāng)該設(shè)備重新插上時(shí),系統(tǒng)就會在注冊表中很快的查找該設(shè)備的驅(qū)動(dòng)程序信息。

固件驅(qū)動(dòng)程序的VID和PID必須為04b4和8613(如果有EEPROM則可以定制),固件驅(qū)動(dòng)程序主要是用來自動(dòng)加載固件配置;通用驅(qū)動(dòng)程序的VID和PID必須和固件程序中配置的一致;

讀寫測試的C語言程序

操作設(shè)備之前需要安裝驅(qū)動(dòng)程序,此時(shí)需要把sys文件和inf文件分別拷貝到系統(tǒng)文件夾system32\drivers和inf下,然后依次選擇驅(qū)動(dòng)程序目錄文件進(jìn)行安裝即可,驅(qū)動(dòng)程序安裝成功后就可以對設(shè)備進(jìn)行訪問。訪問過程通常分為三個(gè)階段:打開設(shè)備、操作設(shè)備、關(guān)閉設(shè)備。

打開設(shè)備可以通過符號鏈接名方式,用CreateFile函數(shù)可以以同步方式打開設(shè)備,獲取設(shè)備句柄。操作設(shè)備通過DeviceIoControl函數(shù)可以完成,由于接口時(shí)鐘不同,所以要用異步方式對設(shè)備進(jìn)行讀寫,否則設(shè)備讀寫將會出現(xiàn)錯(cuò)誤;讀取設(shè)備時(shí)采用直接程序控制方式,即CPU不斷查詢設(shè)備的FULL狀態(tài)位,當(dāng)有數(shù)據(jù)到達(dá)時(shí)該位變?yōu)榈碗娖剑珻PU就開始讀取數(shù)據(jù)。設(shè)備操作完成后通過CloseHandle函數(shù)關(guān)閉設(shè)備句柄。

第6篇

    通用串行總線(Universal Serial Bus,即USB)以其方便的即插即用和熱插拔特性,以及較高的傳輸速率,成為PC領(lǐng)域廣為應(yīng)用的外設(shè)連接規(guī)范。目前,國內(nèi)外普遍采用的是USB1.1規(guī)范,它支持兩種傳輸速率:1.5Mbps和12Mbps,主要應(yīng)用在低速傳輸要求的場合。2000年的USB2.0規(guī)范提供了480Mbs的傳輸速率,以滿足更快的數(shù)據(jù)傳輸要求。

    為了使MPEG視頻卡快速地向PC機(jī)傳送大量的數(shù)據(jù),我們在設(shè)計(jì)MPEG視頻卡與PC機(jī)的接口時(shí)采用USB2.0技術(shù)。對USB的設(shè)計(jì)與開發(fā),我們是基于CYPRESS公司的EZ-USB FX2系列的CY7C68013芯片及其FX2開發(fā)包。

    1、 硬件設(shè)計(jì)

    傳統(tǒng)的采用PCI接口的MPEG視頻卡, 不但占用了有限的PCI插槽,安裝不方便,而且不支持熱插拔和即插即用。所以,在本設(shè)計(jì)中,我們選用USB2.0接口芯片對傳統(tǒng)的MPEG視頻卡進(jìn)行了改進(jìn)。

    改進(jìn)后的USB2.0接口的方案如圖1所示。

   

    該USB2.0接口的MPEG視頻卡的工作原理為:音視頻信號經(jīng)AK4550音頻處理芯片及AA7113視頻處理芯片進(jìn)行A/D轉(zhuǎn)換,將模擬信號轉(zhuǎn)換成8bit的PCM格式的數(shù)字信號,傳入SZ1510音視頻壓縮采集芯片進(jìn)行處理,將編碼調(diào)制PCM格式的數(shù)據(jù)轉(zhuǎn)化為符合格式MPEG-1的混合影視文件,最后MPEG-1數(shù)據(jù)經(jīng)USB接口芯片送給PC機(jī)作進(jìn)一步的處理,如存儲、顯示等。

    設(shè)計(jì)中,我們選用的USB接口芯片是EZ-USB FX2 系列的CY7C68013芯片。該芯片是針對USB2.0的,而且和USB1.1兼容,它支持兩種傳輸速率:全速(Full_speed)12Mbps和高速(High_speed)480Mbps,它不支持低速(Low_speed)1.5Mbps。該芯片的內(nèi)部結(jié)構(gòu)如圖2所示。

    CY7C68013-128AC內(nèi)部集成了一個(gè)增強(qiáng)的8051內(nèi)核,它既與標(biāo)準(zhǔn)的8051兼容,又有諸多的改進(jìn):最高工作頻率48MHZ,一個(gè)指令周期只需4個(gè)時(shí)鐘周期,比標(biāo)準(zhǔn)的8051平均提高了2.5倍;2個(gè)UARTS端口;3個(gè)定時(shí)/記數(shù)器;擴(kuò)展的中斷系統(tǒng)及其更多I/O口等。CY7C68013內(nèi)部集成的USB2.0的SIE能完成大部分USB2.0協(xié)議的處理工作,減少了用戶對繁雜的USB協(xié)議的處理。另外,用戶在開發(fā)時(shí),可以利用GPIF和FIFO方式實(shí)現(xiàn)與高速外圍設(shè)備之間的邏輯連接,并進(jìn)行高速數(shù)據(jù)的傳輸。在該改進(jìn)方案中,我們選用的是GPIF方式,實(shí)現(xiàn)和Z1510之間的通信。

    2、 軟件設(shè)計(jì)

    USB 軟件設(shè)計(jì)包括三方面的工作:固件(Fireware)設(shè)計(jì),驅(qū)動(dòng)程序設(shè)計(jì)和主機(jī)端應(yīng)用程序的設(shè)計(jì)。

    (1) 固件設(shè)計(jì)

    設(shè)計(jì)中,我們考慮到MPEG視頻卡要求快速地持續(xù)地傳送大量數(shù)據(jù),并對數(shù)據(jù)的完整性要求不太高,我們采用ISO傳輸方式。另外,我們讓CY7C68013工作在GPIF模式下的FIFO Read方式,最多可以傳輸4G byte(WORDWIDE=0)或word(WORDWIDE=1)。外設(shè)的數(shù)據(jù)由于不需8051的處理,我們采用自動(dòng)打包的方式(AUTOIN=1),直接從FIFO到SIE,這樣有利于提高傳輸速率。其主要實(shí)現(xiàn)代碼如下:

void  TD_Init( )

{

CPUCS = 0X01;   

file://CLKSPD[1:0]=10; for 48MHz operation.

GpifInit( );

   ……

SYNCDELAY;

EP6CFG = 0XDA; 

file://端點(diǎn)配置: 同步IN方式、緩沖大小1024字節(jié)

SYNCDELAY;

FIFORESET = 0X80; 

// activate NAK_ALL to avoid race conditions

SYNCDELAY;

FIFORESET = 0X06;    file://reset, FIFO 6

SYNCDELAY;

FIFORESET = 0X00;    file://deactivate NAK_ALL

SYNCDELAY;

EP6FIFOCFG = 0X0D;   file://wordwide=1

SYNCDELAY;

……

}

    (2) 驅(qū)動(dòng)程序設(shè)計(jì)

    在WINDOWS平臺下,USB 驅(qū)動(dòng)程序由三部分組成:USB設(shè)備驅(qū)動(dòng)程序,USB總線驅(qū)動(dòng)程序和USB主控制器驅(qū)動(dòng)程序,它們必須遵循WIN32驅(qū)動(dòng)程序模型(WDM)。其中,WINDOWS操作系統(tǒng)已經(jīng)提供了處于驅(qū)動(dòng)程序棧底的USB總線驅(qū)動(dòng)程序和USB主控制器驅(qū)動(dòng)程序。而USB設(shè)備驅(qū)動(dòng)程序由設(shè)備開發(fā)者編寫,它通過向USB總線驅(qū)動(dòng)程序發(fā)送包含URB(USB  Request Block)的IRP(I/O Request Packet),來實(shí)現(xiàn)USB外設(shè)之間的信息交換。當(dāng)主機(jī)應(yīng)用程序要對USB設(shè)備進(jìn)行I/O操作時(shí),它調(diào)用Windows API函數(shù)對Win32子系統(tǒng)進(jìn)行Win32調(diào)用,由I/O管理器將此請求構(gòu)造成一個(gè)合適的IRP,并把它傳遞給USB設(shè)備驅(qū)動(dòng)程序。USB設(shè)備驅(qū)動(dòng)程序接受到這個(gè)IRP后,根據(jù)IRP中包含的具體操作代碼,構(gòu)造響應(yīng)的URB并把它放到一個(gè)新IRP中,然后把此IRP傳遞到USB總線驅(qū)動(dòng)程序,USB總線驅(qū)動(dòng)程序根據(jù)IRP中所包含的URB執(zhí)行響應(yīng)的操作,并把操作結(jié)果通過IRP返還給USB設(shè)備驅(qū)動(dòng)程序。USB設(shè)備驅(qū)動(dòng)程序接受到此IRP后,將操作結(jié)果通過IRP返還I/O管理器。最后,I/O管理器將此IRP中操作結(jié)果返還給應(yīng)用程序,至此應(yīng)用程序?qū)SB設(shè)備的一次I/O操作完成。

    開發(fā)USB設(shè)備驅(qū)動(dòng)程序,可采用Numega公司的開發(fā)包Driver Works和 Microsoft公司的2000DDK,并以VC++6.0作為輔助開發(fā)環(huán)境。Driver Works提供的驅(qū)動(dòng)向?qū)?,可根據(jù)用戶的需要,自動(dòng)生成代碼框架。減少了開發(fā)的難度,縮短了開發(fā)的周期。

    在CYPRESS公司的EZ-USB FX2開發(fā)包中,有一個(gè)通用的驅(qū)動(dòng)程序,該程序可不加修改經(jīng)DDK編譯后直接使用。在本設(shè)計(jì)中,由于時(shí)間關(guān)系,我們采用的就是這個(gè)通用驅(qū)動(dòng)程序(GPD)。

    (3) 應(yīng)用程序設(shè)計(jì)

    USB主機(jī)應(yīng)用程序是計(jì)算機(jī)中完成特定功能的程序,其關(guān)鍵是實(shí)現(xiàn)從USB 外設(shè)讀取或發(fā)送特定數(shù)量的數(shù)據(jù),USB標(biāo)準(zhǔn)設(shè)備請求和特定的命令等。另外,可以對數(shù)據(jù)做進(jìn)一步的處理,如:存儲、顯示、快速傅立葉變換等。在WINDOWS 2000下,我們所使用的應(yīng)用程序開發(fā)工具是VC++6.0。

第7篇

關(guān)鍵字:JDBC;數(shù)據(jù)庫;MySql

Java數(shù)據(jù)庫連接(JDBC)由一組用 Java 編程語言編寫的類和接口組成。JDBC 為工具/數(shù)據(jù)庫開發(fā)人員提供了一個(gè)標(biāo)準(zhǔn)的 API,使他們能夠用純Java API 來編寫數(shù)據(jù)庫應(yīng)用程序。然而各個(gè)開發(fā)商的接口并不完全相同,所以開發(fā)環(huán)境的變化會帶來一定的配置變化。

一、連接各種數(shù)據(jù)庫方式速查表

下面羅列了各種數(shù)據(jù)庫使用JDBC連接的方式,可以作為一個(gè)手冊使用。

1. Oracle8/8i/9i數(shù)據(jù)庫(thin模式)

Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();

String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl為數(shù)據(jù)庫的SID

String user="test"; String password="test";

Connection conn= DriverManager.getConnection(url,user,password);

2. DB2數(shù)據(jù)庫

Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();

String url="jdbc:db2://localhost:5000/sample"; //sample為你的數(shù)據(jù)庫名

String user="admin"; String password="";

Connection conn= DriverManager.getConnection(url,user,password);

3. Sql Server7.0/2000數(shù)據(jù)庫

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();

String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";String user="sa"; String password="";

Connection conn= DriverManager.getConnection(url,user,password);

4. Sybase數(shù)據(jù)庫

Class.forName("com.sybase.jdbc.SybDriver").newInstance();

String url =" jdbc:sybase:Tds:localhost:5007/myDB";//myDB為你的數(shù)據(jù)庫名

Properties sysProps = System.getProperties();

SysProps.put("user","userid");

SysProps.put("password","user_password");

Connection conn= DriverManager.getConnection(url, SysProps);

5. MySQL數(shù)據(jù)庫

Class.forName("org.gjt.mm.mysql.Driver").newInstance(); String url="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" //myDB 為數(shù)據(jù)庫名

Connection conn= DriverManager.getConnection(url);

6. access數(shù)據(jù)庫直連用ODBC的

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ;

String url="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb");

Connection conn = DriverManager.getConnection(url,"","");

Statement stmtNew=conn.createStatement() ;

二、JDBC連接MySql方式

下面是使用JDBC連接MySql的一個(gè)小的教程

1. 查找驅(qū)動(dòng)程序

MySQL目前提供的java驅(qū)動(dòng)程序?yàn)镃onnection/J,可以從MySQL官方網(wǎng)站下載,并找到mysql-connector-java-3.0.15-ga-bin.jar文件,此驅(qū)動(dòng)程序?yàn)榧僯ava驅(qū)動(dòng)程序,不需做其他配置。

2. 動(dòng)態(tài)指定classpath

如果需要執(zhí)行時(shí)動(dòng)態(tài)指定classpath,就在執(zhí)行時(shí)采用-cp方式。否則將上面的.jar文件加入到classpath環(huán)境變量中。

3. 加載驅(qū)動(dòng)程序

trClass.forName(com.mysql.jdbc.Driver);

System.out.println(Success loading Mysql Driver!);

}catch(Exception e){System.out.println(Error loading Mysql Driver!);e.printStackTrace();}

4. 設(shè)置連接的url

jdbc:mysql://localhost/databasename[?pa=va][&pa=va]

三、以下列出了在使用JDBC來連接Oracle數(shù)據(jù)庫時(shí)可以使用的一些技巧

1. 在客戶端軟件開發(fā)中使用Thin驅(qū)動(dòng)程序

在開發(fā)Java軟件方面,Oracle的數(shù)據(jù)庫提供了四種類型的驅(qū)動(dòng)程序,二種用于應(yīng)用軟件、applets、servlets等客戶端軟件,另外二種用于數(shù)據(jù)庫中的Java存儲過程等服務(wù)器端軟件。在客戶機(jī)端軟件的開發(fā)中,我們可以選擇OCI驅(qū)動(dòng)程序或Thin驅(qū)動(dòng)程序。OCI驅(qū)動(dòng)程序利用Java本地化接口(JNI),通過Oracle客戶端軟件與數(shù)據(jù)庫進(jìn)行通訊。Thin驅(qū)動(dòng)程序是純Java驅(qū)動(dòng)程序,它直接與數(shù)據(jù)庫進(jìn)行通訊。為了獲得最高的性能,Oracle建議在客戶端軟件的開發(fā)中使用OCI驅(qū)動(dòng)程序,這似乎是正確的。但我建議使用Thin驅(qū)動(dòng)程序,因?yàn)橥ㄟ^多次測試發(fā)現(xiàn),在通常情況下,Thin驅(qū)動(dòng)程序的性能都超過了OCI驅(qū)動(dòng)程序。

2. 關(guān)閉自動(dòng)提交功能,提高系統(tǒng)性能

在第一次建立與數(shù)據(jù)庫的連接時(shí),在缺省情況下,連接是在自動(dòng)提交模式下的。為了獲得更好的性能,可以通過調(diào)用帶布爾值false參數(shù)的Connection類的setAutoCommit()方法關(guān)閉自動(dòng)提交功能。

3. 在動(dòng)態(tài)SQL或有時(shí)間限制的命令中使用Statement對象

在執(zhí)行SQL命令時(shí),我們有二種選擇:可以使用PreparedStatement對象,也可以使用Statement對象。無論多少次地使用同一個(gè)SQL命令,PreparedStatement都只對它解析和編譯一次。當(dāng)使用Statement對象時(shí),每次執(zhí)行一個(gè)SQL命令時(shí),都會對它進(jìn)行解析和編譯。這可能會使你認(rèn)為,使用PreparedStatement對象比使用Statement對象的速度更快。然而,我進(jìn)行的測試表明,在客戶端軟件中,情況并非如此。因此,在有時(shí)間限制的SQL操作中,除非成批地處理SQL命令,我們應(yīng)當(dāng)考慮使用Statement對象。

第8篇

【摘要】 我們從軟件技術(shù)的角度,論述了在Windows XP環(huán)境下基于PCI總線數(shù)據(jù)采集卡實(shí)現(xiàn)實(shí)時(shí)測控所需要的關(guān)鍵技術(shù)、軟件體系結(jié)構(gòu)和開發(fā)方法。遵循本文所討論的技術(shù)路線,開發(fā)了DFQ系列多方位牽引床的測控軟件,提高了被控系統(tǒng)的控制精度和可靠性,增強(qiáng)了系統(tǒng)的可用性。

【關(guān)鍵詞】 PCI總線;WDM設(shè)備驅(qū)動(dòng)程序;軟件體系結(jié)構(gòu);計(jì)算機(jī)測量與控制

Abstract:The key techniques, software architecture and development method used to implement real-time measurement and control based on PCI bus data acquisition card in Windows XP environment are discussed from the viewpoint of software technology. The measurement and control software for DFQ multidimensional traction bed are developed according to the techniques provided in this paper,the precision, high reliability and better usability of the object system are improved.

Key words:PCI Bus;WDM device driver;Software architecture;Computer measurement and control

1 引 言

計(jì)算機(jī)測控技術(shù)在生產(chǎn)實(shí)踐中有著廣泛的應(yīng)用。基于計(jì)算機(jī)技術(shù)的測控系統(tǒng)主要分為兩種類型。一類是以各種單片機(jī)、可編程邏輯芯片為核心組成的測控系統(tǒng),這類測控系統(tǒng)一般適用于功能要求相對簡單的被控對象,可獨(dú)立構(gòu)成測控系統(tǒng),或以PC機(jī)作為上位機(jī)構(gòu)成兩級級聯(lián)的測控系統(tǒng),此時(shí)PC機(jī)一般負(fù)責(zé)界面處理。一類是以PC機(jī)為核心構(gòu)成的測控系統(tǒng),PC機(jī)通過數(shù)據(jù)采集卡及接口電路連接到被控對象。由于PC機(jī)具有高性能、易用性、可擴(kuò)展性和豐富的軟件資源等,此類系統(tǒng)可適用于功能要求較為復(fù)雜的被控對象。

Windows XP是一個(gè)多任務(wù)的并能夠滿足實(shí)時(shí)要求的操作系統(tǒng),是目前PC機(jī)普遍采用的操作系統(tǒng)之一。PCI總線是高性能的局部總線,支持高速數(shù)據(jù)傳輸,是PC機(jī)上流行的總線接口標(biāo)準(zhǔn)。我們從軟件技術(shù)的角度,討論了在Windows XP操作系統(tǒng)下,基于PCI總線數(shù)據(jù)采集卡,在工業(yè)現(xiàn)場實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)測控的關(guān)鍵技術(shù),包括實(shí)時(shí)I/O端口讀寫和定時(shí)數(shù)據(jù)采集的實(shí)現(xiàn)方法。本研究的技術(shù)已成功應(yīng)用于DFQ多方位牽引床的軟件研發(fā),取得了良好的效果。由于是在Windows XP操作系統(tǒng)下采用實(shí)時(shí)測控技術(shù),最終設(shè)計(jì)完成的牽引床系統(tǒng)功能豐富,控制精確,可靠性高,具有良好的用戶界面。

2 系統(tǒng)的關(guān)鍵點(diǎn)和技術(shù)難點(diǎn)

Windows XP是一個(gè)多用戶、多任務(wù)的操作系統(tǒng)。由于允許多個(gè)任務(wù)并發(fā)執(zhí)行以及允許多個(gè)用戶同時(shí)登錄操作系統(tǒng),安全性和穩(wěn)定性是Windows XP操作系統(tǒng)設(shè)計(jì)的主要目標(biāo)之一。在Windows XP操作系統(tǒng)下,計(jì)算機(jī)的運(yùn)行狀態(tài)被強(qiáng)制為用戶態(tài)和核心態(tài)兩種狀態(tài)。對于一個(gè)程序,在一個(gè)確定的時(shí)刻,要么在用戶態(tài)執(zhí)行,要么在核心態(tài)執(zhí)行。在用戶態(tài)運(yùn)行的程序處于系統(tǒng)最低的中斷請求級(interrupt request level,IRQL)上,隨時(shí)可以被具有更高中斷請求級的中斷請求所打斷[1]。因此,為了能夠在給定的時(shí)間約束內(nèi)發(fā)出控制信號和采集數(shù)據(jù),滿足系統(tǒng)的實(shí)時(shí)性要求,提高系統(tǒng)可靠性,必須使得測控程序能夠在核心態(tài)執(zhí)行。

其次,為了滿足自身的穩(wěn)定性,Windows XP將對硬件的訪問封裝在了系統(tǒng)底層。用戶態(tài)的應(yīng)用程序不能直接訪問硬件資源,包括讀寫I/O端口和內(nèi)存,響應(yīng)中斷,執(zhí)行DMA操作等。在Windows XP下,程序只有轉(zhuǎn)入核心態(tài),并通過系統(tǒng)調(diào)用才能直接訪問硬件資源。顯然,若能夠獲得直接訪問硬件的能力,則可明顯提高測控程序的實(shí)時(shí)性和效率。

綜上所述,在Windows XP操作系統(tǒng)下,測控軟件要獲得本質(zhì)上的實(shí)時(shí)性和高可靠性,必須具有在操作系統(tǒng)核心態(tài)運(yùn)行的能力。設(shè)備驅(qū)動(dòng)程序是Windows XP留給用戶的允許用戶獲得核心態(tài)運(yùn)行能力的唯一開發(fā)接口[1]。WDM(windows driver model)驅(qū)動(dòng)程序模型是Windows XP下的設(shè)備驅(qū)動(dòng)程序的模型之一,測控軟件可借助WDM驅(qū)動(dòng)程序?qū)崿F(xiàn)所要求的實(shí)時(shí)性和高可靠性。

3 系統(tǒng)組成和開發(fā)環(huán)境

如圖1所示,牽引床控制系統(tǒng)由PC機(jī)、PCI總線數(shù)據(jù)采集卡、外圍接口電路和牽引床四部分組成[2]。PCI總線數(shù)據(jù)采集卡是通用的標(biāo)準(zhǔn)模塊,可供選擇的產(chǎn)品很多,本系統(tǒng)使用凌華公司的PCI 9111數(shù)據(jù)采集卡[3]。接口電路完成模擬信號和數(shù)字信號的調(diào)理和傳輸。

系統(tǒng)測控程序由上層主程序和下層設(shè)備驅(qū)動(dòng)程序兩部分組成。主程序完成系統(tǒng)的總體邏輯功能和界面交互,運(yùn)行于操作系統(tǒng)的用戶態(tài)。設(shè)備驅(qū)動(dòng)程序采集數(shù)據(jù),完成牽引床的各種基本控制動(dòng)作,運(yùn)行于操作系統(tǒng)的核心態(tài)。主程序和驅(qū)動(dòng)程序之間通過事件通知的機(jī)制完成通信聯(lián)絡(luò),驅(qū)動(dòng)程序向下調(diào)用操作系統(tǒng)的系統(tǒng)服務(wù)完成基本控制動(dòng)作。

軟件開發(fā)環(huán)境由Windows XP DDK(Driver Develo

pment Kit)、DriverStudio 3.1和Visual C 6.0組成。Visual C 6.0是系統(tǒng)主程序和驅(qū)動(dòng)程序的集成開發(fā)調(diào)試環(huán)境,DriverStudio 3.1和Windows XP DDK用于編譯生成驅(qū)動(dòng)程序。

4 測控程序設(shè)計(jì)

我們本節(jié)論述測控程序設(shè)計(jì)的幾個(gè)關(guān)鍵問題,包括訪問PCI 9111數(shù)據(jù)采集卡,讀寫I/O端口,定時(shí)中斷的實(shí)現(xiàn)方法和主程序與驅(qū)動(dòng)程序的通信共四部分。

4.1 訪問PCI 9111數(shù)據(jù)采集卡

PCI 9111是一塊集成的多功能數(shù)據(jù)采集卡,具有數(shù)字量輸入輸出、模擬量輸入輸出、定時(shí)計(jì)數(shù)的基本功能,支持軟件查詢方式、中斷方式、DMA方式多種數(shù)據(jù)傳輸方式,AD采樣頻率最高支持100 KHz。PCI 9111板卡上使用PCI 9052[4]作為PCI總線接口芯片,支持PnP即插即用功能,用戶無需手工設(shè)置板卡使用的硬件資源(如IO基地址、中斷請求號等),這些硬件資源由計(jì)算機(jī)的PnP子系統(tǒng)自動(dòng)分配。用戶通過基地址BASE加偏移量的IO端口讀寫方式,訪問PCI 9111的各寄存器,實(shí)現(xiàn)對PCI 9111的控制命令寫入和數(shù)據(jù)輸入輸出。因此,要訪問PCI 9111,必須首先要獲得PnP子系統(tǒng)分配給PCI 9111的基地址。

根據(jù)PCI總線規(guī)范,PnP子系統(tǒng)分配給PCI設(shè)備的基地址,存儲在PCI接口芯片的BAR0~BAR5共六個(gè)PCI配置寄存器(PCI configuration registers,PCRs)中。對于PCI 9111板卡而言,BAR1中存儲的是PCI 9052芯片局部配置寄存器(local configuration registers,LCRs)的起始地址,BAR2中存儲的是局部地址空間0的基地址,即PCI 9111板卡寄存器的基地址BASE。

PnP子系統(tǒng)為PCI設(shè)備分配的硬件資源,由操作系統(tǒng)的PnP管理程序通知給PCI設(shè)備的設(shè)備驅(qū)動(dòng)程序。在DriverStudio的WDM設(shè)備驅(qū)動(dòng)程序框架下,該信息以IO請求包(Irp)的形式傳遞給驅(qū)動(dòng)程序設(shè)備類(是KPnpDevice的子類)的OnStartDevice()成員函數(shù)。在OnStartDevice()函數(shù)中,通過如圖2中的代碼,可獲得BAR1寄存器和BAR2寄存器的值。

NTSTATUS DfqDevice::OnStartDevice(KIrp I)

{

……

PCMRESOURCELIST pResListRaw=I.AllocatedResources();

PCMRESOURCELIST pResListTranslated=I.TranslatedResources();

KPciConfiguration PciConfig(mLower.TopOfStack());

//BAR1

mIoLCR.Initialize(pResListTranslated, pResListRaw,

PciConfig.BaseAddressIndexToOrdinal(1));

//BAR2

mIoPortRange.Initialize(pResListTranslated, pResListRaw,

PciConfig.BaseAddressIndexToOrdinal(2));

……

}

圖2 初始化mIoLCR和mIoPortRange

Fig 2 Initialization of mIoLCR and mIoPortRange

在圖2所示的代碼中,mIoLCR和mIoPortRange都是DfqDevice類的KIoRange類型的成員變量。圖2所示代碼實(shí)際上是使用BAR1和BAR2寄存器的值分別對mIoLCR和mIoPortRange進(jìn)行了初始化。mLower是DfqDevice類的KPnpLowerDevice類型的成員變量,該成員變量指向代表PCI設(shè)備的底層物理設(shè)備對象。

4.2 讀寫IO端口

一旦初始化mIoPortRange和mIoLCR,進(jìn)行IO端口讀寫就非常容易。使用KIoRange類的成員函數(shù)inx()/outx(),可完成對指定端口的讀寫,其中x可為b、w、d,分別表示8位數(shù)據(jù)、16位數(shù)據(jù)和32位數(shù)據(jù)。于是,調(diào)用m_IoPortRange對象的IO讀寫成員函數(shù),可訪問PCI 9111板卡的各寄存器;調(diào)用mIoLCR對象的IO讀寫成員函數(shù),可訪問PCI 9052芯片的各局部配置寄存器。參照PCI 9111的用戶手冊[3],就可以方便地完成PCI 9111數(shù)據(jù)采集卡的數(shù)字量輸入、數(shù)字量輸出、軟件查詢式AD轉(zhuǎn)換和模擬量輸出功能。

4.3 定時(shí)中斷

對于實(shí)時(shí)過程監(jiān)控,最為關(guān)鍵的是能夠定時(shí)檢測被控對象的狀態(tài),一旦達(dá)到預(yù)定義的條件,則發(fā)出相應(yīng)的控制命令。這就需要設(shè)備驅(qū)動(dòng)程序能夠提供精確的定時(shí)中斷。

PCI 9111板卡上提供了8254定時(shí)/計(jì)數(shù)器,可用于實(shí)現(xiàn)定時(shí)中斷。通過編程設(shè)置PCI 9111,可令8254定時(shí)/計(jì)數(shù)器的輸出作為中斷源發(fā)起定時(shí)中斷請求。在中斷服務(wù)程序內(nèi),可以完成AD數(shù)據(jù)采集(從而實(shí)現(xiàn)定時(shí)中斷式AD轉(zhuǎn)換)、數(shù)字量數(shù)據(jù)輸入輸出等各種定時(shí)執(zhí)行的任務(wù)。對于中斷式AD轉(zhuǎn)換,也可以編程設(shè)置PCI 9111,令8254定時(shí)/計(jì)數(shù)器的輸出作為AD轉(zhuǎn)換觸發(fā)信號,而AD轉(zhuǎn)換器的AD轉(zhuǎn)換結(jié)束信號作為中斷源發(fā)起中斷請求。由于AD轉(zhuǎn)換器是定時(shí)觸發(fā),此時(shí)亦可實(shí)現(xiàn)定時(shí)中斷式AD轉(zhuǎn)換。

要使得驅(qū)動(dòng)程序能夠響應(yīng)來自PCI 9111的硬件中斷,首先需要編寫在設(shè)備類里的中斷服務(wù)程序鏈接到PnP子系統(tǒng),分配給PCI 9111的中斷請求號(IRQ)上。代碼見圖3。

NTSTATUS DfqDevice::OnStartDevice(KIrp I)

{

……

mInterrupt.InitializeAndConnect(pResListTranslated, LinkTo(ISR), this);

……

}

圖3 鏈接中斷服務(wù)程序到系統(tǒng)分配的中斷請求號

Fig 3 Link interrupt service routine to interrupt request number of

system distribution

圖3的代碼中,mInterrupt是定義在DfqDevice類中的KInterrupt類型的中斷對象。ISR是DfqDevice類的成員函數(shù),即實(shí)際的中斷服務(wù)程序。

由于Windows XP是一個(gè)多任務(wù)的操作系統(tǒng),在編寫中斷服務(wù)程序時(shí),要考慮留給其他程序執(zhí)行的機(jī)會,因此,在中斷服務(wù)程序中,通常完成當(dāng)前最為緊迫的任務(wù)。由于多個(gè)物理設(shè)備可能共享同一個(gè)中斷請求號,因此在中斷服務(wù)程序中,首先判斷所響應(yīng)的中斷請求是否來自PCI 9111。若不是,則立即返回,以節(jié)省時(shí)間。然后清除硬件中斷,以便下一次中斷請求能夠正常產(chǎn)生(而不被阻塞)。然后針對具體被控對象的定時(shí)執(zhí)行的任務(wù)。

在DFQ牽引床控制軟件中,編程使PCI 9111板卡的8254定時(shí)技術(shù)芯片每160 μs產(chǎn)生一次中斷。在每次中斷中完成AD數(shù)據(jù)采集和數(shù)字量輸入,檢測當(dāng)前動(dòng)作的執(zhí)行情況。當(dāng)AD采樣值達(dá)到主程序設(shè)定要求時(shí),即牽引床動(dòng)作到位,中斷服務(wù)程序及時(shí)發(fā)出動(dòng)作結(jié)束信號。牽引床的每個(gè)動(dòng)作的執(zhí)行都在頻率為6 KHz的AD采樣監(jiān)視之下完成。首先,由于AD采樣頻率高,牽引床動(dòng)作(如距離、角度等)的執(zhí)行非常精確。牽引床動(dòng)作的實(shí)際誤差基本不受測控軟件的影響,而主要取決于牽引床本身的機(jī)械結(jié)構(gòu)所帶來的誤差。其次,由于牽引床的動(dòng)作控制信號是在設(shè)備驅(qū)動(dòng)程序中發(fā)出的,而設(shè)備驅(qū)動(dòng)程序具有比任何Windows線程更高的中斷請求級(IRQL),牽引床工作的可靠性明顯提高。在連續(xù)長時(shí)間的測試以及大量用戶的反饋中,牽引床系統(tǒng)幾乎沒有出現(xiàn)錯(cuò)誤動(dòng)作。

值得提出的是,由于PCI 9111的AD轉(zhuǎn)換頻率最高可達(dá)100 KHz,因此在實(shí)際使用中,8254的定時(shí)常數(shù)可以設(shè)置得比160 μs更低,如十微秒級,這樣可以完成對于更加快速控制過程的實(shí)時(shí)監(jiān)控。另外,在許多系統(tǒng)中,人們也使用Windows提供的軟件定時(shí)器或編寫已有驅(qū)動(dòng)程序的回調(diào)函數(shù)實(shí)現(xiàn)過程監(jiān)控,但這并不能從根本上滿足實(shí)時(shí)要求。其原因?yàn)椋海?)軟件定時(shí)器工作在用戶態(tài),不具有嚴(yán)格的實(shí)時(shí)性。(2)由于受Windows操作系統(tǒng)線程調(diào)度模型的制約,軟件定時(shí)器和回調(diào)函數(shù)只能實(shí)現(xiàn)毫秒級或十毫秒級的定時(shí),不能滿足高速的實(shí)時(shí)測控要求。因此,設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)的方法保證了數(shù)據(jù)采集和過程監(jiān)控的實(shí)時(shí)性、高精度和可靠性。

4.4 主程序和設(shè)備驅(qū)動(dòng)程序的通信

主程序和設(shè)備驅(qū)動(dòng)程序是功能相對獨(dú)立的兩個(gè)程序,它們之間通過通信聯(lián)絡(luò)完成控制命令和數(shù)據(jù)的傳輸。主程序和設(shè)備驅(qū)動(dòng)程序之間通信的典型方法有異步IO、事件通知等[3,5]。DFQ牽引床系統(tǒng)采用事件通知的方法完成主程序和設(shè)備驅(qū)動(dòng)程序之間的通信。

在此,以牽引床的一個(gè)基本動(dòng)作的執(zhí)行過程為例,說明主程序和設(shè)備驅(qū)動(dòng)程序之間的通信。首先,主程序調(diào)用SDK函數(shù) CreateEvent(NULL, FALSE, FALSE, NULL)創(chuàng)建事件句柄hEvent,其中第二個(gè)參數(shù)FALSE表示所創(chuàng)建的事件為自動(dòng)重置事件,第三個(gè)參數(shù)FALSE表示事件的初始狀態(tài)為無信號狀態(tài)。然后主程序調(diào)用SDK函數(shù)DeviceIoControl()向設(shè)備驅(qū)動(dòng)程序發(fā)出控制命令,命令參數(shù)中含有事件句柄hEvent。最后,主程序調(diào)用SDK函數(shù)WaitForSingleObject()等待事件hEvent變?yōu)橛行盘枲顟B(tài),從而主程序線程進(jìn)入阻塞狀態(tài)。設(shè)備驅(qū)動(dòng)程序在控制命令處理函數(shù)中通過new(NonPagedPool) KEvent(hEvent, OBJECTTYPEALLACCESS)創(chuàng)建KEvent類對象pEvent,然后啟動(dòng)動(dòng)作執(zhí)行,并中斷對動(dòng)作進(jìn)行定時(shí)監(jiān)控。當(dāng)檢測到動(dòng)作執(zhí)行到位(或遇到異常情況中止)后,設(shè)備驅(qū)動(dòng)程序調(diào)用pEvent->Set()將事件對象hEvent設(shè)置為有信號狀態(tài)。此時(shí)主程序線程作系統(tǒng)喚醒,繼續(xù)向下執(zhí)行。主程序可進(jìn)一步訪問設(shè)備驅(qū)動(dòng)程序獲得動(dòng)作的執(zhí)行情況以做出相應(yīng)的處理。

事件通知的方法,在保證牽引床動(dòng)作執(zhí)行的實(shí)時(shí)性、可靠性和精確性的同時(shí),還符合多任務(wù)系統(tǒng)的設(shè)計(jì)原則,主程序和設(shè)備驅(qū)動(dòng)程序并不會持續(xù)長時(shí)間獨(dú)占CPU而影響計(jì)算機(jī)整體性能。這是因?yàn)椋?1)在牽引床動(dòng)作執(zhí)行期間,主程序因調(diào)用WaitForSingleObject()而一直處于阻塞狀態(tài),并沒有獲得執(zhí)行。(2)在牽引床動(dòng)作執(zhí)行期間,設(shè)備驅(qū)動(dòng)程序通過定時(shí)中斷的方法,只是每隔設(shè)定的一段時(shí)間(在牽引床系統(tǒng)中設(shè)置為160 μs),檢測一次動(dòng)作的執(zhí)行情況,設(shè)備驅(qū)動(dòng)程序也沒有在動(dòng)作執(zhí)行期間獨(dú)占CPU。這樣,CPU就會有充足的時(shí)間執(zhí)行其他的程序。于是,可在主程序中進(jìn)一步使用多線程技術(shù),實(shí)現(xiàn)更為復(fù)雜的邏輯控制功能。如牽引床的快速牽引、復(fù)合牽引等各種治療功能就是使用多線程技術(shù)實(shí)現(xiàn)的。

5 結(jié)束語

本研究從操作系統(tǒng)底層的角度,對Windows XP操作系統(tǒng)的實(shí)時(shí)測控技術(shù)進(jìn)行了研究和探討。通過WDM設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)的方法,使程序獲得在系統(tǒng)核心態(tài)執(zhí)行的能力,從而實(shí)現(xiàn)實(shí)時(shí)過程監(jiān)控。以DFQ牽引床系統(tǒng)為例,剖析了在Windows XP操作系統(tǒng)下,基于PCI總線數(shù)據(jù)采集卡進(jìn)行實(shí)時(shí)過程監(jiān)控的關(guān)鍵技術(shù)。遵循本文的技術(shù)路線,我們設(shè)計(jì)了DFQ牽引床系統(tǒng)的測控軟件,產(chǎn)品質(zhì)量檢測和實(shí)際應(yīng)用均表明,DFQ牽引床工作可靠性高,動(dòng)作完成精確到位,測控軟件具有良好的易用性。本研究所論述的實(shí)時(shí)測控技術(shù)可適用于一般的控制系統(tǒng)。

參考文獻(xiàn)

[1]尤晉元,史美林.Windows操作系統(tǒng)原理[M]. 北京:機(jī)械工業(yè)出版社,2001.

[2]劉傳永,張明,王艷萍,等.雙中心重合式脊柱治療機(jī)的研制[J].生物醫(yī)學(xué)工程研究,2006,25(1):55-57

[3]ADLINK Technology.PCI-9111 DG/HR multi-functions data acquisition card User's guide[EB/OL].adlinktech.com/PD/Download/adlinktechnology-index.php.2008-01-10.

[4]武安河,邰銘,于洪濤.Windows 2000/XP WDM設(shè)備驅(qū)動(dòng)程序開發(fā)[M]. 北京:電子工業(yè)出版社,2003.

第9篇

由于工作關(guān)系,我經(jīng)常涉及PC機(jī)與設(shè)備接口的工作,從PC機(jī)這方面要做的工作看來,主要是通過接口處理設(shè)備的中斷,通過I/O端口或內(nèi)存地址與外設(shè)互相傳遞數(shù)據(jù)。從計(jì)算機(jī)原理的角度看,所要達(dá)到的目的很簡單,那么如何編寫程序完成上述功能呢?

目前國內(nèi)流行的PC操作系統(tǒng)有三種:DOS,Win95/98系列,WindowsNT。DOS是單用戶、單任務(wù)操作系統(tǒng),由于PC機(jī)硬件處理速度不斷提高,基于單用戶、單任務(wù)的操作系統(tǒng)越來越不能充分發(fā)揮硬件的功能,現(xiàn)在只應(yīng)用于一些老式PC及其它個(gè)別場合,有逐漸被淘汰的趨勢;Win95/98系列和WindowsNT屬于多任務(wù)操作系統(tǒng),不論從其原理還是界面上看,這兩種操作系統(tǒng)都比DOS有著無可比擬的優(yōu)越性,這兩種操作系統(tǒng)雖然在界面和操作上及其相似,但其內(nèi)部實(shí)現(xiàn)的諸多方面有許多區(qū)別,有些區(qū)別是本質(zhì)上的。Win95/98設(shè)計(jì)目標(biāo)是針對一般家庭用戶,安全性及可靠性存在許多薄弱環(huán)節(jié),就可靠性而言,Win95/98系列不能很好的防止多任務(wù)環(huán)境中某個(gè)進(jìn)程的非法操作導(dǎo)致系統(tǒng)中其它程序甚至整個(gè)系統(tǒng)的崩潰,而WindowsNT在這方面及其它諸多方面設(shè)計(jì)的相當(dāng)嚴(yán)謹(jǐn)。這兩種操作系統(tǒng)是Microsoft公司同一時(shí)期的產(chǎn)品,但針對不同的使用群,所以在一些重要場合及生產(chǎn)實(shí)踐中應(yīng)該選擇WindowsNT作為計(jì)算機(jī)的操作系統(tǒng),此外,從發(fā)展趨勢來看,WindowsNT已經(jīng)成為定型產(chǎn)品,具有相對穩(wěn)定性。

在不同操作系統(tǒng)下編寫驅(qū)動(dòng)程序是有很大區(qū)別的,在DOS平臺上,應(yīng)用程序和設(shè)備驅(qū)動(dòng)程序之間沒有標(biāo)準(zhǔn)的接口,它們在外部表現(xiàn)為一個(gè)擴(kuò)展名為EXE的文件,驅(qū)動(dòng)程序的作用被柔和在應(yīng)用程序中,這樣,應(yīng)用程序?yàn)榱耸褂貌煌瑥S商的同一類設(shè)備,必須了解這些設(shè)備在接口上具體的硬件實(shí)現(xiàn),同時(shí),對于一個(gè)特定型號的硬件產(chǎn)品,所有支持它的應(yīng)用軟件中對于控制整個(gè)設(shè)備動(dòng)作的這部分代碼,可能被多次重寫。這種情況不適應(yīng)硬件及應(yīng)用軟件的飛速發(fā)展。Windows系統(tǒng)在這方面,進(jìn)行了根本性改進(jìn),把控制設(shè)備動(dòng)作的這部分代碼獨(dú)立出來,提出了設(shè)備驅(qū)動(dòng)程序的概念,驅(qū)動(dòng)程序是應(yīng)用程序和硬件設(shè)備之間的一個(gè)橋梁,應(yīng)用程序與驅(qū)動(dòng)程序之間有明確的接口,應(yīng)用程序通過與驅(qū)動(dòng)程序交換信息,達(dá)到控制外設(shè)的目的。接口定義的操作是面向設(shè)備的,這就是說,在應(yīng)用程序的設(shè)計(jì)中,并不用關(guān)心對外設(shè)操作的具體硬件實(shí)現(xiàn),只是對驅(qū)動(dòng)程序發(fā)出一系列指令既可;驅(qū)動(dòng)程序接受來自上層應(yīng)用程序的指示,具體操縱實(shí)際硬件,完成用戶功能。具體實(shí)現(xiàn)上,Win95/98系列與WindowsNT又有所區(qū)別,WindowsNT是嚴(yán)格按照上述思路設(shè)計(jì)的;而Win95/98系列不那么嚴(yán)格,其支持上述思路,但同時(shí)應(yīng)用程序也可以繞過驅(qū)動(dòng)程序直接訪問實(shí)際物理I/O,這樣做,增加程序設(shè)計(jì)的靈活性,但同時(shí),對系統(tǒng)可靠性造成一定隱患。這也正是Win95/98系列可靠性低于WinNT的原因之一。

WindowsNT設(shè)備驅(qū)動(dòng)程序的組成原理

WindowsNT操作系統(tǒng)結(jié)構(gòu)分為用戶模式和內(nèi)核模式,用戶模式下的編程為應(yīng)用程序的設(shè)計(jì),而開發(fā)設(shè)備驅(qū)動(dòng)程序,則屬于內(nèi)核模式下的編程,內(nèi)核模式組件包括NTExecutive(ExXxx),內(nèi)核(KeXxx),硬件抽象層(HalXxx)。其層次如圖2-1所示,其中NTExecutive包括幾個(gè)獨(dú)立的軟件組件,它們是系統(tǒng)服務(wù)接口(ZwXxx),對象管理器(ObXxx),配置管理器,進(jìn)程管理器(PsXxx),安全監(jiān)視器(SeXxx),虛擬空間管理器(MemXxx),本地進(jìn)程調(diào)用,I/O管理器(IoXxx)。內(nèi)核模式的系統(tǒng)服務(wù)并不是全部公開的,而是提供了一系列開發(fā)設(shè)備驅(qū)動(dòng)程序需要的函數(shù)(上文括號內(nèi)為函數(shù)形式,函數(shù)手冊參見[2]Kernel-ModeDrivers-Reference章節(jié)),換言之,這些函數(shù)功能是所有內(nèi)核模式的系統(tǒng)服務(wù)功能的子集。

驅(qū)動(dòng)程序由一系列相對獨(dú)立的函數(shù)組成,由I/O管理器根據(jù)需要調(diào)用這些函數(shù),對于一個(gè)需要處理中斷的最簡單的驅(qū)動(dòng)程序也需要由以下幾個(gè)函數(shù)構(gòu)成:

1.DriverEntry()運(yùn)行于PASSIVE_LEVEL

驅(qū)動(dòng)程序入口點(diǎn),當(dāng)驅(qū)動(dòng)程序被手動(dòng)或自動(dòng)裝入系統(tǒng)后,驅(qū)動(dòng)程序從這點(diǎn)開始執(zhí)行,主要用于定位硬件資源,建立指向其它驅(qū)動(dòng)程序函數(shù)的指針等其它初始化工作。

2.XxUnload()運(yùn)行于PASSIVE_LEVEL

用于驅(qū)動(dòng)程序從系統(tǒng)卸出之前,釋放由驅(qū)動(dòng)程序占用的所有系統(tǒng)資源。

3.XxIsr()運(yùn)行于DIRQL

中斷服務(wù)程序。

4.XxDpcForIsr()運(yùn)行于DISPATCH_LEVEL

中斷服務(wù)程序后處理程序,以排隊(duì)方執(zhí)行不太關(guān)鍵代碼的執(zhí)行,由于排隊(duì)機(jī)制及優(yōu)先級,不會造成代碼擁塞從而提高中斷服務(wù)程序的響應(yīng)并且提高系統(tǒng)總體I/O吞吐率。

5.XxOpen()運(yùn)行于PASSIVE_LEVEL

處理應(yīng)用程序Win32函數(shù)CreateFile()請求。

6.XxClose()運(yùn)行于PASSIVE_LEVEL

處理應(yīng)用程序Win32函數(shù)CloseHandle()請求。

7.XxDispatch()運(yùn)行于PASSIVE_LEVEL

處理應(yīng)用程序Win32函數(shù)DeviceIoControl()請求,通過一系列自定義命令,驅(qū)動(dòng)程序與應(yīng)用程序交換特定的信息。

WindowsNT使用一個(gè)抽象化的CPU優(yōu)先級方案,IRQL代表中斷請求級,任一時(shí)刻CPU總處在某一級上,這個(gè)數(shù)越大,表示當(dāng)前的任務(wù)重要性越大,如表2-1所示,從上至下IRQL越來越小。所有上述驅(qū)動(dòng)程序的函數(shù)及內(nèi)核模式函數(shù)都必須運(yùn)行于各自的IRQL級上,如果違反這一調(diào)用規(guī)定,會造成系統(tǒng)崩潰。例如,中斷服務(wù)程序(XxIsr)運(yùn)行于DIRQL及上,那幺在編寫中斷服務(wù)程序時(shí),只能調(diào)用允許在這一級運(yùn)行的內(nèi)核模式函數(shù)(并不是所有內(nèi)核模式函數(shù)都能運(yùn)行于DIRQL級)。至于每個(gè)內(nèi)核模式函數(shù)運(yùn)行級別的說明,詳見[2]Kernel-ModeDrivers-Reference章節(jié)。

WindowsNT是一多任務(wù)系統(tǒng),許多設(shè)備的驅(qū)動(dòng)程序同時(shí)存在系統(tǒng)中,這樣各個(gè)設(shè)備所占用的資源(中斷,I/O及RAM地址空間)很有可能沖突,如果設(shè)備驅(qū)動(dòng)程序在運(yùn)行之前不進(jìn)行‘探測’而使用自己硬件設(shè)備的資源,有可能和系統(tǒng)內(nèi)其它設(shè)備占用的資源沖突,后果不堪設(shè)想。WindowsNT通過注冊表管理硬件資源的占用信息,作為內(nèi)核模式信任的組件,驅(qū)動(dòng)程序使用硬件資源之前必須遵循‘查詢-申請-使用-釋放’的原則

WindowsNT設(shè)備驅(qū)動(dòng)程序的編寫步驟與實(shí)例

現(xiàn)以一實(shí)際例子簡要說明設(shè)備驅(qū)動(dòng)程序的開發(fā)步驟,本例以CINRAD天氣雷達(dá)測試卡實(shí)際應(yīng)用為原型,加以簡化、抽象。

第一步,了解被控設(shè)備的接口情況。

本例為一ISA卡,占用PC機(jī)9號中斷,I/O地址360H及RAM地址D0228H分別一個(gè)字空間。

第二步,確定驅(qū)動(dòng)程序的功能。

驅(qū)動(dòng)程序每當(dāng)9號中斷達(dá)到時(shí),檢查運(yùn)行標(biāo)志變量RunFlag(為一BOOL變量),如果等于TRUE,中斷累積計(jì)數(shù)器counter(為一unsignedshort變量)增一,把這個(gè)值寫入RAM地址D0228H,再從這個(gè)地址讀出,如果讀出值等于寫入值,把這個(gè)值寫入I/O地址360H,這個(gè)地址的內(nèi)容會驅(qū)動(dòng)板卡上的LED顯示,把寫入值顯示出來;如果讀出值不等于寫入值,設(shè)置運(yùn)行標(biāo)志變量FALSE。如果運(yùn)行標(biāo)志變量等于FALSE,什幺也不做,返回。

第三步,定義驅(qū)動(dòng)程序與應(yīng)用程序的軟件接口。

本例定義兩個(gè)接口命令:

IOCTL_IOCardA_START:應(yīng)用程序設(shè)置驅(qū)動(dòng)程序內(nèi)部的運(yùn)行標(biāo)志變量等于TRUE。

IOCTL_IOCardA_READ:應(yīng)用程序查詢驅(qū)動(dòng)程序內(nèi)部的中斷累積計(jì)數(shù)器的值。

第四步,畫流程圖。這里列舉本例實(shí)現(xiàn)的幾個(gè)主要流程圖,(圖略)。

系統(tǒng)傳給驅(qū)動(dòng)程序入口函數(shù)系統(tǒng)定義的‘設(shè)備驅(qū)動(dòng)對象’DrObj,通過初始化這個(gè)對象的一些成員變量,把驅(qū)動(dòng)程序其它函數(shù)與這個(gè)對象聯(lián)系起來。

ISA卡為非即插即用設(shè)備,事先把資源占用信息手工添加注冊表如下:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IOCardA\parameters]

"IRQ"=dword:00000009

"IOSPAN"=dword:00000004

"IOAdd"=dword:00000360

"RAMAdd"=dword:000d0228

"RAMSPAN"=dword:00000002

其中IOCardA以下各子鍵及其值為自定義,設(shè)備驅(qū)動(dòng)程序利用相應(yīng)函數(shù)檢索出這些值。

(3)每個(gè)設(shè)備驅(qū)動(dòng)程序可以創(chuàng)建若干系統(tǒng)定義的‘設(shè)備對象’,本例根據(jù)需要只創(chuàng)建了一個(gè)‘設(shè)備對象’Dev。‘設(shè)備對象’其中一個(gè)成員變量為指向一非分頁的物理內(nèi)存塊DeviceExtension,這塊內(nèi)存大小及內(nèi)容為用戶自定義,由于Dev或DeviceExtension對象會被系統(tǒng)傳給驅(qū)動(dòng)程序的其它函數(shù),這樣驅(qū)動(dòng)程序各函數(shù)通過訪問這塊內(nèi)存區(qū),實(shí)際上達(dá)到互相傳遞信息的功能。本例在這里存儲設(shè)備硬件資源信息及RunFlag和中斷計(jì)數(shù)器counter,這些數(shù)值在DriverEntry()初始化后,供驅(qū)動(dòng)程序的其它函數(shù)使用。

圖3-2為中斷服務(wù)程序IOCardAIsr()流程圖。操作系統(tǒng)接受中斷,連同DeviceExtension等參數(shù)傳給中斷服務(wù)程序,中斷服務(wù)程序利用這些參數(shù),實(shí)現(xiàn)要求功能。

圖3-3為IOCardADispatch()流程圖,這個(gè)函數(shù)用于處理來自上層應(yīng)用程序的命令。上層應(yīng)用程序通過以下程序段設(shè)置驅(qū)動(dòng)程序中RunFlag值為TRUE,從而啟動(dòng)中斷服務(wù)程序開始計(jì)數(shù)。

BOOLcmd=TRUE;

hTest=CreateFile(...);//打開設(shè)備

DeviceIoControl(hTest,//設(shè)備句柄

IOCTL_IOCardA_START,//命令

&cmd,sizeof(BOOL),//輸入緩沖區(qū)地址及大小

NULL,0,&c,NULL);

CloseHandle(hTest);//關(guān)閉設(shè)備

上層應(yīng)用程序通過以下程序段查詢當(dāng)前的中斷計(jì)數(shù)器的值并存于變量w中。

unsignedshortw;

hTest=CreateFile(...);

DeviceIoControl(hTest,

IOCTL_IOCardA_READ,//命令

NULL,0,

&w,sizeof(unsignedshort),//輸出緩沖區(qū)地址及大小

&c,NULL);

CloseHandle(hTest);

其中DeviceIoControl()執(zhí)行后,操作系統(tǒng)調(diào)用IOCardADispatch()函數(shù),如流程圖所示,這個(gè)函數(shù)內(nèi)部通過一個(gè)開關(guān)語句,根據(jù)命令執(zhí)行相應(yīng)的分支。驅(qū)動(dòng)程序與應(yīng)用程序通過此函數(shù)接換數(shù)據(jù)時(shí),操作系統(tǒng)提供4種可選數(shù)據(jù)緩沖方式,本例由于數(shù)據(jù)I/O量比較小,故選用‘緩沖I/O’(METHOD_BUFFERED)。過程是,I/O管理器首先分配一個(gè)非分頁池,它的大小為調(diào)用者輸入緩沖區(qū)和輸出緩沖區(qū)的較大者,第一段程序?yàn)閟izeof(BOOL),第二段程序?yàn)閟izeof(unsignedshort),它的地址存到IRP(I/O請求包)的AssociatedIrp.SystemBuffer域中,然后把輸入數(shù)據(jù)拷貝到這個(gè)池中,在第一段程序中cmd的值TRUE被拷貝到池中,這樣驅(qū)動(dòng)程序通過RtlCopyBytes()函數(shù)再把池中的值拷貝到驅(qū)動(dòng)程序的RunFlag中。IOCardADispatch()函數(shù)執(zhí)行完,I/O管理器把池中的內(nèi)容拷貝到調(diào)用者的輸出緩沖區(qū),在第二段程序中,驅(qū)動(dòng)程序通過RtlCopyBytes()函數(shù)把counter的值拷貝到池中,從而最終傳遞到應(yīng)用程序變量w中。

第五步,編程。在編寫設(shè)備驅(qū)動(dòng)程序的同時(shí),要編寫一個(gè)簡單的應(yīng)用程序用于測試設(shè)備驅(qū)動(dòng)程序的一些功能。

第六步,驅(qū)動(dòng)程序的載入。

驅(qū)動(dòng)程序C語言源程序經(jīng)過編譯、連接生成擴(kuò)展名為SYS的文件,本例為IOCardA.sys,把這個(gè)文件拷貝到\WINNT\system32\drivers\系統(tǒng)目錄下,同時(shí)手工添加如下信息到注冊表:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\IOCardA]

"ErrorControl"=dword:00000001

"Start"=dword:00000003

"Type"=dword:00000001

要保證IOCardA子鍵名與驅(qū)動(dòng)程序文件名一致,其中Type=1表示此驅(qū)動(dòng)程序?yàn)閮?nèi)核模式驅(qū)動(dòng)程序,Start=3表示此驅(qū)動(dòng)程序手動(dòng)載入,ErrorControl=1表示當(dāng)驅(qū)動(dòng)程序發(fā)生錯(cuò)誤時(shí),日志記錄錯(cuò)誤并顯示一個(gè)消息框。這樣當(dāng)Windows重新啟動(dòng)后,通過使用控制面板中的Device小應(yīng)用程序,從列表中找到IOCardA設(shè)備名,按Start按鈕,于是,設(shè)備驅(qū)動(dòng)程序就駐留內(nèi)存并在底層開始工作了。

第七,調(diào)試。設(shè)備驅(qū)動(dòng)程序沒有界面,完全在系統(tǒng)底層運(yùn)行,為了觀察驅(qū)動(dòng)程序的運(yùn)行狀態(tài),WindowsNTDDK提供windbj.exe程序用于設(shè)備驅(qū)動(dòng)程序的調(diào)試,調(diào)試設(shè)備驅(qū)動(dòng)程序需要兩臺CPU體系結(jié)構(gòu)完全相同的計(jì)算機(jī),一臺為‘宿主機(jī)’,運(yùn)行windbj.exe程序,另一臺為‘目標(biāo)機(jī)’,運(yùn)行設(shè)備驅(qū)動(dòng)程序,兩臺計(jì)算機(jī)用串口線連好,進(jìn)行一系列軟件設(shè)置(參見[1]第17章),就可以開始調(diào)試了,從‘宿主機(jī)’可以控制及觀察‘目標(biāo)機(jī)’上驅(qū)動(dòng)程序的運(yùn)行情況。最常用的調(diào)試手段是在驅(qū)動(dòng)程序中必要的位置加入DbgPrint()函數(shù),這個(gè)函數(shù)可以把指定信息輸出到‘宿主機(jī)’windbg.exe窗口中,通過分析這些信息,可以了解驅(qū)動(dòng)程序當(dāng)前的運(yùn)行情況。

結(jié)束語

WindowsNT是一個(gè)復(fù)雜而嚴(yán)密的系統(tǒng),驅(qū)動(dòng)程序的開發(fā)不可避免的涉及現(xiàn)代操作系統(tǒng)理論及其它許多計(jì)算機(jī)理論,內(nèi)涵相當(dāng)廣泛,本文圍繞著開發(fā)實(shí)踐從一定深度探討了WindowsNT設(shè)備驅(qū)動(dòng)程序開發(fā)最基本的知識及一般方法,希望對讀者有所幫助,對于復(fù)雜,特殊應(yīng)用的實(shí)現(xiàn)及編程技巧,有待于讀者在各自實(shí)際應(yīng)用中不斷探索。

參考文獻(xiàn)

第10篇

【關(guān)鍵詞】ARM;矩陣鍵盤;linux驅(qū)動(dòng);TQ2440

1.引言

ARM微處理器已廣泛應(yīng)用于工業(yè)控制、消費(fèi)類電子產(chǎn)品、通信系統(tǒng)等領(lǐng)域。矩陣鍵盤是一種常用的鍵盤形式,它將按鍵設(shè)計(jì)成M行N列,這樣共需M+N根信號線,卻可驅(qū)動(dòng)M×N個(gè)按鍵,大大節(jié)約了I/O資源。本文介紹了一種利用TQ2440開發(fā)板的GPIO口擴(kuò)展5×4矩陣鍵盤的方法,并將所有按鍵重新布局成手持終端的鍵盤形式,方便操作。

2.硬件設(shè)計(jì)

本設(shè)計(jì)擴(kuò)展5行4列的矩陣鍵盤,如圖1所示。其中行線ROW1-ROW5連接S3C2440的中斷引腳EINT8,EINT9,EINT11,EINT13,EINT14[1]。這些中斷引腳本身連有10kΩ的上拉電阻,把中斷引腳電平拉高,確保按鍵空閑時(shí)不會觸發(fā)中斷。列線COL1-COL4連接S3C2440的普通I/O口GPF3,GPF4,GPG7,GPG10。這里需要注意的問題是:確保行線所用的中斷在Linux的其他設(shè)備中均未使用到,否則會引起該驅(qū)動(dòng)程序或其他驅(qū)動(dòng)程序初始化失敗。

圖1 5×4矩陣鍵盤電路原理圖

考慮到手持終端設(shè)備按鍵的常用性與操作的方便性,只取矩陣鍵盤的前18鍵,并將它們重新布局為圖2的形式。其中Ent鍵具有二重功能,即確認(rèn)功能(短按)和開關(guān)機(jī)功能(長按),此功能將在驅(qū)動(dòng)程序中實(shí)現(xiàn)。

圖2 鍵盤布局

3.矩陣鍵盤的Linux驅(qū)動(dòng)程序設(shè)計(jì)

3.1 鍵盤驅(qū)動(dòng)總體概述

驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和硬件設(shè)備之間的接口。設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件的細(xì)節(jié),使應(yīng)用程序可以像操作普通文件一樣操作硬件設(shè)備[2]。驅(qū)動(dòng)程序沒有main函數(shù),它以一個(gè)模塊初始化函數(shù)作為入口,并且它完成初始化之后不再運(yùn)行,等待系統(tǒng)調(diào)用。

驅(qū)動(dòng)程序是linux內(nèi)核的一部分,所以在程序編寫上要采用linux的表達(dá)方式。首先將列I/O端口定義為數(shù)組:col_table [] = { S3C2410_GPF3,S3C2410_GPF4, ...},行I/O端口定義為結(jié)構(gòu)型:

button_irqs [] ={ {IRQ_EINT8,S3C2410_GPG0,S3C2410_GPG0_EINT8, 0,"R1"},

{IRQ_EINT9,S3C2410_GPG1,S3C2410_GPG1_EINT9, 1,"R2"},

...}。//中斷號(irq),引腳(pin),引腳設(shè)置,序號,名稱

矩陣鍵盤是作為Linux的一個(gè)字符設(shè)備注冊到系統(tǒng)中的。我們首先向系統(tǒng)注冊矩陣鍵盤設(shè)備,包括設(shè)備號,設(shè)備名及file_operations結(jié)構(gòu)體;file_operations結(jié)構(gòu)體的成員函數(shù)是字符設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)的主體內(nèi)容,這些函數(shù)實(shí)際會在應(yīng)用程序進(jìn)行Linux的open()、write()、read()、close()等系統(tǒng)調(diào)用時(shí)最終被調(diào)用[3]。用戶對鍵盤沒有寫操作,其file_operations結(jié)構(gòu)體的成員函數(shù)為open()、read()、close()、poll()。

中斷的注冊和行列初始化在打開鍵盤時(shí)(即open()函數(shù)中)實(shí)現(xiàn)。注冊中斷包括:中斷號,中斷入口程序,中斷方式,中斷名和代號。關(guān)鍵語句為:request_irq(button_irqs[i].irq,buttons_interrupt,IRQ_TYPE_EDGE_FALLING,button_irqs[i].name,(void *)&button_irqs[i])。IRQ_TYPE_EDGE_FALLING意思為下降沿觸發(fā)。然后再進(jìn)行行列初始化:設(shè)置行線為中斷,使能上拉,在linux中其表達(dá)方式為:

s3c2410_gpio_cfgpin(button_irqs[i].pin,S3C2410_GPIO_SFN2); //設(shè)置第i行引腳為中斷

s3c2410_gpio_pullup(button_irqs[i].pin,1); //第i行引腳上拉

設(shè)置列線為輸出,置低電平。語句表達(dá)同理,由于篇幅所限,這里不再一一列出。

read()函數(shù)實(shí)現(xiàn)從設(shè)備中讀取數(shù)據(jù)。該函數(shù)實(shí)現(xiàn)無按鍵按下時(shí)程序進(jìn)入休眠,關(guān)鍵代碼:

static DECLARE_WAIT_QUEUE_HEAD (button_waitq); //生成一個(gè)等待隊(duì)列頭隊(duì)列,名為button_waitq

static volatile int ev_press = 0; //置1,表示有鍵按下

ev_press為0時(shí)執(zhí)行語句:wait_event_interruptible(button_waitq,ev_press),程序即進(jìn)入休眠。ev_press為1時(shí)把數(shù)據(jù)從內(nèi)核空間復(fù)制到用戶空間,關(guān)鍵語句:copy_to_user(buff,(const void *)key_values,min(sizeof(key_values),count)); //buff為用戶空間的指針,key_values為內(nèi)核空間指針,最后一個(gè)參數(shù)為從內(nèi)核空間向用戶空間拷貝數(shù)據(jù)的字節(jié)數(shù),我們?nèi)?shí)際大小與用戶指定大小中的最小值。數(shù)據(jù)復(fù)制成功時(shí)返回零;出錯(cuò)時(shí)返回沒有復(fù)制成功的數(shù)據(jù)字節(jié)數(shù)。

close()函數(shù)實(shí)現(xiàn)關(guān)閉矩陣鍵盤設(shè)備,釋放已注冊的中斷,關(guān)鍵語句:free_irq (button_irqs[i].irq,(void *)&button_irqs[i])。

Poll()函數(shù)實(shí)現(xiàn)輪詢,如果沒有按鍵數(shù)據(jù),調(diào)用linux的poll_wait函數(shù)等待;如果有按鍵數(shù)據(jù),則select函數(shù)會立刻返回。

3.2 中斷處理及鍵盤掃描程序

中斷處理函數(shù)的名稱為上面注冊的buttons _interrupt。具體程序流程如圖3所示。當(dāng)有按鍵按下時(shí),該鍵所在行列導(dǎo)通。列的低電平將該行電平拉低,進(jìn)而觸發(fā)中斷。然后,進(jìn)入中斷處理函數(shù)。由于按鍵存在抖動(dòng)的問題,單靠一次中斷的觸發(fā)就判定有按鍵按下是不可靠的,所以采用定時(shí)器延時(shí)10ms后再進(jìn)入鍵盤掃描函數(shù)。

本設(shè)計(jì)的鍵盤掃描程序采用先確定行再確定列的方法,最后對行列進(jìn)行一定的運(yùn)算即得鍵值。首先確定行:逐行掃描,判斷是否有行引腳為低電平。若有,保存該行值(row)。繼續(xù)確定列:逐列置低電平,當(dāng)該列為按下所在列時(shí),才會使該行再次為低電平,從而確定列(column)。再對行列進(jìn)行運(yùn)算:k=row*4+column,則將矩陣鍵盤的每一鍵對應(yīng)為鍵號0—19。鍵盤布局為圖2所示形式后,我們只取矩陣鍵盤的前18鍵(鍵號0—17),鍵值保存為k+1。對于Ent鍵,通過按下的時(shí)間長短區(qū)分是確定功能還是開關(guān)機(jī)功能,按下時(shí)間小于0.5秒為確認(rèn)功能,按下時(shí)間大于1.6秒為開關(guān)機(jī)功能,時(shí)間在0.5秒—1.6秒的視為無效操作。計(jì)時(shí)方法為:若該行仍為低電平且整數(shù)cnt小于1700:延時(shí)1ms,cnt++;根據(jù)cnt值即得按下時(shí)間。開關(guān)機(jī)功能保存為第18鍵號,鍵值19。

圖3 鍵盤掃描程序流程圖

4.驅(qū)動(dòng)程序的測試

測試程序?qū)儆谏蠈討?yīng)用程序,直接調(diào)用鍵盤驅(qū)動(dòng)程序提供的接口即可實(shí)現(xiàn)度鍵盤的操作。我們調(diào)用open()函數(shù)實(shí)現(xiàn)矩陣鍵盤設(shè)備的打開,再調(diào)用read()函數(shù)即可將鍵盤數(shù)據(jù)讀取出來并保存到自己定義的數(shù)組中,最后使用printf()函數(shù)將測試結(jié)果顯示出來。

按本文介紹的方法設(shè)計(jì)的矩陣鍵盤,已成功運(yùn)用到筆者的項(xiàng)目中,鍵盤輸入的正確率和反應(yīng)時(shí)間均符合設(shè)計(jì)要求。

5.總結(jié)

本文介紹了一種直接從ARM的I/O口擴(kuò)展矩陣鍵盤的方法,它無需增加其它接口元器件,設(shè)計(jì)快速實(shí)用,并實(shí)現(xiàn)了在Linux系統(tǒng)下的驅(qū)動(dòng),為ARM嵌入式設(shè)備擴(kuò)展手持終端式鍵盤提供了一種解決方案。

參考文獻(xiàn)

[1]胡章勇,蔣朝根.Linux的鍵盤驅(qū)動(dòng)與Qt/E的鍵盤映射[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2008(9):35.

[2]李俊.嵌入式Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解[M].北京:人民郵電出版社,2008:17.

第11篇

關(guān)鍵詞:CY7C68013A; 通用串行總線; VC++6.0; 固件; 上位機(jī)

中圖分類號:TP368.1 文獻(xiàn)標(biāo)識碼:A

文章編號:1004-373X(2010)13-0190-04

Design of USB Control System Based on CY7C68013A

ZHAO Tie-jun

(Equipment Power Department, China Coal Beijing Coal Mining Machinery Co. Ltd., Beijing 102400, China)

Abstract: With the increasing development of the communication technology, the universal serial bus (USB) as a new interface technology that makes the connection of PCs with peripheral equipments very simple has been extensively adopted. The feature of USB2.0 is introduced firstly, and then the overall plan for designing the control system by using CY7C68013A is presented. The function of the system firmware and the design of drive program are discussed in detail. The key issues which should be taken more attention during the system design are proposed. The control system firmware is programmed with C language. The control interface on PC is developed under the VC++6.0 development environment. The experiment indicates that the whole system runs perfectly well.

Keywords: CY7C68013A; USB; VC6.0; firmware; PC

0 引 言

通用串行總線 (Universal Serial Bus,USB)作為計(jì)算機(jī)上的新型接口技術(shù),越來越受到人們的青睞。與以前的RS 232,RS 485,ISA,PCI和并行接口等接口相比,USB避免了接口體積大、接口規(guī)范不統(tǒng)一、不支持熱插拔等缺陷,具有使計(jì)算機(jī)與外部設(shè)備連接十分方便的優(yōu)點(diǎn)[1-2]。目前,很多設(shè)備都開始使用USB接口來實(shí)現(xiàn),如鼠標(biāo)、鍵盤、打印機(jī)等。在實(shí)際設(shè)計(jì)工作當(dāng)中,也越來越多地采用了USB技術(shù),如數(shù)據(jù)采集等[3-4]。USB的設(shè)計(jì)和應(yīng)用已經(jīng)成為現(xiàn)代電子設(shè)計(jì)中一個(gè)非常重要的部分。

1 USB 2.0特點(diǎn)

USB是一種高效、快速、價(jià)格低廉、體積小的新型串行通信接口,其最大的特點(diǎn)是支持熱插拔,可以在不重新啟動(dòng)計(jì)算機(jī)的情況下直接將USB外部設(shè)備連接到計(jì)算機(jī)并開始通信。

USB具有以下主要特點(diǎn)[2]:

(1) 節(jié)省系統(tǒng)資源。在計(jì)算機(jī)中,系統(tǒng)為USB主控制器分配一根中斷控制線和一些輸入/輸出地址,USB再為外部設(shè)備分配惟一的地址。

(2)可以提供電源。計(jì)算機(jī)上的USB接口可以向外部設(shè)備提供一定的電力支持,其輸出電流最小值為100 mA,最大值為500 mA,輸出電壓為5 V。

(3) 良好的兼容性。USB規(guī)范已經(jīng)有USB 1.0,USB 1.1,USB 2.0,無線USB等多個(gè)版本的協(xié)議,這些協(xié)議都有很好的向下兼容性。

(4) 共享式接口。USB采用“鏈”式的連接方式,同時(shí)支持多個(gè)設(shè)備的連接,一個(gè)USB主控制器最多可以連接126個(gè)外部設(shè)備。

2 CY7C68013A的主要特點(diǎn)

CY7C68013A是Cypress公司的EZ-USB FX2LP系列低功耗版本單片機(jī),具有和8051兼容的CPU和指令系統(tǒng),同時(shí)包括USB接口和完整的USB 2.0協(xié)議引擎,并且提供了完善的固件及主機(jī)程序開發(fā)包。該單片機(jī)的CPU采用的是增強(qiáng)型8051內(nèi)核,比標(biāo)準(zhǔn)的8051的速度快,硬件資源更為豐富,功能更強(qiáng)大。主要具有以下特點(diǎn)[5-6]:

(1) 具有第二個(gè)數(shù)據(jù)指針;

(2) 具有第二個(gè)USATRT;

(3) I2C總線接口;

(4) 8個(gè)額外的中斷(INT2~INT6,WAKEUP,T2,USART1);

(5) CPU時(shí)鐘可以運(yùn)行在12 MHz,24 MHz,48 MHz。

3 控制系統(tǒng)設(shè)計(jì)

基于USB的控制系統(tǒng)設(shè)計(jì)主要包含兩個(gè)方面的內(nèi)容,分別為固件程序的開發(fā)和上位機(jī)(主機(jī))控制界面的設(shè)計(jì)。CY7C68013A芯片采用的是一種軟配置模式,即程序和數(shù)據(jù)都存放在內(nèi)部RAM中,并從RAM中開始執(zhí)行。

3.1 啟動(dòng)模式的選擇

EZ-USB在沒有固件的情況下列舉為一個(gè)缺省的USB設(shè)備,并且將其固件和描述符等下載到EZ-USB后,開始執(zhí)行固件程序,此時(shí)模擬一個(gè)物理上的斷開重新連接過程[6-7]。在列舉為一個(gè)USB設(shè)備時(shí),根據(jù)芯片有沒有連接E2PROM,以及E2PROM中第一個(gè)字節(jié)值的不同,其處理方式有很多。主要有:不連接E2PROM的缺省設(shè)備列舉、C0加載、C2加載等啟動(dòng)方式。在此系統(tǒng)的設(shè)計(jì)過程中,采用第一種方式,即芯片沒有連接任何片外存儲器,USB的描述符以及VID,PID和DID等均由芯片內(nèi)置的邏輯提供,然后根據(jù)驅(qū)動(dòng)程序中提供的VID,PID和DID把主機(jī)上對應(yīng)的固件程序下載到片內(nèi)的RAM中,并執(zhí)行固件代碼。該方式具有硬件連接簡單,節(jié)省器件等特點(diǎn)。

3.2 硬件系統(tǒng)框圖

整個(gè)系統(tǒng)的硬件框圖如圖1所示。可以看出USB控制系統(tǒng)在整個(gè)系統(tǒng)中起到橋梁作用,用于連接上位機(jī)和外部設(shè)備。

圖1 系統(tǒng)硬件框圖

上位機(jī)發(fā)送控制指令給USB設(shè)備,信息處于下行狀態(tài),解碼后用來控制設(shè)備執(zhí)行相應(yīng)功能。上位機(jī)需要從外設(shè)獲得信息(如數(shù)據(jù)采集),信息處于上行狀態(tài),由USB設(shè)備負(fù)責(zé)控制外設(shè)并將數(shù)據(jù)傳送到上位機(jī),由上位機(jī)分析、顯示。

3.3 固件程序設(shè)計(jì)

在固件中,主要實(shí)現(xiàn)芯片設(shè)備的控制,以及對USB設(shè)備的功能描述等任務(wù),同時(shí)負(fù)責(zé)與上位機(jī)通信,響應(yīng)上位機(jī)的標(biāo)準(zhǔn)請求和自定義請求。

描述符主要是讓上位機(jī)了解USB功能設(shè)備的基本配置信息和能力,如端點(diǎn)、接口等。在此主要使用標(biāo)準(zhǔn)描述符來說明USB設(shè)備,如設(shè)備描述符、配置描述符、接口描述符、端點(diǎn)描述符、設(shè)備限定描述符等。在該設(shè)備中,這些描述符的層次結(jié)構(gòu)如圖2所示。

圖2 描述符層次圖

系統(tǒng)中使用了2個(gè)配置描述符,分別為高速配置和全速配置,┟扛霆配置使用1個(gè)接口,并對應(yīng)1個(gè)接口描述符,每個(gè)接口應(yīng)用了4個(gè)端點(diǎn),對應(yīng)4個(gè)端點(diǎn)描述符。同時(shí)端點(diǎn)配置為塊傳輸模式,2、4端點(diǎn)為OUT,6、8端點(diǎn)為IN,最大數(shù)據(jù)包長度為512 B,上位機(jī)通過0端點(diǎn)來操作、控制USB設(shè)備。設(shè)備描述符中VID=0x04B4,PID=0x1304,用于指示設(shè)備供應(yīng)商和產(chǎn)品信息,并用于上電時(shí)幫助主機(jī)加載合適的驅(qū)動(dòng)程序,進(jìn)而下載相應(yīng)的固件程序。固件中對標(biāo)準(zhǔn)請求的響應(yīng)部分,主要是讓上位機(jī)能夠?qū)γ枋龇M(jìn)行讀取和寫操作。自定義請求響應(yīng)主要實(shí)現(xiàn)上位機(jī)發(fā)送控制命令,來使能USB功能設(shè)備、以及執(zhí)行相應(yīng)的功能的目的,如DR_SendData,DR_ ReadData。

固件設(shè)計(jì)流程圖如圖3所示。

圖3 固件設(shè)計(jì)流程圖

用戶初始化設(shè)備部分放在TD_Init()子程序中,負(fù)責(zé)整個(gè)USB設(shè)備的初始化過程。在定向描述符之后,需要把所用中斷打開,并開啟8051全局中斷EA=1。由于EZ-USB設(shè)備啟動(dòng)需要重列舉,因而需要通過設(shè)置和判斷USBCS寄存器的RENUM和DISCON位來模擬設(shè)備物理上的斷開和連接過程。用戶設(shè)備控制功能的實(shí)現(xiàn)放在TD_Poll()子程序中,同時(shí)主循環(huán)中的SetupCommand()子程序用于接收、分析上位機(jī)的控制信號,響應(yīng)上位機(jī)請求(標(biāo)準(zhǔn)請求和用戶自定義請求)。

3.4 上位機(jī)界面設(shè)計(jì)

為了能夠很好地控制USB設(shè)備,需要編寫上位機(jī)控制界面。界面程序在VC++6.0環(huán)境下開發(fā),該環(huán)境具有編程簡單、快捷等的特點(diǎn),便于開發(fā)可視化程序[8-9]。Cypress公司為EZ-USB系列芯片提供了開發(fā)庫CyAPI.lib,使用其中的控制函數(shù)類,可以在VC++6.0環(huán)境下開發(fā)界面程序[10]。建立MFC(exe)工程后,在工程中加入CyAPI.lib,并且在主文件頭部添加EZ-USB開發(fā)環(huán)境中提供的CyAPI.h,cyioctl.h頭文件。利用庫中的控制函數(shù),如VendorID,ProductID等,可以獲取USB設(shè)備的描述信息,同時(shí)也可以編寫相關(guān)的控制功能程序。

3.5 系統(tǒng)設(shè)計(jì)中關(guān)鍵問題

(1) 一個(gè)設(shè)備只能有一個(gè)設(shè)備描述符,可以有多個(gè)配置描述符,多個(gè)接口描述符,以及多個(gè)端點(diǎn)描述符。

(2) 設(shè)備描述符中VID,PID要與驅(qū)動(dòng)中的相一致,否則不能自動(dòng)加載相應(yīng)的固件程序。

(3) 固件程序必須轉(zhuǎn)換為.spt格式,用于固件加載的驅(qū)動(dòng)程序和固件程序應(yīng)放在一個(gè)文件夾。

(4) 端點(diǎn)0為缺省控制端點(diǎn),其可設(shè)置最大數(shù)據(jù)包長度為64 B,在設(shè)備描述符中wMaxPacketSize字段描述。

(5) 傳輸模式有中斷傳輸、塊傳輸、同步傳輸、控制傳輸四類,需根據(jù)自己設(shè)計(jì)需求選擇,同時(shí)注意最大數(shù)據(jù)包長度的設(shè)置。

4 驅(qū)動(dòng)程序

對于USB設(shè)備,Windows操作系統(tǒng)要想對其實(shí)現(xiàn)操作,必須借助于驅(qū)動(dòng)程序來實(shí)現(xiàn)。主機(jī)和驅(qū)動(dòng)程序直接通信,交換數(shù)據(jù),而驅(qū)動(dòng)程序則和硬件資源進(jìn)行通信,從而很好地控制USB設(shè)備。Cypress提供的開發(fā)環(huán)境中自帶了相關(guān)的驅(qū)動(dòng)程序CyLoad.sys和CyUSB.sys,可以直接使用,縮短了系統(tǒng)的開發(fā)周期。其中CyLoad.sys用于主機(jī)向USB設(shè)備下載固件程序,CyUSB.sys實(shí)現(xiàn)主機(jī)和固件程序通信。為了在CyLoad.sys的幫助下實(shí)現(xiàn)固件的自動(dòng)下載,固件程序CyLoad.HEX必須轉(zhuǎn)換為適合自動(dòng)下載的CyLoad.spt文件,并且與CyLoad.sys一起放在CyLoad文件夾下,拷貝到系統(tǒng)system32目錄下。在安裝文件CyUSB.inf中設(shè)置的PID,VID必須和描述符中的一致,使得能夠自動(dòng)加載對應(yīng)固件。

5 實(shí) 驗(yàn)

實(shí)驗(yàn)系統(tǒng),采用CY7C68013A-56pin作為USB設(shè)備芯片,實(shí)現(xiàn)控制LED和讀取I/O數(shù)據(jù)功能。

由于芯片采用33 V電壓供電,因此可以從主機(jī)USB口取電,經(jīng)LM317電壓調(diào)整芯片轉(zhuǎn)換為33 V,也可外接33 V電壓供電。在PD口接LED,顯示TD_Poll(void)實(shí)現(xiàn)的功能(燈亮/滅間隔300 ms),┒PA口LED用于顯示判斷主機(jī)發(fā)送數(shù)據(jù)。PB口接高/低電平,用于主機(jī)讀取該口數(shù)據(jù),可以驗(yàn)證主機(jī)接收數(shù)據(jù)的正確性。

初始化子程序:

void TD_Init(void)

{

BREAKPT &= ~bmBPEN;

OED=0xFF;//設(shè)置PD口為輸出

}

外設(shè)功能子程序:

void TD_Poll(void)

{

IOD=0x00; //D口輸出低電平

EZUSB_Delay(300);

IOD=0xFF;// D口輸出高電平

EZUSB_Delay(300);

}

自定義請求響應(yīng)發(fā)送數(shù)據(jù)子程序:

BOOL DR_SendData(void)

{

EP0BUF[0]=0xB1;//發(fā)送數(shù)據(jù)自定義請求碼

EP0BCH=0;

EP0BCL=2;

EZUSB_Delay(100);

OEA=0xFF;//PA口為輸出

IOA=EP0BUF[1];

EP0CS |= bmHSNAK;

return(TRUE);

}

自定義請求響應(yīng)接收數(shù)據(jù)子程序:

BOOL DR_ReadData(void)

{

OEB=0x00;//PB口為輸入

EP0BUF[0]=0xB2;//接收數(shù)據(jù)自定義請求碼

EP0BUF[1]=IOB;

EP0BCH=0;

EP0BCL=2;

EP0CS |= bmHSNAK;

return(TRUE);

}

主機(jī)控制界面運(yùn)行如圖4所示。

界面中的USB Information分類框中為USB描述相關(guān)信息,由主機(jī)通過標(biāo)準(zhǔn)請求獲得。Operation分類框中為主機(jī)向USB設(shè)備PA口發(fā)送數(shù)據(jù),以及從USB設(shè)備的PB讀取數(shù)據(jù)的

情況。

圖4 主機(jī)控制界面

6 結(jié) 語

采用CY7C68013A實(shí)現(xiàn)USB控制系統(tǒng),無論在固件程序編寫、主機(jī)控制界面開發(fā),以及設(shè)備驅(qū)動(dòng)程序的使用等方面,都具有簡單、方便的優(yōu)點(diǎn)。系統(tǒng)采用設(shè)備固件存放在主機(jī)上的方法,不但簡化了硬件設(shè)計(jì),節(jié)約元器件成本,而且也提高了設(shè)備的可靠性。同時(shí),此法對以后固件升級或更改設(shè)備功能,也十分簡便,只需把固件修改好并放到主機(jī)相應(yīng)位置,在USB設(shè)備再次插入主機(jī)時(shí),就可以實(shí)現(xiàn)固件自動(dòng)更新。文中給出一些設(shè)計(jì)過程中需要注意的關(guān)鍵問題,對于USB控制設(shè)備的設(shè)計(jì)具有一定的指導(dǎo)作用。上述系統(tǒng)和程序經(jīng)過實(shí)際運(yùn)行,工作穩(wěn)定、可靠。

參考文獻(xiàn)

[1]李英偉,王成儒.USB 2.0原理與工程開發(fā)[M].北京:國防工業(yè)出版社,2007.

[2]胡曉軍,張愛成.USB接口開發(fā)技術(shù)[M].西安:西安電子科技大學(xué)出版社,2005.

[3]錢峰.EZ-USBFX2單片機(jī)原理編程及應(yīng)用[M].北京:北京航空航天大學(xué)出版社,2006.

[4]周立功.PDIUSBD12 USB固件編程與驅(qū)動(dòng)開發(fā)[M].北京:北京航空航天大學(xué)出版社,2003.

[5]薛園園.USB應(yīng)用開發(fā)技術(shù)大全[M].北京:人民郵電出版社,2007.

[6]Cypress. EZ-USB FX2LPTM USB microcontroller datasheet[ EB/OL] . [ 2009-05-20] . .

[7]Cypress. EZ-USB FX2 technical reference manual[ EB/OL] . [ 2009-03-18] . .

[8]周曉云.程序設(shè)計(jì)基礎(chǔ)――可視化及VC++實(shí)現(xiàn)[M].北京:高等教育出版社,2004.

第12篇

        關(guān)鍵詞:電阻電容檢測;微處理器;usb;visual b + +

        基于usb接口虛擬在線電阻電容測試的方法其總體設(shè)計(jì)思想為:將電阻電容的參數(shù)值轉(zhuǎn)換成與之成正比關(guān)系變化的電壓輸出,經(jīng)模數(shù)(a/d)轉(zhuǎn)換,然后送pc機(jī)進(jìn)行數(shù)據(jù)及信息處理,在pc機(jī)上進(jìn)行數(shù)據(jù)和信息顯示。最終完成電阻電容的在線測試與顯示。

        一、電阻電容測試原理

        電阻電容的參數(shù)測試在電子設(shè)計(jì)中是至關(guān)重要的,目前其測試基本上都采用直接測量的方式,即用萬用表直接測試元件的兩端以測得元件參數(shù)。但通常設(shè)計(jì)者們在電路設(shè)計(jì)初期只能通過理論分析計(jì)算需要的電子元件的參數(shù),在實(shí)際的設(shè)計(jì)中,需要測試更換一些電路板上的電子元件。但此時(shí)元件已經(jīng)焊接在電路板上,特別像電阻電容往往都不是分立的元件,直接測試將會造成極大的誤差。傳統(tǒng)的做法是焊開原器件再測量,以避免受板上其他元器件的影響。

        二、visual b + + 6.0

        visual b++6.0是微軟公司推出的一種開發(fā)環(huán)境,以其強(qiáng)大功能友好的界面,32位面向?qū)ο蟮某绦蛟O(shè)計(jì)而受廣大軟件開發(fā)者的青睞,被廣泛應(yīng)用于各個(gè)領(lǐng)域。

        應(yīng)用程序用visual b+ +開發(fā)環(huán)境在windows xp系統(tǒng)下編寫,對usb接口的電阻電容測試儀進(jìn)行打開、讀寫、關(guān)閉等操作都通過調(diào)用系統(tǒng)api函數(shù)完成。應(yīng)用程序首先調(diào)用creat file得到usb設(shè)備的句柄,然后利用device io control 函數(shù)提交一個(gè)i/o控制代碼,通過設(shè)備句柄打開連接驅(qū)動(dòng)的輸入輸出緩沖。

        三、通用串行總線(usb)及其接口芯片

        通用串行總線(usb)是一種簡單的計(jì)算機(jī)外圍接口標(biāo)準(zhǔn)。在早期的計(jì)算機(jī)系統(tǒng)上常用串口或并口連接外圍設(shè)備。每個(gè)接口都需要占用計(jì)算機(jī)的系統(tǒng)資源(如中斷,i/o地址,dma通道等)。無論是串口還是并口都是點(diǎn)對點(diǎn)的連接,每添加一個(gè)新的設(shè)備,就需要添加一個(gè)isa/eisa或pci卡來支持,同時(shí)系統(tǒng)需要重新啟動(dòng)才能驅(qū)動(dòng)新的設(shè)備。usb總線是intel、dec、microsoft、ibm等公司聯(lián)合提出的一種新的串行總線標(biāo)準(zhǔn),主要用于pc機(jī)與外圍設(shè)備的互聯(lián)。usb總線具有低成本、使用簡單、支持即插即用、易于擴(kuò)展等特點(diǎn),已被廣泛地用在pc機(jī)及嵌入式系統(tǒng)上。

        四、usb協(xié)議棧驅(qū)動(dòng)程序及設(shè)備驅(qū)動(dòng)程序需實(shí)現(xiàn)的功能

        usb協(xié)議棧驅(qū)動(dòng)程序需實(shí)現(xiàn)的功能:提供與設(shè)備驅(qū)動(dòng)程序的接口;讀取并解析usb設(shè)備描述符,配置描述符;為usb設(shè)備分配唯一的地址;使用默認(rèn)的配置來配置設(shè)備;支持基本的usb命令請求;連接設(shè)備與相應(yīng)的驅(qū)動(dòng)程序;轉(zhuǎn)發(fā)設(shè)備驅(qū)動(dòng)程序的數(shù)據(jù)包。

        設(shè)備驅(qū)動(dòng)程序需實(shí)現(xiàn)以下功能:提供與應(yīng)用程序的接口;讀取并解析usb設(shè)備特有的描述符,獲得設(shè)備提供的傳輸通道;發(fā)送設(shè)備特有的和基本的usb命令請求;通過設(shè)備提供的傳輸通道與設(shè)備進(jìn)行數(shù)據(jù)傳輸;通過usb命令請求重新配置設(shè)備。

        五、結(jié)論

        系統(tǒng)測試時(shí)選定若干電阻和電容的測試結(jié)果如表1所示。

數(shù)據(jù)中3號代表數(shù)字變化,數(shù)據(jù)不能讀出。通過測試結(jié)果與實(shí)際值的對比,本測試儀已達(dá)到設(shè)計(jì)時(shí)的技術(shù)指標(biāo),基本滿足測試人員的測試要求。

主站蜘蛛池模板: 绿春县| 明光市| 北碚区| 舞钢市| 团风县| 大埔县| 德庆县| 双桥区| 长泰县| 友谊县| 中阳县| 高阳县| 临潭县| 九龙县| 金阳县| 义马市| 托克托县| 无极县| 甘德县| 德昌县| 抚远县| 东城区| 盐边县| 景德镇市| 海伦市| 江津市| 沧州市| 石门县| 图们市| 塔城市| 长沙县| 尖扎县| 德兴市| 山丹县| 岳西县| 长武县| 漳州市| 长寿区| 佛坪县| 沭阳县| 富裕县|