在我國(guó)的靶場(chǎng)測(cè)控領(lǐng)域,所有的數(shù)據(jù)交換都是基于簡(jiǎn)化版的HDLC規(guī)程進(jìn)行的,因此我們自行研制開(kāi)發(fā)了基于簡(jiǎn)化HDLC規(guī)程的通信卡。簡(jiǎn)化HDLC規(guī)程主要是為了提高通信的實(shí)時(shí)性,將HDLC規(guī)程中所有通信聯(lián)絡(luò)命令幀全部簡(jiǎn)化,只保留數(shù)據(jù)通信幀,從而保證一定的實(shí)時(shí)性。由于該卡具有可靠性高,使用簡(jiǎn)單方便,工作時(shí)具有智能化等特點(diǎn),被廣泛地應(yīng)用于測(cè)控系統(tǒng)數(shù)據(jù)傳送的各個(gè)領(lǐng)域中。同時(shí),隨著WindowsXP操作系統(tǒng)在測(cè)控系統(tǒng)逐漸應(yīng)用,開(kāi)發(fā)通信卡WindowsXP驅(qū)動(dòng)程序勢(shì)在必行。因此,我們針對(duì)自行研制的通信卡開(kāi)發(fā)出了核心態(tài)的驅(qū)動(dòng)程序,經(jīng)過(guò)廣泛的用戶使用,普遍反映應(yīng)用好。下面介紹該通信卡的設(shè)計(jì)以及驅(qū)動(dòng)程序的設(shè)計(jì)。 通信卡的硬件設(shè)計(jì) 1 通信卡的主要特點(diǎn) 通信卡的硬件設(shè)計(jì)目的是智能化通信:在卡上具有4個(gè)DMA通道及相應(yīng)的數(shù)據(jù)緩沖存儲(chǔ)區(qū)。在數(shù)據(jù)的接收過(guò)程中,通信卡會(huì)自動(dòng)接收幀數(shù)據(jù),判別幀長(zhǎng)度,在幀尾將接收到的幀數(shù)據(jù)提交系統(tǒng)。在發(fā)送數(shù)據(jù)過(guò)程中,系統(tǒng)只須把發(fā)送的數(shù)據(jù)提交給本卡,具體的發(fā)送過(guò)程由該卡自行完成,不因多路通信而使主機(jī)增加開(kāi)銷(xiāo)。該卡有內(nèi)/外時(shí)鐘兩種工作方式,近距離可省去調(diào)制解調(diào)器,波特率為600b/s~64Kb/s,提供2路符合RS-232/CCITT V.24和RS-422A標(biāo)準(zhǔn)的接口信號(hào)。 2 通信卡的電路設(shè)計(jì) 圖1 通信卡框圖 通信卡組成框圖如圖1所示。其主要由DMA控制器、總線竟?fàn)幹俨闷、串行通信控制器、?shù)據(jù)緩沖存儲(chǔ)器SRAM、存儲(chǔ)器I/O映像和物理地址產(chǎn)生器、總線接口及防護(hù)、波特率產(chǎn)生器、接口電路等單元電路組成。 DMA控制器作為通信卡的主設(shè)備,控制卡上的數(shù)據(jù)接收和發(fā)送(來(lái)自通信控制器和CPU),并負(fù)責(zé)仲裁優(yōu)先權(quán)。由于在進(jìn)行數(shù)據(jù)通信時(shí),允許主機(jī)CPU訪問(wèn)本卡SRAM,且主機(jī)對(duì)其中某一路發(fā)控制命令時(shí),不影響其余三路通信,這樣將會(huì)使主機(jī)CPU與本卡DMA竟?fàn)幈究ǹ偩控制權(quán)。而總線上沒(méi)有給出主機(jī)CPU指令排隊(duì)狀態(tài)序列,故不能直接設(shè)計(jì)多主竟?fàn),因而在本卡總線上用門(mén)陣列設(shè)計(jì)了一個(gè)狀態(tài)機(jī),不斷地監(jiān)視總線爭(zhēng)用情況,完成本卡總線竟?fàn)、仲裁功能。完成HDLC規(guī)程的串行通信的器件是INTEL8274多規(guī)程串行控制器,它能完成2個(gè)獨(dú)立的串行接收/發(fā)送全雙工通信。為了使4個(gè)信道在一幀數(shù)據(jù)的發(fā)送或接收過(guò)程中,主機(jī)不干預(yù),故將發(fā)送的一幀數(shù)據(jù)在發(fā)送開(kāi)始前由CPU用批命令放入卡上的SRAM中;同樣,在接收過(guò)程中,卡上DMA將接收到的數(shù)據(jù)放入SRAM中,等一幀接收完成后,再用批命令取出,放入系統(tǒng)存儲(chǔ)器中?ㄉ蟂RAM不占用主機(jī)內(nèi)存地址,采用I/0映像,該適配器插入主機(jī)之后,主機(jī)通過(guò)系統(tǒng)I/O地址對(duì)其訪問(wèn),這由地址產(chǎn)生器完成。總線接口包括數(shù)據(jù)收發(fā)器,數(shù)據(jù)開(kāi)關(guān)電路,讀、寫(xiě)及中斷等控制電路,地址譯碼等。波特率產(chǎn)生器提供了一個(gè)可編程的時(shí)鐘信號(hào)發(fā)生器,用戶可自行設(shè)置通信速率,供工作于內(nèi)時(shí)鐘方式時(shí)使用。接口電路提供符合RS-232/CCITT V.24和RS-422A標(biāo)準(zhǔn)的接口信號(hào)。 3通信流程設(shè)計(jì) 如果要發(fā)送一幀數(shù)據(jù),CPU用批命令將數(shù)據(jù)放到本卡SRAM中,然后設(shè)置相應(yīng)的發(fā)送DMA通道。DMA通道是非自動(dòng)重裝方式,啟動(dòng)8274控制器發(fā)送,然后CPU就不需要管理,由卡上硬件自動(dòng)發(fā)送。 如果需要接收數(shù)據(jù),啟動(dòng)接收通道。接收通路自動(dòng)搜索輸入信號(hào),搜索到數(shù)據(jù)幀時(shí),由卡上DMA控制器來(lái)管理,將接收的數(shù)據(jù)放入本卡SRAM中,并向CPU請(qǐng)求中斷,讀出數(shù)據(jù)。 4 總線竟?fàn)幵O(shè)計(jì) 由于同時(shí)可進(jìn)行四路通信,且CPU可隨時(shí)對(duì)某一路發(fā)控制命令或訪問(wèn)卡上SRAM存儲(chǔ)器,就將出現(xiàn)CPU與本卡主設(shè)備DMA爭(zhēng)用本卡總線的狀況。由于ISA總線沒(méi)能給出CPU指令排隊(duì)狀態(tài)序列,這給總線仲裁帶來(lái)了困難,而本卡的總線竟?fàn)、仲裁是由可編程邏輯器件設(shè)計(jì)的狀態(tài)機(jī)來(lái)完成的。狀態(tài)機(jī)使用一個(gè)4MHz信號(hào)作為時(shí)鐘,共設(shè)3種狀態(tài): ① CPU控制狀態(tài)。 ② DMA控制狀態(tài)。 ③ 空閑狀態(tài), CPU及DMA均未能得到控制權(quán)。 當(dāng)狀態(tài)機(jī)檢測(cè)到無(wú)CPU及DMA申請(qǐng)總線使用權(quán)時(shí),就進(jìn)入空閑狀態(tài),而一旦CPU或DMA請(qǐng)求總線,狀態(tài)機(jī)立即將總線使用權(quán)交給CPU或DMA。如果正在CPU控制狀態(tài)期間,DMA申請(qǐng)總線使用權(quán),狀態(tài)機(jī)仍然判定CPU控制總線,讓DMA處于等待,直到檢測(cè)CPU指令完成,狀態(tài)機(jī)才轉(zhuǎn)為DMA控制狀態(tài)。如果在DMA控制狀態(tài)時(shí),CPU申請(qǐng)總線使用權(quán),狀態(tài)機(jī)仍然判定DMA控制總線,讓CPU處于等待,直至DMA字節(jié)傳送完,狀態(tài)機(jī)轉(zhuǎn)為CPU控制狀態(tài)。CPU及DMA對(duì)總線的使用權(quán)是單個(gè)指令或字節(jié)傳送,不設(shè)置總線封鎖,因而CPU、DMA可頻繁交換使用權(quán),不會(huì)出現(xiàn)等待時(shí)間過(guò)長(zhǎng)的現(xiàn)象。 通信卡的驅(qū)動(dòng)程序設(shè)計(jì) 1 設(shè)備驅(qū)動(dòng)程序的I/O模型 通信卡的驅(qū)動(dòng)程序是利用WindowsXP的DDK軟件開(kāi)發(fā)的標(biāo)準(zhǔn)的核心態(tài)設(shè)備驅(qū)動(dòng)程序。它使用統(tǒng)一的“文件”形式,用戶可以通過(guò)代表通信卡設(shè)備的文件名,在WIN32子系統(tǒng)中用文件操作函數(shù)來(lái)訪問(wèn)。該設(shè)備驅(qū)動(dòng)和程序可以根據(jù)用戶的需要,設(shè)置為自動(dòng)加載,或手動(dòng)加載,也可以動(dòng)態(tài)的加載該驅(qū)動(dòng)程序。通信卡的驅(qū)動(dòng)程序設(shè)計(jì)成為支持同步I/O模型,也可以為異步I/O模型。 2 發(fā)送數(shù)據(jù)I/O例程設(shè)計(jì) 在用戶態(tài)提交發(fā)送任務(wù)到核心態(tài),由I/O管理程序負(fù)責(zé)調(diào)用驅(qū)動(dòng)程序,驅(qū)動(dòng)程序發(fā)送IRP交給硬件,假若當(dāng)前發(fā)送器不忙,則具體的發(fā)送操作全部由發(fā)送器自行完成,而驅(qū)動(dòng)程序則返回已經(jīng)一個(gè)本幀可以發(fā)送的標(biāo)志。具體的發(fā)送完成結(jié)果則可以在發(fā)送任務(wù)完成后查詢得到?墒牵绻绦蛳虍(dāng)前設(shè)備發(fā)送器提交發(fā)送任務(wù)時(shí),該發(fā)送器正在處理上一幀,那么則有兩種方法處理。 ① 立即方式:立即返回一個(gè)錯(cuò)誤,當(dāng)前設(shè)備忙,不能發(fā)送。 ②阻塞方式:I/O管理器程序會(huì)調(diào)度相應(yīng)的異步處理例程,將當(dāng)前的發(fā)送任務(wù)放進(jìn)任務(wù)隊(duì)列中,返回一個(gè)標(biāo)志:I/O掛起,當(dāng)前設(shè)備忙,發(fā)送任務(wù)提交任務(wù)隊(duì)列。驅(qū)動(dòng)程序會(huì)在發(fā)送器空閑時(shí),提交任務(wù)隊(duì)列中的發(fā)送任務(wù)給發(fā)送器。完成發(fā)送任務(wù)后,將相關(guān)文件句柄設(shè)為有信號(hào)狀態(tài),通知本次發(fā)送任務(wù)完成。 3接收數(shù)據(jù)I/O例程 接收數(shù)據(jù)例程采用客戶/服務(wù)器的模式設(shè)計(jì)。由于用戶的接收請(qǐng)求和硬件的接收并不是同步的,所以在設(shè)計(jì)中,為避免丟失數(shù)據(jù),考慮創(chuàng)造一個(gè)專(zhuān)門(mén)的接收線程。這樣,同步用戶請(qǐng)求、接收線程、硬件層之間的通信就必須仔細(xì)地設(shè)計(jì)。圖2示意了用戶態(tài)接收請(qǐng)求、接收線程以及硬件層之間的通信同步。 圖2 用戶態(tài)接收請(qǐng)求、接收線程與硬件層之間的通信同步 ① 硬件層與接收線程之間通信 硬件層與接收線程之間通信的同步是通過(guò)同步事件對(duì)象來(lái)實(shí)現(xiàn)的。同步事件對(duì)象通常處于無(wú)信號(hào)狀態(tài),只有當(dāng)成功地接收到一幀時(shí),才將該事件置為有信號(hào)狀態(tài)。接收線長(zhǎng)久等待同步事件對(duì)象,在沒(méi)有收到數(shù)據(jù)時(shí),因同步事件對(duì)象處于無(wú)信號(hào)狀態(tài)而阻塞。當(dāng)硬件檢測(cè)到數(shù)據(jù)時(shí),實(shí)時(shí)中斷服務(wù)程序負(fù)責(zé)將同步事件對(duì)象置為有信號(hào)狀態(tài),接收線程就會(huì)釋放阻塞。將通信卡SRAM上的接收數(shù)據(jù)讀進(jìn)接收線程緩沖區(qū)隊(duì)列,然后將同步事件對(duì)象置為無(wú)信號(hào)狀態(tài),接收線程再次阻塞,等待接收下一幀數(shù)據(jù)。 ② 用戶層和接收線程之間的通信 當(dāng)用戶提交接收任務(wù)時(shí),由驅(qū)動(dòng)程序的調(diào)度程序讀取接收線程的緩沖區(qū)隊(duì)列,并將標(biāo)志置為“空”,同時(shí)將緩沖隊(duì)列事件置為無(wú)信號(hào)狀態(tài),并返回,如果緩沖區(qū)是空,則 ● 立即方式:立即返回?zé)o數(shù)據(jù)。 ● 阻塞方式:阻塞直到有數(shù)據(jù)隊(duì)列進(jìn)入。接收隊(duì)列的每個(gè)緩沖區(qū)都對(duì)應(yīng)一個(gè)通知事件,如果接收線程將SRAM中的數(shù)據(jù)讀進(jìn)隊(duì)列,就將相應(yīng)的通知事件置為有信號(hào)狀態(tài),用戶請(qǐng)求就等待該通知事件,只要有數(shù)據(jù)在隊(duì)列中,就讀取返回,否則被阻塞。 4 硬中斷服務(wù)程序設(shè)計(jì) 通信卡在全雙工的通信中具有實(shí)時(shí)性,而且在較高的波特率,硬中斷非常多。為了防止高優(yōu)先級(jí)中斷過(guò)多地?fù)屨糃PU時(shí)間,設(shè)計(jì)中采用了實(shí)時(shí)中斷服務(wù)程序和延遲過(guò)程調(diào)用的方法。 在WindowsXP系統(tǒng)中,每個(gè)內(nèi)核函數(shù)和過(guò)程都運(yùn)行于特定的優(yōu)先級(jí)。較高優(yōu)先級(jí)的函數(shù)或事件可以搶占較低優(yōu)先級(jí),反之則不然。實(shí)時(shí)中斷服務(wù)程序ISR運(yùn)行于DIRQL級(jí),具有較高的優(yōu)先級(jí),它只能被更高級(jí)的硬中斷所搶占,不會(huì)對(duì)同級(jí)或較低優(yōu)先級(jí)的硬中斷的響應(yīng)。所以,在實(shí)時(shí)中斷服務(wù)程序中,只做盡量少的必須工作,即讀出中斷向量,而將大量的數(shù)據(jù)傳送及處理等工作交給延遲過(guò)程DPC去完成。因?yàn)镈PC過(guò)程運(yùn)行于DISPATCH_LEVEL級(jí),是相對(duì)較低的優(yōu)先級(jí),它可以被任何級(jí)的硬中斷所搶占。這樣,既保證了硬中斷的及時(shí)響應(yīng),又提高了程序的性能。 5 驅(qū)動(dòng)程序入口例程 WindowsXP為每個(gè)核心態(tài)的驅(qū)動(dòng)程序提供了一個(gè)默認(rèn)的標(biāo)準(zhǔn)入口點(diǎn)DriverEntry()。設(shè)計(jì)中,考慮到該例程運(yùn)行于PASSIVE_LEVE級(jí),系統(tǒng)只運(yùn)行該例程一次就拋棄了,所以在驅(qū)動(dòng)程序中用到的重要數(shù)據(jù)、對(duì)象等都不能保存在DriverEntry()例程中,必須在初始化過(guò)程中分配一塊NoPaged內(nèi)存來(lái)保存。通信卡的驅(qū)動(dòng)程序的DriverEntry()例程主要完成如下功能。 讀取Registry的硬件配置信息;聲明I/O地址、中斷等資源;創(chuàng)建代表通信卡的設(shè)備名MPSC,該名字對(duì)WIN32子系統(tǒng)是可見(jiàn)的;設(shè)置調(diào)度例程入口點(diǎn);分配一塊NoPaged的內(nèi)存,存儲(chǔ)重要信息;連接硬中斷,設(shè)置中斷服務(wù)程序;初始化線程、事件、信號(hào)燈、DPC等內(nèi)核對(duì)象;返回狀態(tài)STATUS_SUCCESS。 如果在以上過(guò)程中遇到錯(cuò)誤,則需要做以下工作:斷開(kāi)硬中斷;釋放硬件資源;將相關(guān)的錯(cuò)誤信息打包,并記錄;返回錯(cuò)誤信息。 6 設(shè)計(jì)驅(qū)動(dòng)程序中需要注意的問(wèn)題 于通信卡在應(yīng)用中具有一定的實(shí)時(shí)性,為了克服中斷的不確定性,提高系統(tǒng)的性能,開(kāi)發(fā)了WindowsXP系統(tǒng)所有驅(qū)動(dòng)程序中最難的異步驅(qū)動(dòng)程序。在系統(tǒng)的內(nèi)核開(kāi)發(fā),異步模型I/O操作中,內(nèi)核對(duì)象的同步十分復(fù)雜,細(xì)微的差錯(cuò)都會(huì)導(dǎo)致系統(tǒng)徹底崩潰。在設(shè)計(jì)驅(qū)動(dòng)程序中需要注意以下問(wèn)題。 ● 在程序中用到的內(nèi)核對(duì)象:事件、信號(hào)燈、線程以及轉(zhuǎn)鎖等,都必須將其存儲(chǔ)在Nopaged內(nèi)存中,否則,會(huì)造成系統(tǒng)崩潰。 ● 在DPC例程中,如果要訪問(wèn)中斷服務(wù)程序ISR程序中用到端口地址,一定要將訪問(wèn)語(yǔ)句放在系統(tǒng)提供的同步例程中,這是因?yàn)楫?dāng)DPC例程訪問(wèn)該端口時(shí),有可能被優(yōu)先級(jí)高的ISR例程所搶占,而造成數(shù)據(jù)錯(cuò)誤。 ● 驅(qū)動(dòng)程序一定不要訪問(wèn)WIN32子系統(tǒng)的運(yùn)行庫(kù)函數(shù)。 |