專利名稱::可用于因特網(wǎng)的網(wǎng)絡(luò)流量計算機系統(tǒng)的制作方法本申請要求1998年12月15日提交的名稱為“可用于因特網(wǎng)的網(wǎng)絡(luò)流量計算機系統(tǒng)”的No.09/212/176號美國專利申請的利益,并將該申請引入本文作為參考。本發(fā)明一般涉及用于測量和控制通過管道或水渠的液體和氣體的流量的計算機系統(tǒng)。本發(fā)明具體涉及可以遠程和本地訪問的流量計算機。本發(fā)明還具體涉及用作web服務(wù)器的流量計算機,能夠使操作者控制該流量計算機,并通過因特網(wǎng),內(nèi)部網(wǎng)和類似技術(shù)從流量計算機獲得流量測量。在世界范圍內(nèi)廣泛使用流量計算機來控制和測量管道中液體和氣體的流量。流量計算機被用于各種產(chǎn)業(yè)中,例如石油和天然氣工業(yè)和水處理工業(yè)。流量計算機通常連接到多個流量傳感器,接收用于指示液體或氣體流量的信號。流量計算機處理這些信號以獲得所需流量計算。在某些產(chǎn)業(yè)領(lǐng)域,這些流量計算被用于確定已經(jīng)通過一個管道的商品(例如石油或天然氣)的數(shù)量。在一些情況下,將流量計算作為商業(yè)交易的基礎(chǔ)來確定已經(jīng)從一方轉(zhuǎn)手到另一方的商品的體積。因為涉及到數(shù)量和金錢,因此非常關(guān)鍵的是流量計算機要極其精確和極其可靠,而不管其使用環(huán)境如何。除了這種提供精確流量測量的重要功能之外,流量計算機還可以用于自動控制各種管道設(shè)備,例如閥門,儀表,電子開關(guān)和其它用于控制液體或氣體的工作和流量的裝置。如圖1所示,常規(guī)流量計算機10包括具有相關(guān)的輔助存儲裝置13、鍵盤14、LCD顯示器15和數(shù)據(jù)端口17-23的處理器11。流量計算機10還可以包括軟盤驅(qū)動器16。流量計算機10可以通過數(shù)據(jù)端口17-23連接各種流量測量變換器24-26,控制裝置29-30,調(diào)制解調(diào)器27,和串行輸入/輸出裝置28,例如主計算機31。數(shù)據(jù)端口17-23可以是RS-232或RS-485數(shù)據(jù)端口。微處理器(或“處理器”)11作為流量計算機10的“大腦”工作。微處理器11例如通過流量測量變換器24-26連接到管道。已知有多種合適的變換器24-26能夠提供模擬電壓、模擬電流、頻率或其它格式的數(shù)據(jù),但是所有這些變換器都提供關(guān)于通過管道流動的液體的數(shù)量和性質(zhì)的監(jiān)視數(shù)據(jù)。微處理器11監(jiān)視來自變換器的數(shù)據(jù),進行計算,并執(zhí)行其它功能。在輔助存儲裝置13中嵌入了允許微處理器11執(zhí)行這些功能的軟件。輔助存儲裝置13通常是被稱作“閃速盤”或ROM芯片的昂貴的固態(tài)器件,其可以承受流量計算機通常工作時所處的惡劣環(huán)境和極端天氣條件。流量計算機10可以由“現(xiàn)場”操作者控制。鍵盤14允許操作者輸入信息,例如一些命令,用于確定以何種頻度讀取流量測量讀數(shù)和計算其結(jié)果。操作者還可以選擇使用軟盤驅(qū)動器16或其它適當(dāng)?shù)拇鎯ρb置,來將數(shù)據(jù)裝載和存儲到流量計算機10中。處理器11通過LCD顯示器屏幕15向操作者提供視覺反饋。另選地,操作者可以選擇通過數(shù)據(jù)端口17-23中的一個端口將一個膝上型計算機或其它接口裝置31“插入”到流量計算機上。這使得流量計算機10的擁有者或操作者能夠容易地從流量計算機獲得流量測量信息,并能夠在必要時對流量計算機的軟件進行再編程或修改。參見圖1,盡管有可能直接或在本地對流量計算機10進行配置,遠程地與流量計算機10通信也是眾所周知的。例如,調(diào)制解調(diào)器27連接到電話線32并允許主計算機到流量計算機10的遠程連接。當(dāng)流量計算機位于難以訪問的位置時,可以使用衛(wèi)星天線裝置來形成衛(wèi)星鏈路,以向/從主計算機傳送信息。因此,如果一個石油公司希望從深水海上平臺得到流量數(shù)據(jù),該石油公司可以通過衛(wèi)星連接從一個主計算機建立與流量計算機的通信,從而獲得希望的流量信息。另選地,操作者可以來到該海上平臺,將膝上型計算機連接到流量計算機以取出所需信息。與流量計算機的遠程通信提供的優(yōu)點是,可以通過膝上型計算機與流量計算機進行現(xiàn)場鏈接,而無需物理地連接到流量計算機。但是,這種方法在當(dāng)前系統(tǒng)中存在幾個問題。盡管系統(tǒng)允許從遠端位置容易地獲得流量測量,但是存在幾個問題。第一個問題是,流量計算機的制造商通常在它們的流量計算機10中實現(xiàn)它們自己的專有通信協(xié)議。制造商甚至可能使用一種使用專有操作系統(tǒng)的定制處理器。因此,主計算機31必須具有能夠與流量計算機上運行的專有軟件連接和通信的專用軟件,以便配置流量計算機或從流量計算機取出信息。同樣,如果使用膝上型計算機直接與流量計算機通信,該膝上型計算機必須使用適當(dāng)?shù)膶S型ㄐ艆f(xié)議。本領(lǐng)域技術(shù)人員可以理解,客戶可能采用來自多個制造商的流量計算機。在此情況下,客戶必須了解每個流量計算機的制造商,從而在與一個特定流量計算機通信時能使用正確的通信協(xié)議。更不利的是,流量計算機制造商定期地為它們的流量計算機發(fā)布新版本軟件。在用新軟件更新流量計算機時,主計算機或膝上型計算機也必須更新。因此,客戶必須不僅記錄制造商,還要記錄流量計算機中駐留的軟件的版本,以確??梢杂芍饔嬎銠C或膝上型計算機進行正確通信和控制。因此,每次向軟件加入一個新特性或者使用一個新的或改進的協(xié)議時,主計算機都必須做相應(yīng)的修改/更新。不可避免地存在在不同主機上運行的很多版本的軟件。結(jié)果,會產(chǎn)生一個重要問題,即,一個特定主機會由于其所運行的主機軟件的版本不同,而能夠或不能有效地通信和使用一個給定流量計算機的某些或全部特性。而且,流量計算機的制造商為了試圖確保與還沒有更新為最新軟件版本的主機軟件的向后兼容性,會面臨大量的工作。軟件版本兼容性問題會造成現(xiàn)場用戶的困惑,以及客戶服務(wù)的不利局面。這個問題已經(jīng)存在很多年,而沒有任何可行的解決方法。盡管這個問題眾所周知,但是沒有出現(xiàn)有效的解決方法。當(dāng)前沒有一個工業(yè)標(biāo)準(zhǔn)協(xié)議,而且隨著技術(shù)的發(fā)展,工業(yè)標(biāo)準(zhǔn)協(xié)議可能會過于局限。MODBUS就是這樣一個例子,MODBUS是當(dāng)前用于將流量變換器(例如24-26)連接到流量計算機10的一種工業(yè)標(biāo)準(zhǔn)總線。MODBUS技術(shù)大約有20年的歷史,已經(jīng)不能跟上近年來很多技術(shù)發(fā)展的步伐。因此,為了使MODBUS能夠用于某些當(dāng)前技術(shù),必須對MODBUS進行改進。但問題是,一旦修改了標(biāo)準(zhǔn)MODBUS結(jié)構(gòu),就會在流量計算機和變換器之間引起不兼容性,除非二者使用相同版本的MODBUS。因此,除非持續(xù)更新工業(yè)標(biāo)準(zhǔn)結(jié)構(gòu)或協(xié)議,否則該標(biāo)準(zhǔn)會過時。希望能為流量計算機和主計算機開發(fā)出標(biāo)準(zhǔn)化結(jié)構(gòu)和協(xié)議,同時允許足夠的靈活性,以允許在流量計算機技術(shù)中實現(xiàn)技術(shù)改進。盡管這種系統(tǒng)提供了明顯的優(yōu)點,但是還沒有解決上述問題的方法。本發(fā)明的一個實施例包括一種網(wǎng)絡(luò)流量系統(tǒng),其包括至少一個測量裝置;流量計算機,配置為web服務(wù)器并與測量裝置相連,從測量裝置接收數(shù)據(jù);和主計算機,在本地或通過因特網(wǎng)/內(nèi)部網(wǎng)連接與流量計算機通信。因此,統(tǒng)一資源定位器(“URL”)地址可以標(biāo)識流量計算機,并且主機可以從流量計算機以網(wǎng)頁格式接收數(shù)據(jù)。流量計算機還可以進行自配置以識別一個附接的測量裝置并與其通信。流量計算機可以具有壓縮在閃速盤上的可升級操作系統(tǒng),并可以由主計算機遠程編程。主計算機可以通過web瀏覽器與流量計算機通信。本發(fā)明的另一個實施例是一種用于獲得測量數(shù)據(jù)的方法。該方法包括將一流量計算機耦合到一個適于監(jiān)視流體并提供相應(yīng)測量數(shù)據(jù)的測量裝置;通過通信鏈路將流量計算機連接到一主計算機;流量計算機使用第一協(xié)議從測量裝置獲得測量數(shù)據(jù),并使用第二協(xié)議與主計算機通信,第二協(xié)議適于因特網(wǎng)/內(nèi)部網(wǎng)通信。還可以提出本方法的其它方面。例如,可以以有規(guī)律的間隔詢問測量裝置,主計算機可以對流量計算機編程,可以使用URL地址識別流量計算機,并且流量計算機可以產(chǎn)生一個包括來自測量裝置的數(shù)據(jù)的網(wǎng)頁。通過結(jié)合以下附圖對優(yōu)選實施例的詳細說明可以對本發(fā)明有更好的理解圖1是現(xiàn)有技術(shù)流量計算機系統(tǒng)的方框圖;圖2是根據(jù)優(yōu)選實施例構(gòu)建的改進流量計算機和主機系統(tǒng)的方框圖;圖3是根據(jù)本發(fā)明原理構(gòu)建的圖2的網(wǎng)絡(luò)流量計算機的方框圖;圖4是圖2的網(wǎng)絡(luò)流量計算機中實現(xiàn)的軟件的方框圖;圖5是圖2的網(wǎng)絡(luò)流量計算機的閃速盤,BIOS和RAM盤的方框圖;圖6是圖2的網(wǎng)絡(luò)流量計算機上執(zhí)行的閃速盤初始化例程的流程圖。下面的詳細說明描述了用于實現(xiàn)本發(fā)明基本原理的優(yōu)選實施例。但是,本領(lǐng)域技術(shù)人員應(yīng)該理解,下面的說明是本發(fā)明的例示,不應(yīng)被理解為限制此處所述的原理。而且,在以下的說明書和使用了某些術(shù)語來表示特定的系統(tǒng)部件。本領(lǐng)域技術(shù)人員應(yīng)該理解,制造商可能會以不同的名稱命名一個部件。本申請文件并不意圖區(qū)分功能相同而名稱不同的部件。在以下的討論和權(quán)利要求中,以一種開放方式使用術(shù)語“包括”,因此其應(yīng)被理解為“包括,而不是被限制為……”。此外,使用的術(shù)語“流體”意欲包括液體和氣體。而且,術(shù)語“耦合”或“連接”意欲表示間接或直接電連接。因此,如果第一裝置耦合或連接到第二裝置,該連接可以是通過直接電連接實現(xiàn)或者是通過利用其它裝置和連接的間接電連接實現(xiàn)?,F(xiàn)在參考圖2,主計算機50通過因特網(wǎng)、內(nèi)部網(wǎng)或類似技術(shù)耦合到一個或多個網(wǎng)絡(luò)流量計算機100,800,900。流量計算機還通過一標(biāo)準(zhǔn)化總線(例如MODBUS)連接到各種流量測量裝置710,720,730。盡管圖2中顯示了三個這種測量裝置連接到每個流量計算機,本領(lǐng)域技術(shù)人員可以理解,流量測量裝置和其它設(shè)備的數(shù)量可以改變。同樣,主計算機50可以作為不受限制的未規(guī)定數(shù)量的流量計算機的主機。根據(jù)本發(fā)明的優(yōu)選實施例,流量計算機被編程以從測量裝置(例如710,720,730)收集或接收數(shù)據(jù)。流量計算機100還被編程為一個web服務(wù)器,使得其可以通過因特網(wǎng)、內(nèi)部網(wǎng)或類似技術(shù)的連接進行通信。除了作為web服務(wù)器工作以外,網(wǎng)絡(luò)流量計算機100還執(zhí)行其它流量計算軟件。主計算機50可以包括任何PC(個人計算機),膝上型計算機,工作站,大型計算機,或能夠支持因特網(wǎng)、內(nèi)部網(wǎng)或類似技術(shù)訪問的任何其它類型的計算機。網(wǎng)絡(luò)流量計算機100可以基于INTELx86系列微處理器或兼容的處理器,例如AMD制造的K6和K7系列處理器,CYRIX的PR系列,IDT的C6和C7系列微處理器。網(wǎng)絡(luò)流量計算機100還可以基于SUMMICROSYSTEM的RS6000,SPARC,或基于ALPHARISC微處理器的機器。另選地,網(wǎng)絡(luò)流量計算機100可以基于能夠執(zhí)行本發(fā)明所需操作的任何其它類型的微處理器。優(yōu)選實施例期待使用基于INTELx86的計算機作為最有成本效率的平臺。對于x86平臺上的網(wǎng)絡(luò)流量計算機的最低系統(tǒng)需求是386級別的微處理器,例如可以從INTEL,AMD和CYRIX等制造商購買的微處理器。本發(fā)明也可以在更高級別x86架構(gòu)的微處理器(例如486系列,PENTIUM,PENTIUMPRO,PENTIUMII等等)上工作。如上所述,本發(fā)明也可以在非x86平臺計算機上工作。盡管最佳模式實現(xiàn)了一種標(biāo)準(zhǔn)PC配置,本發(fā)明也可以在具有嵌入式計算機或處理器的機器中實現(xiàn)。主計算機50最好運行一個因特網(wǎng)web瀏覽器軟件包,例如微軟的INTERNETEXPLORER或者網(wǎng)景的NAVIGATOR軟件,盡管也可以使用任何通用的瀏覽器。在主計算機上不需要其它專用軟件。但是,如果需要,可以利用專用軟件對主計算機50編程以實現(xiàn)與網(wǎng)絡(luò)流量計算機上運行的舊版本軟件的向后兼容性。這種專用軟件與本發(fā)明優(yōu)選實施例中實現(xiàn)的軟件共存。主計算機50可以直接連接到因特網(wǎng)或者通過服務(wù)提供商連接到因特網(wǎng)。同樣,主計算機50和網(wǎng)絡(luò)流量計算機100可以使用任何通信媒介連接到因特網(wǎng),其中包括標(biāo)準(zhǔn)模擬電話線連接,ISDN連接,T1連接,衛(wèi)星連接,直接導(dǎo)線連接等等。主計算機50也可以繞過公共因特網(wǎng)直接連接到流量計算機100(例如通過使用內(nèi)部網(wǎng)和類似技術(shù))。在操作期間,流量測量裝置710,720和730監(jiān)視并測量所關(guān)注流體或流體的特定參數(shù)。流量計算機100接收來自流量測量裝置710,720和730的流量測量值并進行流量計算。然后,流量計算機將這些流量計算實時顯示在網(wǎng)頁上。還可以要求流量計算機100顯示歷史信息和其它測量值或配置數(shù)據(jù)。因此,每個流量計算機具有其自己的web地址。主計算機50通過簡單地輸入一個特定流量計算機的相應(yīng)URL地址來訪問這些流量計算機。例如,為了對流量計算機100尋址,主計算機50的操作者選擇用于流量計算機100的因特網(wǎng)URL地址,其在圖2的例子中顯示為www.flow#1.com。雖然本發(fā)明使用URL來識別流量計算機100的地址,本發(fā)明包括可以用于識別流量計算機的任何其它類型的尋址方式。響應(yīng)于該地址選擇,流量計算機100被連接,并以它的網(wǎng)頁應(yīng)答,該網(wǎng)頁最好包括當(dāng)前流量計算的清單??梢詮脑撚嬎銠C的網(wǎng)頁中的菜單項目中選擇流量計算機100的其它特性和細節(jié)。以類似方式,可以通過因特網(wǎng)、內(nèi)部網(wǎng)或類似技術(shù)對客戶的詳細目錄中的其它的每個流量計算機尋址并實時監(jiān)視其信息。圖2所示的配置解決了與現(xiàn)有技術(shù)相關(guān)的很多問題。現(xiàn)有技術(shù)測量裝置710,720,730可以僅使用單一工業(yè)標(biāo)準(zhǔn)協(xié)議操作。例如,氣相色譜儀僅使用MODBUS協(xié)議來與外部裝置通信。當(dāng)氣相色譜儀使用工業(yè)標(biāo)準(zhǔn)MODBUS協(xié)議連接到網(wǎng)絡(luò)流量計算機時,氣相色譜儀實際上成為一個可以通過網(wǎng)絡(luò)流量計算機遠程訪問的聯(lián)網(wǎng)的氣相色譜儀。而且,氣相色譜儀上的軟件不需要升級。只要氣相色譜儀如上所述耦合到網(wǎng)絡(luò)流量計算機100,網(wǎng)絡(luò)流量計算機就能使氣相色譜儀所提供的流量測量數(shù)據(jù)可以由位于世界上任何位置的任何主計算機50遠程訪問。這使得無需確保流量計算機和主計算機運行相同版本的軟件。此外,這種解決方法在實際世界中非常實用,因為因特網(wǎng)連接具有廣泛的可用性。本發(fā)明的原理可以應(yīng)用于現(xiàn)有儀表,例如氣相色譜儀,超聲波測量儀,孔板流量計。例如,這些儀表可以已經(jīng)在它們的設(shè)計中包括了相關(guān)的電子器件。這些電子器件可以與網(wǎng)絡(luò)流量計算機集成在一起,使得這種儀表實際成為具有內(nèi)置的網(wǎng)絡(luò)流量計算機的可用于因特網(wǎng)的儀表。當(dāng)本發(fā)明用于這種儀表中時,除了儀表中的現(xiàn)有功能以外,儀表還能夠以類似于本發(fā)明優(yōu)選實施例的方式工作。操作參見圖3,根據(jù)優(yōu)選實施例構(gòu)建的網(wǎng)絡(luò)流量計算機100包括以100Mhz或133Mhz時鐘速度工作的PENTIUM系列微處理器。網(wǎng)絡(luò)流量計算機100優(yōu)選包括最少2兆字節(jié)的閃速盤170,最好具有5-10MB。閃速盤的實際大小在一定程度上取決于系統(tǒng)中包括的選項或特性的數(shù)量。流量計算機100優(yōu)選還包括至少8MB的RAM130,最好具有16-32MB。流量計算機100還包括一顯示機構(gòu)110。顯示器110可以是以標(biāo)準(zhǔn)PC配置實現(xiàn)的流量計算機中的獨立監(jiān)視器。當(dāng)流量計算機100在具有嵌入式計算機或處理器的機器中實現(xiàn)時,顯示器110可以是LCD顯示單元,例如只顯示文本的2”x16”LCD顯示器。流量計算機100還包括鍵盤145,并且可以包括軟盤驅(qū)動器160。網(wǎng)絡(luò)流量計算機100最好還包括一個或多個總線接口185,例如ISA和PCI總線接口。流量計算機100中的模擬和數(shù)字接口卡190耦合到流量計算機的總線接口185。將諸如渦輪式流量計710、壓力變換器720、壓差變換器730、溫度探頭740和其它流量測量裝置750等流量測量裝置耦合到模擬或數(shù)字接口卡190。這種流量測量裝置在實時基礎(chǔ)上將流量數(shù)據(jù)提供給流量計算機100。當(dāng)流量測量裝置710,720,730,740和750被直接連接到網(wǎng)絡(luò)流量計算機100時,網(wǎng)絡(luò)流量計算機成為這些流量測量裝置的流量計。作為流量計,網(wǎng)絡(luò)流量計算機100接收并處理由流量測量裝置710,720,730,740和750發(fā)送的數(shù)字和模擬信號。然后,網(wǎng)絡(luò)流量計算機100對從流量測量裝置710,720,730,740和750接收的原始數(shù)據(jù)進行必要的計算和校正。流量計算機100將計算的流量測量結(jié)果存儲在閃速盤170上的記錄文件中。流量計算機還可以進行自配置以識別一個附接的測量裝置并與其通信。本領(lǐng)域技術(shù)人員可以理解,識別附接到一個計算機的外圍設(shè)備的方法是本領(lǐng)域公知的。主計算機50可以通過因特網(wǎng)340連接到網(wǎng)絡(luò)流量計算機100以實時查看流量結(jié)果。如上所述,主計算機50也可以通過內(nèi)部網(wǎng)或類似技術(shù)連接到網(wǎng)絡(luò)流量計算機100。在主計算機50,以數(shù)據(jù)的圖形,表格或任何其它希望的顯示方式顯示計算的流量結(jié)果。而且,流量計算機100可以存儲一部分或全部計算的流量結(jié)果以備主計算機50的以后分析。仍然參見圖3,網(wǎng)絡(luò)流量計算機100最好還包括一個或多個串行端口150,例如RS-232或RS-485串行端口。串行端口150使得網(wǎng)絡(luò)流量計算機100能夠與各種外部裝置通信。網(wǎng)絡(luò)流量計算機100通過串行端口150耦合到超聲波測量儀400和氣相色譜儀500。流量計算機100使用工業(yè)標(biāo)準(zhǔn)MODBUS協(xié)議通過RS-232或RS-485串行端口與超聲波測量儀400,氣相色譜儀500,和流量計算機600通信。串行端口150還用于提供主計算機50與網(wǎng)絡(luò)流量計算機100的直接連接。當(dāng)由于各種原因(例如對網(wǎng)絡(luò)流量計算機檢測故障或維修)而使得主計算機用戶物理地位于網(wǎng)絡(luò)流量計算機的位置時,通常需要通過串行端口150將主計算機50與網(wǎng)絡(luò)流量計算機100直接連接。使用工業(yè)標(biāo)準(zhǔn)MODBUS協(xié)議通過RS-232或RS-485串行端口150將氣相色譜儀500連接到網(wǎng)絡(luò)流量計算機100。仍然參見圖3,網(wǎng)絡(luò)流量計算機100通過串行端口150耦合到超聲波測量儀400。超聲波測量儀400也可以通過LAN接口140和LAN服務(wù)器320連接到網(wǎng)絡(luò)流量計算機100。超聲波測量儀400嚴(yán)格地講可以是一個流量計或流量計算機。作為流量計,超聲波測量儀400記錄原始速度流量數(shù)據(jù),并不進行諸如溫度和壓力的任何數(shù)據(jù)校正。然后,超聲波測量儀400將原始數(shù)據(jù)傳送到流量計算機100,流量計算機100進行所有必要的計算,包括對溫度和壓力的數(shù)據(jù)校正。作為流量計算機,超聲波測量儀400不僅記錄原始數(shù)據(jù),還進行必要的計算,校正溫度和壓力數(shù)據(jù),并最終將計算結(jié)果傳送到網(wǎng)絡(luò)流量計算機100。網(wǎng)絡(luò)流量計算機100通過串行端口150耦合到其它流量計算機。例如,網(wǎng)絡(luò)流量計算機100可以通過串行端口150耦合到另一個流量計算機600,例如市售的DANIELSPECTRA100。外部流量計算機600自己可以耦合到其它流量測量裝置,例如裝置710,720,730,740和750。在這種配置中,網(wǎng)絡(luò)流量計算機100通過流量計算機600間接連接到流量測量裝置710,720,730,740和750。在網(wǎng)絡(luò)流量計算機100與流量測量裝置710,720,730,740和750的間接連接中,流量計算機600接收并處理來自測量裝置的數(shù)字和模擬流量信號,流量計算機600通常執(zhí)行所有必要的流量測量計算。然后流量計算機600將計算結(jié)果傳送到網(wǎng)絡(luò)流量計算機100。在接收到計算結(jié)果后,網(wǎng)絡(luò)流量計算機100將結(jié)果存儲在閃速盤170上的記錄文件中。在本發(fā)明的優(yōu)選實施例中,網(wǎng)絡(luò)流量計算機100通過因特網(wǎng)和萬維網(wǎng)340連接到主計算機50。如上所述,并且本領(lǐng)域技術(shù)人員可以理解的是,網(wǎng)絡(luò)流量計算機100也可以通過內(nèi)部網(wǎng)和類似技術(shù)連接到主計算機50。流量計算機100可以以很多不同方式連接到因特網(wǎng)和萬維網(wǎng)340。在優(yōu)選實施例中,流量計算機100通過局域網(wǎng)(“LAN”)連接到因特網(wǎng)和萬維網(wǎng)340。網(wǎng)絡(luò)流量計算機100包括LAN接口140。盡管優(yōu)選實施例使用工業(yè)標(biāo)準(zhǔn)以太網(wǎng)LAN,本領(lǐng)域技術(shù)人員可以理解,也可以使用其它的市售LAN,例如LONWORKS,PROFIBUS,DEVICENET,CAN,USB,或者任何其它工業(yè)標(biāo)準(zhǔn)LAN。LAN連接140使得流量計算機100能夠與因特網(wǎng)和萬維網(wǎng)340連接。LAN連接140也使得網(wǎng)絡(luò)流量計算機100能夠在其使用位置與其它設(shè)備聯(lián)網(wǎng)。為了能夠?qū)⒘髁坑嬎銠C連接到因特網(wǎng)340,LAN接口140耦合到路由器或網(wǎng)關(guān)310,路由器或網(wǎng)關(guān)310又耦合到LAN服務(wù)器320。為了防止未授權(quán)訪問,從因特網(wǎng)向LAN的病毒侵入,和考慮到其它安全原因,通過將LAN服務(wù)器320耦合到防火墻330來保護流量計算機100的LAN連接140。然后將防火墻330耦合到因特網(wǎng)和萬維網(wǎng)340。盡管在優(yōu)選實施例中流量計算機100耦合到因特網(wǎng)和萬維網(wǎng)340,本領(lǐng)域技術(shù)人員可以理解,本發(fā)明可以同樣適用于對因特網(wǎng),萬維網(wǎng)或因特網(wǎng)的其它方面的任何改進,包括所謂的即將到來的“第二代因特網(wǎng)”。仍然參見圖3,網(wǎng)絡(luò)流量計算機100也可以通過其它通信媒介連接到因特網(wǎng)和萬維網(wǎng)340。因此,流量計算機100最好還包括一個或多個通信接口卡115,接口卡115通過調(diào)制解調(diào)器210,衛(wèi)星220,ISDN230,T1線路240和電纜250耦合到各種外部通信裝置。調(diào)制解調(diào)器210,衛(wèi)星220,ISDN230,T1線路240和電纜250中的任何一個或多個通信媒介都可以用于將網(wǎng)絡(luò)流量計算機100連接到因特網(wǎng)和萬維網(wǎng)340。同樣,主計算機50被連接到因特網(wǎng)和萬維網(wǎng)340?,F(xiàn)在參見圖4,已經(jīng)編制了用戶軟件并將其與市售的或公用軟件組合,以實現(xiàn)網(wǎng)絡(luò)流量計算機100。圖4中軟件的組合,順序,分層或分級是為了簡化優(yōu)選實施例中所用軟件的討論。不應(yīng)將其解釋為對本發(fā)明的限制。軟件的不同組合,順序,分層或分級可用于本發(fā)明。用于本發(fā)明優(yōu)選實施例的軟件包括LINUX操作系統(tǒng)(“OS”)101,網(wǎng)絡(luò)服務(wù)軟件NETSERVICES102,工業(yè)標(biāo)準(zhǔn)MODBUS通信協(xié)議103,APACHEweb服務(wù)器104,CGI腳本和HTML碼105以及JAVA小程序和C程序106。網(wǎng)絡(luò)流量計算機100中的軟件的基礎(chǔ)平臺最好包括REDHATLINUX操作系統(tǒng)(“OS”)101。LINUXOS101是一種多任務(wù)和多用戶操作系統(tǒng)。REDHATLINUXOS101是通行的UNIX操作系統(tǒng)的一種變形。REDHATLINUXOS可以從REDHATSOFTWARE,INC.(http//www.redhat.com)購買。LINUXOS101包含用于網(wǎng)絡(luò)流量計算機100的軟件“內(nèi)核”。本領(lǐng)域技術(shù)人員可以理解,內(nèi)核是操作系統(tǒng)中用作所有系統(tǒng)操作和資源的主控制器的軟件代碼。內(nèi)核包含操作系統(tǒng)(而不是文件系統(tǒng))的基本功能。內(nèi)核負(fù)責(zé)分配計算機資源。內(nèi)核需要一個文件系統(tǒng)來執(zhí)行文件,定位文件,和執(zhí)行其它文件操作。有很多不同類型的文件,包括數(shù)據(jù)文件和代碼文件。代碼文件的例子是EMACS(一種文本編輯器),和X-WINDOWS(一種用于LINUXOS101的圖形外殼)。雖然本發(fā)明優(yōu)選實施例采用REDHATLINUXOS101,但是如果需要,也可以使用LINUX的其它發(fā)布產(chǎn)品或其它操作系統(tǒng)。LINUX的其它公用發(fā)布的例子包括SLACKWARELINUX,YGGDRASILLINUX和CALDERALINUX。盡管本發(fā)明將與全特性操作系統(tǒng),例如WINDOWS98或WINDOWSNT一道工作,但其最好使用可升級的操作系統(tǒng),例如LINUXOS101或MICROSOFTWINDOWSCE??缮壍牟僮飨到y(tǒng)允許選擇操作系統(tǒng)特性或組件中對于當(dāng)前應(yīng)用必須的一個子集。對操作系統(tǒng)特性或組件的該子集所需的存儲器空間進行控制,因此可以使其最小。在存儲器空間非常有限和昂貴情況下的嵌入式系統(tǒng)的開發(fā)中,特別希望可升級操作系統(tǒng)的上述能力。例如,在本發(fā)明中,具有選定特性組的LINUXOS101僅需要大約2MB來啟動,而WINDOWS98需要超過100MB。此外,因為網(wǎng)絡(luò)流量計算機100最好被設(shè)計用于惡劣環(huán)境,因此使用相對昂貴的存儲部件,例如閃速盤170。因此,希望使用可升級的操作系統(tǒng)(例如LINUXOS101)來使流量計算機中所需的存儲器量最小,并且因此使系統(tǒng)成本最小。仍然參見圖4,在優(yōu)選實施例中,通過利用標(biāo)準(zhǔn)LINUXOS的全特性的一個子集重編譯LINUXOS源代碼,嵌入式LINUXOS101的大小被降低到1到2MB的存儲空間。這是通過運行由REDHATLINUX提供的一個配置公用程序完成的。該公用程序使得能夠選擇標(biāo)準(zhǔn)LINUX安裝中提供的功能中的一個子集。該公用程序在LINUX提供的X-WINDOWS外殼中執(zhí)行。從X-WINDOWS內(nèi)部執(zhí)行命令“makexconfig”以啟動該公用程序。一旦啟動了該公用程序,就選擇附錄A中標(biāo)識的選項。一旦選擇了標(biāo)識的LINUXOS選項,就使用該配置公用程序來重編譯LINUXOS101的源代碼,以產(chǎn)生該OS的一個子集版本,在該子集版本中,OS的大小已經(jīng)被最小化,以節(jié)省網(wǎng)絡(luò)流量計算機100的閃速盤170上的存儲空間。網(wǎng)絡(luò)流量計算機100中軟件的下一個“層”是軟件的NETSERVICE102包。NETSERVICES軟件102是一個或多個系統(tǒng)程序(相對于應(yīng)用程序)的組合,這些系統(tǒng)程序提供各種系統(tǒng)服務(wù)和資源并且與LINUXOS101協(xié)同工作。例如,優(yōu)選實施例使用NETSERVICES,例如FILETRANSFERPROTOCOL(“FTP”),HYPERTEXTTRANSFERPROTOCOL(“HTTP”)和TELNET。但是,本發(fā)明可以使用其它NETSERVICES102。NETSERVICES102程序是現(xiàn)有的公用程序,可以從很多不同的來源獲得。例如,如優(yōu)選實施例中,NETSERVICES102軟件可以從REDHATLINUX發(fā)布的CD-ROM獲得。大多數(shù)現(xiàn)有公用的LINUX發(fā)布通常包括NETSERVICES102軟件。如前所述,其它現(xiàn)有公用LINUX發(fā)布的例子包括SLACKWARELINUX,YGGDRASILLINUX,和CALDERALINUX。NETSERVICES102軟件也可以很容易地從各種因特網(wǎng)站點下載。通過使用普通現(xiàn)有的因特網(wǎng)搜索引擎很容易找到這些因特網(wǎng)站點。仍然參見圖4,優(yōu)選實施例使用FTP網(wǎng)絡(luò)服務(wù)102,在主計算機50和網(wǎng)絡(luò)流量計算機100之間傳送文件。HTTP網(wǎng)絡(luò)服務(wù)102使得網(wǎng)絡(luò)流量計算機100能夠在因特網(wǎng)的萬維網(wǎng)中通信。因此,操作者可以使用因特網(wǎng)瀏覽器(例如微軟的INTERNETEXPLORER或網(wǎng)景的NETSCAPENAVIGATOR)通過主計算機50查看來自網(wǎng)絡(luò)流量計算機100的流量測量結(jié)果。優(yōu)選實施例使用TELNET網(wǎng)絡(luò)服務(wù)102以使得操作者能夠遠程登錄到作為終端的網(wǎng)絡(luò)流量計算機100。這種遠程連接對于網(wǎng)絡(luò)流量計算機100來說,就好象是技術(shù)人員實際來到網(wǎng)絡(luò)流量計算機所處位置,并允許技術(shù)人員直接在網(wǎng)絡(luò)流量計算機上工作。此外,這種連接使得技術(shù)人員能夠從遠端位置對網(wǎng)絡(luò)流量計算機100進行故障檢修。MODBUS軟件103使得網(wǎng)絡(luò)流量計算機100能夠通過RS-232或RS-485串行端口與傳統(tǒng)流量計算機或流量計(例如超聲波測量儀400,氣相色譜儀500,和其它流量計算機600)通信。MODBUS軟件103實現(xiàn)標(biāo)準(zhǔn)MODBUS通信協(xié)議,以與LINUXOS101協(xié)同工作。附錄B中的源代碼是使用C編程語言的MODBUS協(xié)議的實現(xiàn)。APACHEWeb服務(wù)器軟件104使得網(wǎng)絡(luò)流量計算機100能夠作為使用HTTP和FTPNETSERVICES102通信協(xié)議的web服務(wù)器。作為web服務(wù)器,網(wǎng)絡(luò)流量計算機100可以由主計算機50通過因特網(wǎng)340訪問。同樣,網(wǎng)絡(luò)流量計算機100可以由主計算機50通過內(nèi)部網(wǎng)或類似技術(shù)訪問。APACHEWeb服務(wù)器軟件104還可以使得能夠使用COMMONGATEWAYINTERFACE(“CGI”)腳本105,下面將對其討論。APACHEWEB服務(wù)器軟件104是現(xiàn)有公用的web服務(wù)器軟件,并且可以容易地從因特網(wǎng)下載。通過使用普通現(xiàn)有的因特網(wǎng)搜索引擎可以找到用于下載APACHEweb服務(wù)器軟件104的因特網(wǎng)站點。一個用于下載APACHEweb服務(wù)器軟件104的永久因特網(wǎng)站點是www.apache.org。仍然參見圖4,CGI腳本和HTML代碼105,和JAVA小程序和C程序106是應(yīng)用程序,這些應(yīng)用程序使得網(wǎng)絡(luò)流量計算機100能夠作為其全部功能的一部分執(zhí)行各種任務(wù),以與各種外部裝置通信和將計算的流量數(shù)據(jù)結(jié)果提供給通過因特網(wǎng)340連接到網(wǎng)絡(luò)流量計算機的主計算機50。本領(lǐng)域技術(shù)人員可以理解,可以編制各種這樣的程序來使得網(wǎng)絡(luò)流量計算機100能夠執(zhí)行各種功能。例如,附錄C中提供的源代碼使得網(wǎng)絡(luò)流量計算機100能夠每60秒詢問超聲波測量儀400一次,以得到校正的流率。一旦獲得流率,流量計算機100就將該流率附加到名為“ultrasonic.log”的記錄文件。為每個整天產(chǎn)生一個這種文件,并且每24小時重復(fù)該程序。類似地,附錄D是一個例子,其列出了使得流量計算機100能夠從超聲波測量儀400讀取預(yù)定義消息塊的源代碼。這些消息塊包含用于填充表的數(shù)據(jù)。然后在通過因特網(wǎng)340連接到流量計算機100的主計算機50上顯示這些表。上述兩個例子都使用附錄B中列出的MODBUS協(xié)議103程序。當(dāng)主機通過因特網(wǎng)340連接到流量計算機100時,CGI腳本和HTML代碼105使用JAVA小程序來在主計算機50上以圖形格式顯示計算的流量數(shù)據(jù)結(jié)果。JAVA小程序可以從VISUALENGINEERING,INC.的品牌JAVACHART購買。本領(lǐng)域技術(shù)人員可以理解,可以使用JAVA編程獨立地開發(fā)商業(yè)軟件JAVACHART提供的功能。現(xiàn)在參見圖3和5,網(wǎng)絡(luò)流量計算機100的閃速盤170包含圖4中標(biāo)識的軟件文件。當(dāng)網(wǎng)絡(luò)流量計算機100為其特定目的而使用時,執(zhí)行這些程序和數(shù)據(jù)。但是,閃速盤170在正確工作前必須被初始化。類似于普通PC的硬盤上的操作系統(tǒng)和其它軟件和數(shù)據(jù)的初始格式化和安裝,閃速盤170的初始化通常每個單元只執(zhí)行一次。但是,在必要時,可以重復(fù)初始化程序。在初始化之前,閃速盤170或者是未格式化的或者包含必須刪除的文件?,F(xiàn)在參見圖5,如前所述,網(wǎng)絡(luò)流量計算機100包括閃速盤170和RAM130。網(wǎng)絡(luò)流量計算機100還包括BIOS121。閃速盤170包括在閃速盤的主引導(dǎo)記錄(“MBR”)上的LINUXLILO裝載程序171。閃速盤170還包括非壓縮文件空間172,壓縮文件空間173,用戶數(shù)據(jù)區(qū)174和備用空間175。RAM130包括RAM盤131(非壓縮文件空間)。在普通PC中,文件系統(tǒng)通常未被壓縮,并且駐留在PC的硬盤上。PC中的硬盤是相對廉價的存儲介質(zhì)。因此,在普通PC上具有用于一般軟件應(yīng)用程序的非壓縮文件系統(tǒng)是經(jīng)濟上合理的。通常,為了在標(biāo)準(zhǔn)PC配置上運行軟件,將程序動態(tài)地從PC的硬盤裝載到PC的用于執(zhí)行程序的隨機存取存儲器(“RAM”)。標(biāo)準(zhǔn)PC配置中的文件系統(tǒng)保留在硬盤上,程序從/向硬盤上的文件系統(tǒng)進行讀取和寫入。但是,在執(zhí)行期間程序必須駐留在RAM中。程序不能在PC的硬盤上執(zhí)行。本發(fā)明的優(yōu)選實施例不使用硬盤作為一種非易失性永久存儲介質(zhì)形式。這是因為,當(dāng)前的硬盤驅(qū)動技術(shù)通常不能承受流量計算機可能運行時所處的惡劣環(huán)境。本發(fā)明的優(yōu)選實施例代之以使用閃速盤170用于非易失性永久存儲。之所以需要閃速盤,是因為文件必須被存儲在某種永久非易失性存儲介質(zhì)中。非易失性存儲介質(zhì)被斷電時不會丟失存儲于其上的數(shù)據(jù)。閃速盤模擬一個物理磁硬盤。因此,網(wǎng)絡(luò)流量計算機100上運行的軟件不能區(qū)分硬盤和閃速盤。閃速盤使用沒有移動部件的固態(tài)技術(shù)。因此,閃速盤更適于承受諸如沖擊,高溫和低溫等惡劣環(huán)境條件。閃速盤與硬盤成本相比還具有物理尺寸小的附加優(yōu)點。這便利于在配置為嵌入式計算機或處理器的網(wǎng)絡(luò)流量計算機中使用閃速盤。閃速盤與硬盤相比非常昂貴。在具有硬盤的普通PC中,易失性RAM存儲器成本比非易失性硬盤存儲器大約高20到30倍。由于普通PC中的廉價存儲介質(zhì)是硬盤,從成本觀點來看,非壓縮硬盤是一種可以接受的操作模式。在優(yōu)選實施例的網(wǎng)絡(luò)流量計算機100中的情況相反。在網(wǎng)絡(luò)流量計算機100中,非易失性永久閃速盤170存儲介質(zhì)比易失性臨時RAM130存儲器大約貴5倍。由于網(wǎng)絡(luò)流量計算機100的閃速盤170比RAM130更貴,為了使流量計算機的總成本最小,非常希望使用更多的RAM存儲器和更少的閃速盤存儲器。但是,上述期望會受到文件不能在RAM130上永久存儲的技術(shù)限制的制約。因此,為了降低成本,優(yōu)選實施例通過將大多數(shù)文件以壓縮形式存儲在閃速盤上的壓縮文件空間173中來使閃速盤170存儲器最小。當(dāng)網(wǎng)絡(luò)流量計算機100運行時,其將壓縮文件173以非壓縮形式從閃速盤170傳送到RAM130。通過訪問RAM中的壓縮文件空間131而不是通過訪問閃速盤170中的壓縮文件空間173來執(zhí)行流量計算機100上的軟件?,F(xiàn)在參見圖4和5,當(dāng)完成閃速盤170的初始化時,閃速盤除了其它可能的數(shù)據(jù)和程序文件以外至少還包含圖4中標(biāo)識的某些軟件文件。更具體地說,LINUXLILO裝載程序171從零扇區(qū)開始駐留在閃速盤170的MBR上。在緊隨MBR171的存儲器空間和扇區(qū)430之間,駐留非壓縮文件空間172。非壓縮文件空間172包含非壓縮文件系統(tǒng),LINUXOS101內(nèi)核和其它文件。在緊隨扇區(qū)430的空間中,駐留壓縮文件空間173。壓縮文件空間173包含圖4中標(biāo)識的沒有裝載到非壓縮文件空間172中的軟件和文件。用戶數(shù)據(jù)區(qū)174最好包含流量計算機100使用的、在流量計算機使用期間可能變化的數(shù)據(jù)文件。根據(jù)閃速盤170的尺寸,閃速盤的一部分可能是備用空間175。閃速盤170初始化例程的細節(jié)將在后面描述。閃速盤170的用戶數(shù)據(jù)區(qū)174包含在網(wǎng)絡(luò)流量計算機使用期間可能變化的數(shù)據(jù)文件。這種用戶數(shù)據(jù)文件的例子包括用于存儲關(guān)于流量計算機的配置信息的文件。例如,當(dāng)主計算機50連接到網(wǎng)絡(luò)流量計算機100并將流量測量的頻度從每4小時改變?yōu)槊?小時時,對配置文件進行修改。為了永久保存對用戶數(shù)據(jù)文件的修改,將這種文件存儲在閃速盤170上的用戶數(shù)據(jù)區(qū)174中,并且文件的任何變化被同時記錄在閃速盤上而不是RAM130中。根據(jù)各種考慮,例如性能需要、可用的閃速盤空間和其它因素,可用壓縮或不壓縮用戶數(shù)據(jù)區(qū)174。LILO裝載程序171和非壓縮文件空間172所需的閃速盤170存儲空間通過預(yù)編譯LINUXOS101內(nèi)核確定。在優(yōu)選實施例中,在閃速盤170上需要430個扇區(qū)存儲LILO裝載程序171和非壓縮文件空間172。如前所述,LINUXOS101和內(nèi)核的大小可以根據(jù)從標(biāo)準(zhǔn)LINUXOS選擇的全特性的特定子集而變化。此外,該大小也可能受到對LINUXOS101內(nèi)核的任何定制變化的影響。仍然參見圖5,將LINUXOS101內(nèi)核裝載到非壓縮文件空間172中。將內(nèi)核的一個小段以非壓縮形式存儲在非壓縮文件空間172中。將大部分內(nèi)核以壓縮形式存儲在非壓縮文件空間172中。當(dāng)網(wǎng)絡(luò)流量計算機100被加電或重新引導(dǎo)時,首先執(zhí)行非壓縮文件空間172中的非壓縮內(nèi)核段。一旦開始執(zhí)行非壓縮內(nèi)核,內(nèi)核就按需要解壓縮和執(zhí)行非壓縮文件空間172中的其它壓縮內(nèi)核段。在優(yōu)選實施例中,通過創(chuàng)建一個RAM盤在RAM中得到非壓縮文件空間131。RAM盤是在RAM中創(chuàng)建一個“硬盤”或“閃速盤”以模擬硬盤或閃速盤功能的方法。因此,RAM盤131可以存儲文件系統(tǒng),并且可以象常規(guī)PC硬盤或閃速盤一樣向RAM盤寫入文件和從RAM盤訪問文件。從網(wǎng)絡(luò)流量計算機100上運行的軟件(圖4)的觀點來看,對駐留在RAM盤131上的文件系統(tǒng)和駐留在閃速盤170上的文件系統(tǒng)是可以區(qū)分的。只有LINUXOS101內(nèi)核可以區(qū)分RAM盤131和硬盤。創(chuàng)建RAM盤的能力是LINUXOS101內(nèi)核的固有性質(zhì)。雖然從節(jié)省成本觀點來看,希望創(chuàng)建和使用壓縮文件空間173和RAM盤131,但是本發(fā)明不一定需要在網(wǎng)絡(luò)流量計算機100中使用壓縮文件空間和RAM盤。對壓縮文件空間173和RAM盤131的需要是一個成本效率因素。本發(fā)明預(yù)期使用僅具有非壓縮文件空間172的閃速盤170。同理,本發(fā)明將預(yù)期使用不具有RAM盤131的RAM130。如果未來的閃速盤170的成本變得小于RAM130的成本,那么就沒有必要使用壓縮文件空間173和RAM盤131,并且有關(guān)的成本節(jié)省就成為非考慮因素。在網(wǎng)絡(luò)流量計算機100加電或復(fù)位時,BIOS121控制流量計算機。BIOS121是一個安裝在流量計算機100主板上的集成電路芯片。利用在流量計算機初始加電或復(fù)位時引導(dǎo)(即控制)流量計算機的邏輯對BIOS121預(yù)編程。當(dāng)BIOS121開始引導(dǎo)進程時,其搜索被連接為第一驅(qū)動器或“hda”(LINUXOS術(shù)語)的硬盤或閃速盤。然后,BIOS121搜索“hda”上的MBR。由于硬盤被初始安裝為“hda”,BIOS定位硬盤的MBR。安裝在硬盤的MBR上的LINUXOS引導(dǎo)裝載程序在閃速盤170的初始化期間引導(dǎo)網(wǎng)絡(luò)流量計算機100。仍然參見圖5,LILO裝載程序171必須定位在閃速盤170的MBR上,因為BIOS121將從這里搜索來啟動網(wǎng)絡(luò)流量計算機100的引導(dǎo)序列。在BIOS121找到并開始執(zhí)行LILO裝載程序171后,LILO裝載程序在非壓縮文件空間172中搜索和尋找LINUXOS101內(nèi)核。一旦LINUXOS101內(nèi)核被找到,LILO裝載程序171將LINUXOS內(nèi)核裝載到RAM130中,并開始執(zhí)行內(nèi)核。此時,LINUXOS101內(nèi)核控制網(wǎng)絡(luò)流量計算機100的引導(dǎo)序列。LINUXOS101內(nèi)核可以被物理地存儲在閃速盤170上的任何位置。但是,為了使LILO裝載程序171能找到內(nèi)核,必須將關(guān)于內(nèi)核的物理位置專門通知給裝載程序,或者裝載程序必須在缺省的物理位置找到內(nèi)核。內(nèi)核的缺省物理位置是在閃速盤170上緊隨LILO裝載程序占據(jù)的存儲空間開始的存儲空間。在優(yōu)選實施例中,LINUXOS101內(nèi)核物理地位于閃速盤170上非壓縮文件空間172的開始。這是LINUXOS101內(nèi)核的缺省位置。LINUXOS101內(nèi)核具有引導(dǎo)網(wǎng)絡(luò)流量計算機100的首要責(zé)任。為了正確執(zhí)行引導(dǎo)序列,內(nèi)核確定文件系統(tǒng)的位置,是否壓縮文件系統(tǒng),和是否創(chuàng)建RAM盤。如果創(chuàng)建RAM盤,內(nèi)核確定RAM盤的大小和是否將文件系統(tǒng)從閃速盤裝載到RAM盤中。內(nèi)核根據(jù)從LILO裝載程序171傳遞到LINUXOS101內(nèi)核的命令行參數(shù)進行上述決定。如前所述,通常文件系統(tǒng)駐留在硬盤或閃速盤上,并且程序從/向硬盤或閃速盤訪問/寫入文件。當(dāng)建立RAM盤并將文件系統(tǒng)從閃速盤傳送到RAM盤時,網(wǎng)絡(luò)流量計算機100上運行的程序從/向RAM盤(而不是閃速盤)訪問/寫入文件。在優(yōu)選實施例中,從扇區(qū)430開始在閃速盤170上存儲壓縮文件空間173。該空間是閃速盤170中緊隨非壓縮文件空間172的存儲空間。仍然參見圖5,下面根據(jù)優(yōu)選實施例對閃速盤170的初始化進行說明。其它的初始化序列也是合適的,下面的討論僅是優(yōu)選的初始化。作為優(yōu)選初始化進程的先決條件,網(wǎng)絡(luò)流量計算機100必須具有被安裝為其第一驅(qū)動器“hda”的常規(guī)硬盤。閃速盤170必須被初始安裝在網(wǎng)絡(luò)流量計算機100中作為其第二驅(qū)動器“hdc”(可以使用“hdb”代替)。而且,硬盤“hda”必須安裝有LINUXOS。這可以利用稱為REDHATLINUX的可購買或公用的現(xiàn)有軟件包實現(xiàn),REDHATLINUX提供了關(guān)于如何使用由REDHAT提供的CD-ROM盤將LINUXOS安裝到硬盤上的詳細指示。此外,必須把最終將駐留在閃速盤170的壓縮文件空間173和用戶數(shù)據(jù)區(qū)174中的所有文件和相關(guān)目錄結(jié)構(gòu)放置在網(wǎng)絡(luò)流量計算機100的本地硬盤“hda”上的一個臨時目錄中。在優(yōu)選實施例中,附錄E中列出的三個程序腳本“makeLILObootdisk”,“makeCompressedRamDisk”和“bdlilo.conf”用于實現(xiàn)閃速盤170初始化進程。本領(lǐng)域技術(shù)人員可以理解,可以以許多不同變型修改或編制在這三個程序中實現(xiàn)的初始化進程,而實現(xiàn)相同的目的?!癿akeLILObootdisk”和“makeCompressedRamDisk”程序(附錄E)創(chuàng)建RAM盤131和RAM盤內(nèi)的非壓縮文件系統(tǒng)。然后,這些程序?qū)AM盤131中的文件空間的壓縮版本復(fù)制到連接為“hda”的硬盤上的臨時存儲器。程序接著在閃速盤170“hdc”上創(chuàng)建非壓縮文件空間172,并將LINUXOS101的非壓縮和壓縮段和其它文件復(fù)制到非壓縮文件空間172。然后,程序?qū)⒁龑?dǎo)裝載程序文件“boot.b”從硬盤“hda”的引導(dǎo)目錄復(fù)制到閃速盤170“hdc”的主引導(dǎo)記錄171中的引導(dǎo)目錄。然后,將引導(dǎo)裝載程序配置文件“bdlilo.conf”復(fù)制到閃速盤170。接著,必須適當(dāng)?shù)貙⒋鎯υ谟脖P“hda”上的臨時存儲器中的程序和數(shù)據(jù)文件復(fù)制到閃速盤170“hdc”的壓縮文件空間173和用戶數(shù)據(jù)區(qū)174中。也可以將其它文件(例如操作系統(tǒng)文件)復(fù)制到壓縮文件空間173中。在閃速盤170初始化程序“makeLILObootdisk”和“makeCompressedRamDisk”已經(jīng)成功完成后,執(zhí)行LILO引導(dǎo)裝載程序配置程序“bdlilo.conf”(附錄E)。LILO引導(dǎo)裝載程序的程序?qū)⒚钚袇?shù)傳遞到非壓縮文件空間172中的LINUXOS101內(nèi)核。這些參數(shù)告知內(nèi)核網(wǎng)絡(luò)流量計算機100將使用RAM盤131,RAM盤的大小,和閃速盤170上壓縮文件空間173的位置。此外,引導(dǎo)裝載程序的程序還確定在網(wǎng)絡(luò)流量計算機100的引導(dǎo)序列期間使用的特定內(nèi)核映象。在優(yōu)選實施例中,用于引導(dǎo)序列的內(nèi)核映象位于文件“vmlinuz.embedded”中。LILO引導(dǎo)裝載程序配置程序“bdlilo.conf”僅向第一驅(qū)動器“hda”寫入。但是,如上所述,在閃速盤170的初始化期間,網(wǎng)絡(luò)流量計算機100中的第一驅(qū)動器是本地硬盤“hda”,并且閃速盤被連接為第二驅(qū)動器“hdc”。如果在初始化例程期間LILO引導(dǎo)裝載程序的程序被允許向“hda”寫入,那么該程序?qū)⑵茐谋镜赜脖P“hda”上駐留的LINUXOS。因此,一旦已經(jīng)成功完成了初始化程序“makeLILObootdisk”和“makeCompressedRamDisk”,必須將硬盤與網(wǎng)絡(luò)流量計算機100斷開,并且必須將閃速盤170連接為第一驅(qū)動器“hda”。但是,此時閃速盤170的初始化還未完成,并且閃速盤被連接為“hda”,流量計算機100無法使用閃速盤進行引導(dǎo)。其解決方法是創(chuàng)建一個可引導(dǎo)LINUXOS的軟盤。這可以通過使用可購買的或公用的REDHATLINUXOSCD-ROM發(fā)布盤來實現(xiàn)。將可引導(dǎo)軟盤置于網(wǎng)絡(luò)流量計算機100的軟盤驅(qū)動器160中,就可以利用連接到流量計算機作為第一驅(qū)動器“hda”的閃速盤170來引導(dǎo)流量計算機。這種配置在閃速盤初始化例程的LILO配置期間允許閃速盤170被連接為流量計算機100上的第一驅(qū)動器“hda”。因此,當(dāng)執(zhí)行LILO裝載程序的程序時,該程序向連接閃速盤170的“hda”寫入。因此,實現(xiàn)了閃速盤的希望配置結(jié)果。一旦完成LILO裝載程序配置,就完成閃速盤170初始化例程,并從軟盤驅(qū)動器160取出可引導(dǎo)軟盤。現(xiàn)在,網(wǎng)絡(luò)流量計算機100成為就緒狀態(tài)。當(dāng)重新引導(dǎo)網(wǎng)絡(luò)流量計算機100時,利用連接為第一驅(qū)動器“hda”的閃速盤170引導(dǎo)流量計算機。圖6中以流程圖形式顯示上述初始化例程。本領(lǐng)域技術(shù)人員可以理解,可以以不同于此處所述的形式執(zhí)行上述初始化例程,而不偏離初始化例程的目的。本發(fā)明的上述公開和描述是示意性和解釋性的,可以在不偏離本發(fā)明精神的情況下,對大小、形狀、材料、部件、電路元件、布線連接和觸點以及所示電路、結(jié)構(gòu)和操作方法中的細節(jié)進行各種改變。本領(lǐng)域技術(shù)人員在充分理解上述公開后,很容易進行多種變型和改進。所附權(quán)利要求應(yīng)涵蓋所有這些變型和改進。附錄A在“makexconfig”配置實用程序中選擇的LINUXOS選項1.在“代碼多數(shù)級別”選項中,為以下選項選擇“是”a.“提示開發(fā)和/或不完整代碼驅(qū)動程序”。2.在“可裝載模塊支持”選項中,為以下選項選擇“是”a.“使能可裝載模塊支持”;b.“設(shè)置關(guān)于模塊的所有符號的版本信息”;和c.“內(nèi)核daemon支持”。3.在“通用設(shè)置”選項中,為以下選項選擇“是”a.“內(nèi)核數(shù)學(xué)仿真”;b.“聯(lián)網(wǎng)支持”;(該選項使能TCP/IP,一種聯(lián)網(wǎng)通信協(xié)議);c.“PC總線”;d.“PCIBIOS支持”;e.“系統(tǒng)5IPC”;f.“用于A.OUT二元的內(nèi)核支持”;g.“用于F二元的內(nèi)核支持”;h.“用于JAVA二元的內(nèi)核支持”和i.“如果你的GCC是ELF-GCC,將內(nèi)核編譯為ELF”。4.響應(yīng)于“處理器類型”,選擇“486”。該選項指定x86系列微處理器作為網(wǎng)絡(luò)流量計算機100運行的平臺。5.在“軟盤ID和其它塊裝置”選項中,為以下選項選擇“是”a.“通常軟盤支持”;b.“增強IDEMFM和RLL盤CDROM帶式軟盤支持”;c.“包括IDEATAPICDROM支持”;d.“包括IDEATAPI軟盤支持”;e.“CMD640芯片組支持”;f.“CMD640增強支持”;g.“RZ1000芯片組錯誤修復(fù)支持”;h.“Intel82371PUXTriton12DMA支持”;i.“回送裝置支持”;j.“多裝置驅(qū)動程序支持”;k.“可裝載模塊線性模式支持”;l.“RAM盤支持”;和m.“初始RAM盤INITRD支持”;6.在“聯(lián)網(wǎng)”選項中,為以下選項選擇“是”a.“TCPIP聯(lián)網(wǎng)”;b.“IPDropSourceRocketFrames”c.“網(wǎng)絡(luò)裝置支持”(該選項使能以太網(wǎng)LAN接口卡的使用);d.“模塊啞元網(wǎng)絡(luò)驅(qū)動程序支持”;e.“作為一個模塊的EQL串行線路裝載平衡支持”;f.“PPP支持”;g.“以太網(wǎng)10/100兆位”;h.“3-ComISA/EISA/PCI卡”;i.“3C509,3C579支持”(該選項是根據(jù)所使用的以太網(wǎng)LAN接口卡的類型選擇的);j.“3C590,3C900系列VotrexBoomerang支持”;和k.“PCI以太網(wǎng)適配器”。7.在“聯(lián)網(wǎng)”選項中,為以下選項選擇“否”a.“SCSI支持”(在不選擇“SCSI支持”時,其它與SCSI支持有關(guān)的選項被自動禁止);和b.“ISDN支持”。8.在“CDROM驅(qū)動器”選項中,為以下選項選擇“是”a.“非SCSIIDEATAPICDROM驅(qū)動器”;和b.“可軟配置的CDROM接口卡支持”。9.在“文件系統(tǒng)”選項中,為以下選項選擇“是”a.“作為一個模塊的模塊Minix文件系統(tǒng)”;b.“作為一個模塊的擴展FS支持”;c.“第二擴展文件支持”;和d.“本機語言支持統(tǒng)一編碼標(biāo)準(zhǔn)碼頁”。10.在“字符裝置”選項中,為以下選項選擇“是”a.“標(biāo)準(zhǔn)通用串行支持”;b.“Stallion多串行支持”;c.“并行打印機支持”;d.“模塊108+卡支持”;和e.“PS/2鼠標(biāo)支持”11.在“字符裝置”選項中,為以下選項選擇“否”a.“聲音支持”;和b.“內(nèi)核非法修改”。附錄B<prelisting-type="program-listing"><![CDATA[//Startof“asciiModbus.cc”ProgramCode//ASCIIModbusprotocolinterfaceroutines//J.D.A.LambertMay5,1996//DanielIndustries//#include<stdio.h>#include<unistd.h>#include<fcntl.h>#include<errno.h>#include<termios.h>#include<sys/file.h>#ifdefDEBUG#include<string.b>#endif#ifdefTIME_DEBUG#include<sys/time.h>#endif#include″asciiModbus.h″//Localdefinitions#defineONESECOND10//Onesecondin100mSincrements//LocalfunctionprototypesstaticintgetInput(intfd.intbuflen,char*buf,intwait);staticintsendModbusMessage(intfd,ucharaddr,ucharfunct,modReg*data,intnRegs);staticintreadModbusMessage(intfd,modReg*data,intmaxRegs,intmaxTime);staticucharhexToNibble(charhex);#ifdefTIME_DEBUG//LocaldebugdatastaticstructitimervalturnRoundTime;staticintfirst;//Flagtoshowfirstturnroundtime#endif#ifdefREGRESSION//Asimpleregressiontestintmain(intargc,char**argv){intfd;modRegrxBuf[256];modRegdataBuf[]={{{(ushort)9001}}, {{(ushort)50}}};if(argo?。?){//Makesuredeviceisspecifiedfprintf(stderr,″Serialdevicenameisrequiredasaparameter\n″);exit(1);}if((fd=setupSerial(argv[1]))<0){//Openthedevicefprintf(stderr″%s%s\n″,argv[1],sys_errlist[errno]);exit(1);}while(1){intnchars;nchars=sendAndReceiveAscii(fd,1,3, dataBuf,DIM(dataBuf),rxBuf,sizeof(rxBuf));if(nchars>=0){fprintf(stderr,″sendAndReceiveAsciitimedout\n″);}}close(fd);//Closedeviceifweevergethere}#enditintsendAndReceiveAscii(intfd, ucharaddr, ucharfunct, modReg*txData,intnRegs, modReg*rxData,intmaxRegs){if(flock(fd,LOCK_EX)<0){//Thisprocessmusthaveexclusiveusefprintf(stderr,″flockfailed%s\n″,sys_errlist[errno]);exit(1);}if(sendModbusMessage(fd,addr,funct,txData,nRegs)<0){//Attempttosendfprintf(stderr,″sendModbusMessagefailed%s\n″,sys_errlist[errno]);exit(1);}#ifdefTIME_DEBUGturnRoundTime.it_interval.tv_sec=100;//100secondintervalturnRoundTime.it_interval.tv_usee=0;turnRoundTime.it_value.tv_sec=100;//andinitialtimeturnRoundTime.it_value.tv_usec=0;setitimer(ITIMER_REAL,&turnRoundTime,NULL);firs=1;//Setflagforreportingturnaroundtime#endifintnread=readModbusMessage(fd,rxData,maxRegs,ONESECOND);//Trytogetreplyflock(fd,LOCK_UN);//Letothersusethisdeviceusleep(10);//Otherscannotgetinwithoutthisreturnnread;//Tellcallerwhathappened}staticintgetInput(intfd,intbuflen,char*buf,intwait){intnchars=0;while((nchars<=0)&&(wait-->=0)){nchars=read(fd,buf,buflen);//Attempttoreadif(nchars>0){//Only+veresultsaremeaningful#ifdefTIME_DEBUGif(first){//Onlyreportthefirstsuccessfulread first=0;//Makesureothersarenotreported getitimer(ITIMER_REAL,&turnRoundTime); doubleelapsed=(100.0- ((double)turnRoundTime.it_value.tv_sec+ ((double)turnRoundTime.it_value.tv_usec /(double)1000000.0))); printf(″Turnaroundtimeis%7.3fmilliseconds\n″, elapsed*1000); }#endif#ifdefDEBUG printf(″%dcharactersread\n″,nchars); for(inti=0;i<nchars;i++){ printf(″%02X,″,buf[i]&0xff); } printf(″\n″);#endif}else{if(errno?。紼AGAIN){//Error″tryagain″isnotreallyanerror fprintf(stderr,″Fatalerrorduringread%s\n″, sys_errlist[errno]); exit(1);//Treatallerrorsasfatalfornow}usleep(100000);//Justnothingforus,wait100mS}}returnnchars;}intsetupSerial(constchar*dev){structtermiostios;intfd=open(dev,O_RDWR|O_NDELAY);if(fd<0){fprintf(stderr,″%s%s\n″,dev,sys_errlist[errno]);exit(1);}if(tcgetattr(fd,&tios)<0){fprintf(stderr,″Couldnotgetterminalattributes%s″,sys_errlist[errno]);exit(1);}tios.c_cflag=CS7|//Sevendatabits //Implicitlynoparity,onestopbitCREAD|//EnableReceiverHUPCL|//HangupaftercloseCLOCAL|//IgnoremodemcontrollinesPARENB;//Enableparity(evenbydefault)tios.c_iflag=IGNBRK|INPCK;//Ignorebreakcheckinputparityerrorstios.c_oflag=0;tios.c_lflag=0;for(inti=0;i<NCCS;i++){tios.c_cc[i]=′\0′;//nospecialcharacters}tios.c_cc[VMIN]=1;tios.c_cc[VTIME]=0;cfsetospeed(&tios,B9600);cfsetispeed(&tios,B9600);if(tcsetattr(fd,TCSAFLUSH,&tios)<0){fprintf(stderr,″Couldnotsetattributes,%s″,sys_errlist[errno]);exit(1);}returnfd;}////SendaModbusmessagecontainedinmsg,oflengthlen,todevicefd;//intsendModbusMessage(intfd,ucharaddr,ucharfunct,modReg*msg,intnRegs){uintlrc=0;//lrccheckchartxBuffer[512];//Temporarytransmitbuffer#ifdefDEBUGbzero(txBuffer,sizeof(txBuffer));//Cleararrayforeasydebug#endiftxBuffer=′′;//Packageheadersprintf(&txBuffer[1],″%02X%02X″,addr,funct);lrc+=addr;lrc+=funct;for(inti=0;i<nRegs;i++){//Copythemessagesprintf(&txBuffer[5+(i*4)],//tothetransmitbuffer ″%02X%02X″, msg[i].parts.msb,msg[i].parts.lsb);//Convertingittohexadecimallrc+=msg[i]parts.msb;//Accountthelrclrc+=msg[i].parts.lsb;}inttxByteLen=5+(nRegs*4);//Colon(1)+addr(2)+funct(2)+(nRegs*4)lrc=~lrc+1;//Twoscomplementlrc&=0xFF;//Maskoffoverflowbitssprintf(&txBuffer[txByteLen],//andputitintothetransmitter ″%02x\r\n″,lrc);//togetherwiththeCRLFintnchars=write(fd,txBuffer,txByteLen+4);//Transmitthelot#ifdefDEBUGprintf(″%dcharacterswritten\n″,nchars);txBuffer[nchars]=′\0′printf(″%s″,txBuffer);for(inti=0;i<nchars;i++){printf(″%02X,″,txBuffer[i]&0xff);}prntf(″\n″);#endifreturnnchars;}////Readamodbusmessage//staticintreadModbusMessage(intfd,modReg*data,intmaxRegs,intmaxtime){uintlrc=0;//LrcaccumulatorintendPos=0;//FlagtomarkpositionofendnewlineihttotChars=0;//TotalcharactersreceivedcharrxBuf[512];//RawreceivebuffercharbyteBuf[256];//Bufferforbytesinmessagebody#ifdefDEBUGbzero(rxBuf,sizeof(rxBuf));bzero(byteBuf,sizeof(byteBuf));#endifwhile((maxtime-->0)&& (endPos==0)){//Keeptryingtogetdataevery100mSintnchars=getInput(fd, sizeof(rxBuf)-totChars, rxBuf+totChars,1);if(nchars>0){//OnlydealwithrealdatatotChars+=nchars;//Adjustcount}for(inti=0;i<totChars;i++){if(rxBuf[i]=′\n′){ endPos=i; break;//Noneedtogofarther}}}if((endPos?。?)&&//Ifwehavecharacters(rxBuf=′′)&&//Startcolon(rxBuf[endPos-1]=′\r′)&&//andCarriage-return(rxBuf[endPos]=′\n′)//andNewlineallincorrectplaces){//WehaveacorrectlyterminatedbufferintbyteCount=0;//Numberofbytesinmessagefor(inti=1;i<endPos-2;i+=2){//Donotprocess′′,′\r′,or′\n′byteCount++;lrc+=byteBuf[(i-1)/2]=hexToNibble(rxBuf[i])*16+ hexToNibble(rxBuf[i+1]);//Converthexnibblestobinarybytes}if(lrc&0xFF)=0){//IfwehaveagoodlrcintnRegs=0;//Numberofregisterspopulatedfor(inti=3;i<byteCount;i+=2){//Getmodbusregistersskipping //address,functioncode,andbytecount data->parts.msb=byteBuf[i]; data->parts.lsb=byteBuf[i+1]; data++;//Nextregister if(nRegs++>=maxRegs){//Tallyregistersandiftoomany.. break;//quit }}if(-nRegs<=maxRegs){ returnnRegs;//It’sagoodmessage }}}return-1;//Abummerbydefault}////Convertahexcharacterintoanunsignedcharacternibble//staticunsignedcharhexToNibble(charhex){if((hex>=′A′)&&(hex<=′F′)){returnhex-′A′+10;}elseif((hex>=′0′)&&(hex<=′9′)){returnhex-′0′;}else{fprintf(stderr,″Badhexnibble%c\n″,hex);exit(1);}}//Endof“asciiModbus.cc”ProgramCode//Startof“convertModbus.cc”ProgramCode//////FileconvertModbus.cc//AuthorDavidLambert//DateJune30,1988////Variousfunctionstoconvertmodbusregisterstoandfromnativetypes.//#include″convertModbus.h″//PutaShortstoamodbusregistermvoidputShort(shorts,modReg*m){m->value=s;}//GetashortfromamodbusstreammshortgetShort(modReg*m){returnm->value;}//PutafloatftoamodbusstreammvoidputFloat(floatf,modReg*m){union{struct{modReghi,lo;}c;//componentsfloatf;}u;u.f=f;//Loaduptheunionm.value=u.c.lo.value;//Signandexponentm[1].value=u.c.hi.value;//mantissa}//ReturnafloatfromthemodbusstreammfloatgetFloat(modReg*m){union{struct{modReghi,lo;}c;//componentsfloatf;}u;u.c.lo.value=m.value;//Signandexponentu.c.hi.value=m[1].value;//Restofmantissareturn(u.f);}//Endof“convertModbus.cc”ProgramCode//Startof“asciiModbus.h”ProgramCode/*FileasciiModbus.h*/#ifndefASCIIMODBUS_H#defineASCIIMODBUS_H#defineDIM(x)(sizeof(x)/sizeof(x))typedefunsignedintuint;typedefunsignedshortushort;typedefunsignedcharuchar;typedefunion{//Modbusregisterunionushortvalue;//Thevalueasseenbythismachinestruct{ucharlsb;ucharmsb;}parts;//Individualparts}modReg;//ModbusregisterintsetupSerial(constchar*dev);//OpensandsetsupdeviceintsendAndReceiveAscii(intfd,//Filedescriptorofserialchannel ucharaddr,//Modbusaddress ucharfunct,//Modbusfunctioncode modReg*tx,//Modbusregisterarraytotransmit intnRegs,//Numberofregistersintxarray modReg*rx,//Repositoryforreceivedregisters intmaxRegs);//Maximumnumberofrxregisters#endif//Endof“asciiModbus.h”ProgramCode//Startof“convertModbus.h”ProgramCode#ifndefCONVERTMODBUS_H#defineCONVERTMODBUS_H//////FileconvertModbus.h//AuthorDavidLambert//DateJune30,1988////Variousfunctionstoconvertmodbusregisterstoandfromnativetypes.//#include″asciiModbus.h″//PutaShortstoamodbusregistermvoidputShort(shofts,modReg*m);//GetashortfromamodbusstreammshortgetShort(modReg*m);//PutafloatftoamodbusstreammvoidputFloat(floatf,modReg*m);//ReturnafloatfromthemodbusstreammfloatgetFloat(modReg*m);#endif//Endof“convertModbus.h”ProgramCode]]></pre>附錄C<prelisting-type="program-listing"><![CDATA[//Startof“Makefile.2”ProgramCodeCC=g++allflowLogflowLog.oflowLog.cc../asciiModbus.h../modData.hMakefile $(CC)-c-DDEBUG-Wall-gflowLog.ccflowLog../asciiModbus.o../convertModbus.oflowLog.oMakefile $(CC)../asciiModbus.o../convertModbus.oflowLog.o-oflowLog//Endof“Makefile.2”ProgramCode//Startof“flowLog.cc”ProgramCode//Ultrasonicflowlogacquisitionmodule//D.Lambert//DanielIndustries//June8,1998#include<stdio.h>#include<errno.h>#include<unistd.h>#include<time.h>#include″../modData.h″#include″./convertModbus.h″#include″../asciiModbus.h″//Staticfunctionprototypes//Localdefinitions#defineREADREGS3//Readmultipleregistersfunctioncode#defineNTXREGS2//Numberofregisterstotransmitintmain(intargc,char**argv){intlogRate=60;//Defaulttooneminuteloggingrateintfd;intaddress;modRegrxBuf[256];modRegtxData[2];//Transmitdatabufferif(argc<2){//Makesuredeviceisspecifiedfprintf(stderr,″Serialdevicenameisrequiredasparameter1\n″);exit(1);}if(argc<3){fprintf(stderr,″ModbusIDformeterisrequiredasparameter2\n″);exit(1);}sscanf(argv[2],%ud″,&address);if(address>64){fprintf(stderr,″Address%disoutofrange\n,address);exit(1);}if((fd=setupSerial(argv[1]))<0){//Openthedevicefprintf(stderr,″Failedtoopen%s%s\n″,argv[1],sys_errlist[errno]);exit(1);}if(argc<4){fprintf(stderr,″Logfilenameisrequiredasparameter3″);exit(1);}if(argc>4){//Wehavealoggingratesscanf(argv[4],″%d″,&logRate);}FILE*logFile=NULL;//LoggingfileIDtxData.value=392;//StartRegistertxData[1].value=2;//Numberofregisterswhile(TRUE){//ForeverintnRegsRx=sendAndReceiveAscii(fd,address, READREGS, txData,NTXREGS, rxBuf,sizeof(rxBuf));if(nRegsRx<=0){fprintf(stderr,″CommunicationFailure-%s\n″,sys_errlist[errno]);}else{//Wehavegooddata,processit!staticintlastHour=-1;time_ttimeNow=time(NULL);structtm*tmNow=localtime(&timeNow);if((tmNow->tm_hour=0)&&(lastHour?。?)){//Daychange remove(argv[3]);//Fornowjustloosepreviousdata logFile=NULL;}lastHour=tmNow->tm_hour;//Rememberhourif(logFile=NULL){//Weneedtotryandopenthelogfile if((logFile=fopen(argv[3],″a+″))=NULL){ fprintf(stderr,″Failedtoopenlogfile%s\n″,sys_errlist[errno]); exit(1);}}chardateTimeString[256];//Dateandtimestringstrftime(dateTimeString,sizeof(dateTimeString),″%H%M%S%m/%d/%y″, tmNow);modReg*mrp=rxBuf;//Pointertorxmodbusregisters(only1!)fprintf(logFile,″%s,%f\n″,//Printdateandflowrate dateTimeString,getFloat(mrp));fclose(logFile);//Closeitand...logFile=NULL;//tryagainlater}sleep(logRate);//Waitaminutetillnextlog}fflush(NULL);//Flushallstreamsclose(fd);//Closedevice}//Endof“flowLog.cc”ProgramCode]]></pre>附錄D<prelisting-type="program-listing"><![CDATA[//Startof“ultrasonic.cc”ProgramCode//Ultrasonicacquisitionmodule//D.Lambert//DanielIndustries//June8,1998#include<stdio.h>#include<errno.h>#include<unistd.h>#include″modData.h″#include″convertModbtus.h″#include″asciiModbus.h″#include″ultrasonicMessageBlocks.h″//Staticfunctionprototypes//Localdefinitions#defineREADREGS3//Readmultipleregistersfunctioncodeintmain(intargc,char**argv){intfd;uintmbno;//Messageblocknumberintaddress;messageBlock*mb;modRegrxBuf[256];modRegtxData[2];//Transmitdatabufferif(argc<2){//Makesuredeviceisspecifiedfprintf(stderr,″Serialdevicenameisrequiredasparameter1\n″);}if(argc<3){fprintf(stderr,″ModbusIDformeterisrequiredasparameter2\n″);}if(argc<4){fprintf(stderr,″Messageblocknumberisrequiredasparameter3\n″);exit(1);}sscanf(argv[2],″%ud″&address);if(address>64){fprintf(stderr,″Address%disoutofrange\n″,address);exit(1);}sscanf(argv[3],″%ud″,&mbno);if(mbno>=nMessageBlocks){fprintf(stderr,″Messageblocknumber%disoutofrange\n″,mbno);exit(1);}if((mb=messageBlocks[mbno])=NULL){fprintf(stderr,″Messageblocknumber%disnotyetimplemented\n″,mbno);exit(1);}if((fd=setupSerial(argv[1]))<0){//Openthedevicefprintf(stderr″%s%s\n″,argv[1],sys_errlist[errno]);exit(1);}txData.value=mb->points.reg;//StartRegistertxData[1].value=registersInMessageBlock(mb);//NumberofregistersintnRegsRx=sendAndReceiveAscii(fd,address,READREGS, txData,2, rxBuf,sizeof(rxBuf));if(nRegsRx<=0){fprintf(stderr,″CommunicationFailure-%s\n″,sys_errlist[errno]);printf(″CommunicationFailure-%s\n″,sys_errlist[errno]);}else{//Wehavegooddata,processit!modReg*mrp=rxBuf;//Pointertorxmodbusregistersfor(inti=0;i<nRegsRx;i++){modData*mdp=&mb->points[i];//Pointertomodbusdatadescriptorsif(mdp->type=′F′){//Processfloats if(mdp->display){ printf(″<tr><td>%8s<td>%f<td>%s</tr>\n″,mdp->name,getFloat(mrp),mdp->units); } mrp+=2;//Afloatistwomodbusregisters}elseif(mdp->type=′I′){//Processints if(mdp->display){ printf(″<tr><td>%8s<td>%hd<td>%s</tr>\n″,mdp->name,getShort(mrp),mdp->units); } mrp++;//Ashortintegerisonemodbusregister}}}fflush(NULL);//Flushallstreamsclose(fd);//Closedevice}//Endof“ultrasonic.cc”ProgramCode//Startof“ultrasonicMessageBlocks.cc”ProgramCode////FileultrasonicMessageBlocks.cc//AuthorD.Lambert//DateJuly2,1998////Definesmessageblocksas//implementedintheultrasonicmeter.//#include<unistd.h>#include<stdio.h>#include″ultrasonicMessageBlocks.h″//MessageBlockDefinitionsstaticmessageBlockmessageBloek1={//MessageBlockDefinitions{{1,″Spare″,″″,′I′,NO},{2,″Parity″,″″,′I′,YES},{3,″BaudRate,″Bits/sec″,′I′,YES},{4,″WdLength″,″Bits/word″,′I′,YES},{5,″StopBits″,″Bits,′I′,YES},{6,″ModbusID″,″″,′I′,YES},{7,″Spare″,″″,′I′,NO},{8,″Spare″,″″,′I′,NO},{9,″Spare″,″″,′I′,NO},{10,″Spare″,″″,′I′,NO},{11,″Spare″,″″,′I′,NO},{12,″Spare″,″″,′I′,NO},{13,″Spare″,″″,′I′,NO},{14,″Spare″,″″,′I′,NO},{15,″Spare″,″″,′I′,NO}},15//Numberofpoints};staticmessageBlockmessageBlock9={//Oper{{200,″ZeroCut″,″ms″,′F′,YES},{202,″SSMax″,″ms″,′F′,YES},{204,″SSMin″,″ms″,′F′,YES},{206,″EmRate″,″sec″,′F′,YES},{208,″SampRate″,″MHz″,′F′,YES},{210,″PulseWidth″,″sec″,′F′,YES},{212,″PctFail″,″%″,′F′,YES},{214,″MinHoldTime″,″sec″,′F′,YES},{216,″PklPct″,″%″,′F′,YES},{218,″MinSigQlty″,″″,′F′,YES},{220,″DltChk″,″sec″,′F′,YES},{222,″Spare″,″″,′F′,NO},{224,″NegSpan″,″sec″,′F′,YES},{226,″PosSpan″,″sec″,′F′,YES},{228,″TmDevLow1″,″sec″,′F′,YES},{230,″TmDevLow2″,″sec″,′F′,YES},{232,″CRange″,″%″,′F′,YES},{234,″SDevLow″,″sec″,′F′,YES},{236,″SDevFctr″,″″,′F′,YES},{238,″Pk1Wdth″,″sec″,′F′,YES},{240,″TmDevFctr1″,″″,′F′,YES},{242,″TmDevFctr2″,″″,′F′,YES},{244,″FlwChgThrsh″,″%″,′F′,YES},{246,″FlwChgDtctr″,″sec″,′F′,YES},{248,″StackEmRate″,″sec″,′F′,YES}},25//Numberofpoints};staticmessageBlockmessageBlock12={{{350,″Spare″,″″,′F′,NO},{352,″FlowVelA″,″m/s″,′F′,YES},{354,″FlowVelB″,″m/s″,′F′,YES},{356,″FlowVelC″,″m/s″,′F′,YES},{358,″FlowVelD″,″m/s″,′F′,YES},{360,″AvgFlow″,″m/s″,′F′,YES},{362,″SndVelA″,″m/s″,′F′,YES},{364,″SndVelB″,″m/s″,′F′,YES},{366,″SndVelC″,″m/s″,′F′,YES},{368,″SndVelD″,″m/s″,′F′,YES},{370,″AygSndVel″,″m/s″,′F′,YES},{372,″CalVol″,″m^3″,′F′,NO},{374,″CalTime″,″pulses″,′F′,NO},{376,″SDevVelA″,″m/s″,′F′,NO},{378,″SDevVelB″,″m/s″,′F′,NO},{380,″SDevVelC″,″m/s″,′F′,NO},{382,″SDevVelD″,″m/s″,′F′,NO},{384,″SDevSndA″,″m/s″,′F′,NO},{386,″SDevSndB″,″m/s″,′F′,NO},{388,″SDevSndC″,″m/s″,′F′,NO},{390,″SDevSndD″,″m/s″,′F′,NO},{392,″FlowRate″,″acmh″,′F′,YES},{394,″CutRate″,″acmh″,′F′,NO},{396,″CalVolA″,″m^3″,′F′,NO},{398,″CalVolb″,″m^3″,′F′,NO}},25//Numberofpoints};staticmessageBlockmessageBlock13={//Oper{{400,″Spare″,″---″,′F′,YES},{402,″MaxTmA1″,″sec″,′F′,YES},{404,″MaxTmB1″,″sec″,′F′,YES},{406,″MaxTmC1″,″sec″,′F′,YES},{408,″MaxTmD1″,″sec″,′F′,YES},{410,″MaxTmA2″,″sec″,′F′,YES},{412,″MaxTmB2″,″sec″,′F′,YES},{414,″MaxTmC2″,″sec″,′F′,YES},{416,″MaxTmD2″,″sec″,′F′,YES},{418,″MinTmA1″,″sec″,′F′,YES},{420,″MinTmB1″,″sec″,′F′,YES},{422,″MinTmC1″,″sec″,′F′,YES},{424,″MihTmD1″,″sec″,′F′,YES},{426,″MinTmA2″,″sec″,′F′,YES},{428,″MinTmB2″,″sec″,′F′,YES},{430,″MinTmC2″,″sec″,′F′,YES},{432,″MinTmD2″,″sec″,′F′,YES},{434,″MeanTmA1″,″sec″,′F′,YES},{436,″MeanTmB1″,″sec″,′F′,YES},{438,″MeanTmC1″,″sec″,′F′,YES},{440,″MeanTmD1″,″sec″,′F′,YES},{442,″MeanTmA2″,″sec″,′F′,YES},{444,″MeanTmB2″,″sec″,′F′,YES},{446,″MeanTmC2″,″sec″,′F′,YES},{448,″MeanTmD2″,″sec″,′F′,YES}},25//Numberofpoints};staticmessageBlockmessageBlock14={//CalculationResults{{450,″Spare″,″---″,′F′,NO},{452,″DltTmA″,″sec″,′F′,YES},{454,″DltTmB″,″sec″,′F′,YES},{456,″DltTmC″,″sec″,′F′,YES},{458,″DltTmD″,″sec″,′F′,YES},{460,″SDevTmA1″,″ns″,′F′,YES},{462,″SDevTmB1″,″ns″,′F′,YES},{464,″SDevTmB1″,″ns″,′F′,YES},{466,″SDevTmD1″,″ns″,′F′,YES},{468,″SDevTmA2″,″ns″,′F′,YES},{470,″SDevTmB2″,″ns″,′F′,YES},{472,″SDevTmC2″,″ns″,′F′,YES},{474,″SDevTmD2″,″ns″,′F′,YES},{476,″SDevDltTmA″,″ns″,′F′,YES},{478,″SDevDltTmB″,″ns″,′F′,YES},{480,″SDevDltTmC″,″ns″,′F′,YES},{482,″SDevDltTmD″,″ns″,′F′,YES},{484,″MaxDltTmA″,″sec″,′F′,YES},{486,″MaxDltTmB″,″sec″,′F′,YES},{488,″MaxDltTmC″,″sec″,′F′,YES},{490,″MaxDltTmD″,″sec″,′F′,YES},{492,″MinDltTmA″,″sec″,′F′,YES},{494,″MinDltTmB″,″sec″,′F′,YES},{496,″MinDltTmC″,″sec″,′F′,YES},{498,″MinDltTmD″,″sec″,′F′,YES}},25 //Numberofpoints};staticmessageBlockmessageBlock15={//Diag{{500,″Spare″,″---″,′F′,NO},{502,″HoldTmA1″,″sec″,′F′,YES},{504,″HoldTmA2″,″sec″,′F′,YES},{506,″HoldTmB1″,″sec″,′F′,YES},{508,″HoldTmB2″,″sec″,′F′,YES},{510,″HoldTmC1″,″sec″,′F′,YES},{512,″HoldTmC2″,″sec″,′F′,YES},{514,″HoldTmD1″,″sec″,′F′,YES},{516,″HoldTmD2″,″sec″,′F′,YES},{518,″WdwPtrA1″,″si″,′F′,YES},{520,″WdwPtrA2″,″si″,′F′,YES},{522,″WdwPtrB1″,″si″,′F′,YES},{524,″WdwPtrB2″,″si″,′F′,YES},{526,″WdwPtrC1″,″si″,′F′,YES},{528,″WdwPtrC2″,″si″,′F′,YES},{530,″WdwPtrD1″,″si″,′F′,YES},{532,″WdwPtrD2″,″si″,′F′,YES},{534,″Spare″,″---″,′F′,NO},{536,″Spare″,″---″,′F′,NO},{538,″Spare″,″---″,′F′,NO},{540,″Spare″,″---″,′F′,NO},{542,″Spare″,″---″,′F′,NO},{544,″Spare″,″---″,′F′,NO},{546,″Spare″,″---″,′F′,NO},{548,″Spare″,″---″,′F′,NO}},25//Numberofpoints};staticmessageBlockmessageBlock16={//Diag{{550,″PfA1″,″si″,′F′,YES},{552,″PfA2″,″si″,′F′,YES},{554,″pfB1″,″si″,′F′,YES},{556,″PfB2″,″si″,′F′,YES},{558,″PfC1″,″si″,′F′,YES},{560,″PfC2″,″si″,′F′,YES},{562,″PfD1″,″si″,′F′,YES},{564,″PfD2″,″si″,′F′,YES},{566,″P1A1″,″si″,′F′,YES},{568,″P1A2″,″si″,′F′,YES},{570,″P1B1″,″si″,′F′,YES},{572,″P1B2″,″si″,′F′,YES},{574,″P1C1″,″si″,′F′,YES},{576,″P1C2″,″si″,′F′,YES},{578,″P1D1″,″si″,′F′,YES},{580,″P1D2″,″si″,′F′,YES},{582,″PwA1″,″si″,′F′,YES},{584,″PwA2″,″si″,′F′,YES},{586,″PwB1″,″si″,′F′,YES},{588,″PwB2″,″si″,′F′,YES},{590,″PwC1″,″si″,′F′,YES},{592,″PwC2″,″si″,′F′,YES},{594,″PwD1″,″si″,′F′,YES},{596,″PwD2″,″si″,′F′,YES},{598,″Spare″,″---″,F(xiàn)′,YES}},25//Numberofpoints};staticmessageBlockmessageBlock17={//CalculationResults{{600,″PropA″,″---″,′F′,YES},{602,″PropB″,″---″,′F′,YES},{604,″PropC″,″---″,′F′,YES},{606,″PropD″,″---″,′F′,YES},{608,″RPropA″,″---″,′F′,YES},{610,″RPropB″,″---″,′F′,YES},{612,″RPropC″,″---″,′F′,YES},{614,″RPropD″,″---″,′F′,YES},{616,″RABLo″,″---″,′F′,YES},{618,″RABHi″,″---″,′F′,YES},{620,″RDCLo″,″---″,′F,YES},{622,″RDCHi″,″---″,′F′,YES},{624,″RADLo″,″---″,′F′,YES},{626,″RADHi″,″---″,′F′,YES},{628,″RBCLo″,″---″,′F′,YES},{630,″RBCHi″,″---″,′F′,YES},{632,″Spare″,″---″,′F′,NO},{634,″Spare″,″---″,′F′,NO},{636,″Spare″,″---″,′F′,NO},{638,″Spare″,″---″,′F′,NO},{640,″Spare″,″---″,′F′,NO},{642,″Spare″,″---″,′F′,NO},{644,″Spare″,″---″,′F′,NO},{646,″Spare″,″---″,′F′,NO},{648,″Spare″,″---″,′F′,NO}},25//Numberofpoints};staticmessageBlockmessageBlock18={//Oper{{650,″Spare″,″---″,′F′,NO},{652,″Spare″,″---″,′F′,NO},{654,″Spare″,″---″,′F′,NO},{656,″Spare″,″---″,′F′,NO},{658,″Spare″,″---″,′F′,NO},{660,″Spare″,″---″,′F′,NO},{662,″Spare″,″---″,′F′,NO},{664,″Spare″,″---″,′F′,NO},{666,″Spare″,″---″,′F′,NO},{668,″Spare″,″---″,′F′,NO},{670,″Spare″,″---″,′F′,NO},{672,″Spare″,″---″,′F′,NO},{674,″Spare″,″---″,′F′,NO},{676,″Spare″,″---″,′F′,NO},{678,″Spare″,″---″,′F′,NO},{680,″Spare″,″---″,′F′,NO},{682,″Spare″,″---″,′F′,NO},{684,″Spare″,″---″,′F′,NO},{686,″Spare″,″---″,′F′,NO},{688,″Spare″,″---″,′F′,NO},{690,″Spare″,″---″,′F′,NO},{692,″Spare″,″---″,′F′,NO},{694,″Spare″,″---″,′F′,NO},{696,″Spare″,″---″,′F′,NO},{698,″Spare″,″---″,′F′,NO}},25//Numberofpoints};staticmessageBlockmessageBlock19={//Diag{{700,″Wdw1A1″,″---″,′F′,YES},{702,″Wdw1A2″,″---″,′F′,YES},{704,″Wdw1B1″,″---″,′F′,YES},{706,″Wdw1B2″,″---″,′F′,YES},{708,″Wdw1C1″,″---″,′F′,YES},{710,″Wdw1C2″,″---″,′F′,YES},{712,″Wdw1D1″,″---″,′F′,YES},{714,″Wdw1D2″,″---″,′F′,YES},{716,″Wdw2A1″,″---″,′F′,YES},{718,″Wdw2A2″,″---″,′F′,YES},{720,″Wdw2B1″,″---″,′F′,YES},{722,″Wdw2B2″,″---″,′F′,YES},{724,″Wdw2C1″,″---″,′F′,YES},{726,″Wdw2C2″,″---″,′F′,YES},{728,″Wdw2D1″,″---″,′F′,YES},{730,″Wdw2D2″,″---″,′F′,YES},{732,″Spare″,″---″,′F′,NO},{734,″Spare″,″---″,′F′,NO},{736,″Spare″,″---″,′F′,NO},{738,″Spare″,″---″,′F′,NO},{740,″Spare″,″---″,′F′,NO},{742,″Spare″,″---″,′F′,NO},{744,″Spare″,″---″,′F′,NO},{746,″Spare″,″---″,′F′,NO},{748,″Spare″,″---″,′F′,NO}},25//Numberofpoints};staticmessageBlockmessageBlook20={//Diag{{750,″Wdw3A1″,″---″,′F′,YES},{752,″Wdw3A2″,″---″,′F′,YES},{754,″Wdw3B1″,″---″,′F′,YES},{756,″Wdw3B2″,″---″,′F′,YES},{758,″Wdw3C1″,″---″,′F′,YES},{760,″Wdw3C2″,″---″,′F′,YES},{762,″Wdw3D1″,″---″,′F′,YES},{764,″Wdw3D2″,″---″,′F′,YES},{766,″Wdw4A1″,″---″,′F′,YES},{768,″Wdw4A2″,″---″,′F′,YES},{770,″Wdw4B1″,″---″,′F′,YES},{772,″Wdw4B2″,″---″,′F′,YES},{774,″Wdw4C1″,″---″,′F′,YES},{776,″Wdw4C2″,″---″,′F′,YES},{778,″Wdw4D1″,″---″,′F′,YES},{780,″Wdw4D2″,″---″,′F′,YES},{782,″Spare″,″---″,′F′,NO},{784,″Spare″,″---″,′F′,NO},{786,″Spare″,″---″,′F′,NO},{788,″Spare″,″---″,′F′,NO},{790,″Spare″,″---″,′F′,NO},{792,″Spare″,″---″,′F′,NO},{794,″Spare″,″---″,′F′,NO},{796,″Spare″,″---″,′F′,NO},{798,″Spare″,″---″,′F′,NO}},25//Numberofpoints};staticmessageBlockmessageBlock21={//Diag{ {800,″SpecMaxA1″,″---″,′F′,YES}, {802,″SpecMaxA2″,″---″,′F′,YES}, {804,″SpecMaxB1″,″---″,′F′,YES}, {806,″SpecMaxB2″,″---″,′F′,YES}, {808,″SpecMaxC1″,″---″,′F′,YES}, {810,″SpecMaxC2″,″---″,′F′,YES}, {812,″SpecMaxD1″,″---″,′F′,YES}, {814,″SpecMaxD2″,″---″,′F′,YES}, {816,″MaxNEA1″,″---″,′F′,YES}, {818,″MaxNEA2″,″---″,′F′,YES}, {820,″MaxNEB1″,″---″,′F′,YES}, {822,″MaxNEB2″,″---″,′F′,YES}, {824,″MaxNEC1″,″---″,′F′,YES}, {826,″MaxNEC2″,″---″,′F′,YES}, {828,″MaxNED1″,″---″,′F′,YES},{830,″MaxNED2″,″---″,′F′,YES},{832,″QpefA1″,″---″,′F′,YES},{834,″QpefA2″,″---″,′F′,YES},{836,″QpefB1″,″---″,′F′,YES},{838,″QpefB2″,″---″,′F′,YES},{840,″QpefC1″,″---″,′F′,YES},{842,″QpefC2″,″---″,′F′,YES},{844,″QpefD1″,″---″,′F′,YES},{846,″QpefD2″,″---″,′F′,YES},{848,″Spare″,″---″,′F′,NO}},25//Numberofpoints};messageBlock*messageBlocks[]={NULL,//Messageblock0isnotdefined&messageBlock1,//Messageblock1NULL,//Messageblock2isnotdefinedNULL,//Messageblock3isnotdefinedNULL,//Messageblock4isnotdefinedNULL,//Messageblock5isnotdefinedNULL,//Messageblock6isnotdefinedNULL,//Messageblock7isnotdefinedNULL,//Messageblock8isnotdefined&messageBlock9,//Messagebloek9NULL,//Messageblock10isnotdefinedNULL,//Messageblock11isnotdefined&messageBlock12,//Messageblock12&messageBlock13,//Messageblock13&messageBlock14,//Messageblock14&messageBlock15,//Messageblock15&messageBlock16,//Messageblock16&messageBlock17,//Messageblock17&messageBlock18,//Messageblock18&messageBlock19,//Messageblock19&messageBlock20,//Messageblock20&messageBlock21,//Messageblock21NULL,//Messageblock22isnotdefinedNULL,//Messageblock23isnotdefinedNULL,//Messageblock24isnotdefinedNULL,//Messageblock25isnotdefinedNULL,//Messageblock26isnotdefinedNULL,//Messageblock27isnotdefinedNULL,//Messageblock28isnotdefinedNULL,//Messageblock29isnotdefinedNULL,//Messageblock30isnotdefinedNULL,//Messageblock31isnotdefinedNULL//Messageblock32isnotdefined};unsignedintnMessageBlocks=(sizeof(messageBlocks)/sizeof(messageBlocks));//MethodtocountthenumberofnativemodbusregistersinamessageblockintregistersInMessageBlock(messageBlock*mbp){inti;//Loopcontrolintc=0;//Accumulatorfor(i=0;inPoints;i++){switch(mbp->points[i].type){case′F′{//ModbusFloatis2registersc+=2;break;}case′I′{c++;//ModbusIntis1registerbreak;}defaultfprintf(stderr,″Unrecognizeddataitemtype%c\n″,mbp->points[i].type);}}returnc;}//Endof“ultrasonicMessageBlocks.cc”ProgramCode//Startof“Makefile”ProgramCodeCC=g++allultrasonicconvertModbus.oconvertModbus.ccconvertModbus.hMakefile $(CC)-c-Wall-gconvertModbus.ccasciiModbus.oasciiModbus.ccasciiModbus.hMakefile $(CC)-c-Wall-gasciiModbus.ccultrasonicMessageBlocks.oultrasonicMessageBlocks.cc\ ultrasonicMessageBlocks.hMakefile $(CC)-c-Wall-gultrasonicMessageBlocks.ccultrasonic.oultrasonic.ccasciiModbus.hmodData.hMakefile $(CC)-c-DDEBUG-Wall-gultrasonic.ccultrasonicasciiModbus.oconvertModbus.oultrasonic.o\ ultrasonicMessageBlocks.oMakefile $(CC)asciiModbus.oultrasonic.oultrasonicMessageBlocks.o\ convertModbus.o-oultrasonic//Endof“Makefile”ProgramCode//Startof“ultrasonicMessageBlocks.h”ProgramCode#ifndefULTRASONICMESSAGEBLOCS_H#defineULTRASONICMESSAGEBLOCS_H////FileultrasonicMessageBlocks.h//AuthorD.Lambert//DateJuly2,1998////Definesstructuresformessageblocksas//implementedintheultrasonicmeter.//#include″modData.h″#defineMAXPOINTS128//MaximumnumberofpointsinamessageblocktyPedefstruct{modDatapoints[MAXPOINTS];intnPoints;}messageBlock;////Thearrayofmessageblocks//externmessageBlock*messageBlocks[];externunsignedintnMessageBlocks;////Returnacountofthenumberofmodbusregistersinamessageblock//intregistersInMessageBlock(messageBlock*mbp);#endif//Endof“ultrasonicMessageBlocks.h”ProgramCode//Startof“ultrasonic12”ProgramCode#!/bin/bashcat<<EOMContent-typetext/html<html><head><TITLE>UltrasonicMeter1</TITLE></head><BODYbackground=″../backlla.gif″><body><H1><imgsrc=″../logo_bln.gif″align=bottom></H1><H1>UltrasonicMeter1</H1><H1><imgsrc=″../danlineb.gif″align=bottom></H1><HR><BR><H2><CENTER><appletcode=j(luò)avachart.applet.dateLineApp.classcodebase=../width=900height=240><paramname=CopyrightNotificationvalue=″JavaChartisacopyrightedwork,andsubjecttofulllegalprotection″> ?。紁aramname=titleStringvalue=″Today′sFlowHistory″> ?。紁aramname=titleFontvalue=″TimesRoman,20,1″> ?。紁aramname=plotAreaTopvalue=″.80″> ?。紁aramname=plotAreaLeftvalue=″.05″> ?。紁aramname=plotAreaRightvalue=″.85″> ?。紁aramname=plotAreaBottomvalue=″.10″> <paramname=xAxisOptionsvalue=″gridOn″> ?。紁aramname=y(tǒng)AxisOptionsvalue=″gridOn,rightAxis″> ?。紁aramname=networkIntervalvalue=″20″> <paramname=customDarasetHandlervalue=″../ultsonic/ultrasonic.log″> ?。紁aramname=dataset0namevalue=″Meter1″> ?。紁aramname=dataset0Colorvalue=″red″> ?。紁aramname=legendOnvalue=″yes″> <paramname=legendLabelFontvalue=″TimesRoman,24,2″> ?。紁aramname=2Dvalue=″yes″></applet><HR><tableborder=1bgcolor=whitesmokecellspacing=0cellpadding=5cols=3align=left><tr><thcolspan=3><B>AssortedDatasets</B><tr>EOMcat<<EOF<tdvalign=top><tablebgcolor=whiteborder=1cellspacing=0cellpadding=5cols=3><tr><thcolspan=3><B>Setup</B></th>EOF/bin/ultrasonic/dev/cua0321cat<<EOF</table>EOFcat<<EOF<tdvalign=top><tablebgcolor=whiteborder=Icellspacing=0cellpadding=5cols=3><tr><thcolspan=3><B>FlowData</B></th>EOF/bin/ultrasonic/dev/cua03212cat<<EOF</table>EOFcat<<EOF<tdval=top><tablebgcolor=whiteborder=1cellspacing=0cellpadding=5cols=3><tr><thcolspan=3><B>CalculationResults</B></th>EOF/bin/ultrasonic/dev/cua03214cat<<EOF</table>EOFcat<<EOM</table></H2><H2>ClickmeterImagetoRefresh</H2><AHREF=ultrasonic12><imgsrc=″../ultsonic.gif″align=top></A></CENTER></body></html>EOM//Endof“ultrasonic12”ProgramCode//Startof“ultrasonic.c”ProgramCode//Ultrasonicacquistionmodule//D.Lambert//DanielIndustries//June8,1998#include<stdio.h>#include<errno.h>#include<unistd.h>#include″modData.h″#include″convertModbus.h″#include″asciiModbus.h″#include″ultrasonicMessageBlocks.h″//Staticfunctionprototypes//Localdefinitions#defineREADREGS3//Readmultipleregistersfunctioncodeintmain(intargc,char**argv){intnRegsRx;//Numberofregistersreceivedintfd;uintmbno;//Messageblocknumberintaddress;messageBlock*mb;modRegrxBuf[256];modRegtxData[2];//Transmitdatabufferif(argc<2){//Makesuredeviceisspecifiedfprintf(stderr,″Serialdevicenameisrequiredasparameter1\n″);}if(argc<3){fprintf(stderr,″ModbusIDformeterisrequiredasparameter2\n″);}if(argc<4){fprintf(stderr,″Messageblocknumberisrequiredasparameter3\n″);exit(1);}sscanf(argv[2],″%ud″,&address);if(address>64){fprintf(stderr,″Address%disoutofrange\n″,address);exit(1);}sscanf(argv[3],″%ud″,&mbno);if(mbno>=nMessageBlocks){fprintf(stderr,″Messageblocknumber%disoutofrange\n″,mbno);exit(1);}if((mb=messageBlocks[mbno])=NULL){fptintf(stderr,″Messageblocknumber%disnotyetimplemented\n″,mbno);exit(1);}if((fd=setupSerial(argv[1]))<0){//Openthedevicefprintf(stderr,″%s%s\n″,argv[1],sys_errlist[errno]);exit(1);}txData.value=mb->points.reg;//StartRegistertxData[1].value=registersInMessageBlock(mb);//NumberofregistersnRegsRx=sendAndReceiveAscii(fd,address,READREGS, txData,2, rxBuf,sizeof(rxBuf));if(nRegsRx<=0){fprintf(stderr,″CommunicationFailure-%s\n″,sys_errlist[errno]);printf(″CommunicationFailure-%s\n″,sys_errlist[errno]);}else{//Wehavegooddata,processit!inti;//LoopcountermodReg*mrp=rxBuf;//Pointertorxmodbusregistersfor(i=0;i<nRegsRx;i++){modData*mdp=&mb->points[i];//Pointertomodbusdatadescriptorsif(mdp->type=′F′){//Processfloats if(mdp->display){ printf(″%8s\t%f%s\n″,mdp->name,getFloat(mrp),mdp->units); } mrp+=2;//Afloatistwomodbusregisters}elseif(mdp->type=T){//Processints if(mdp->display){printf(″%8s\t%hd%s\n″,mdp->name,getShort(mrp),mdp->units); } mrp++;//Ashortintegerisonemodbusregister}}}fflush(NULL);//Flushallstreamsclose(fd);//Closedevice}//Endof“ultrasonic.c”programCode]]></pre>附錄E<prelisting-type="program-listing"><![CDATA[makeLILObootdiskscript#ThisismakeLILObootdiskscript#Firstmakeacompressedimageoftherootfilesystemusingaramdiskimage./makeCompressedRamDisk#Unmnounttheflashdiskunmount/mnt/flash#Setavariabletobelargerthanthenumberofblocks#occupiedbythekernelimageandaminimalfilesystem.ExportKERNEL_BLOCKS=430#MakeafilesystemthatsizeonthefirstpartoftheFLASHdisk.Mke2fs-i8192-m0/dev/hdc$KERNEL_BLOCKS#Nowmountthatfilesystemthathasjustbeencreatedmount/dev/hdc/mnt/flash#Removefilesthatarenotrequiredrm-rf/mnt/flash/lost+found#Makethenecessarydirectoriesmkdir/mnt/flash/lost+found#Makethenecessarydirectoriesmkdir/mnt/flash/{boot,dev}#Copyneededdevices,cp-dpR/dev/{null,hda,hdal,hdc,hdcl}/mnt/flash/dev#bootfilescp/boot/boot.b/mnt/flash/boot#configurationfiles,andfinallythekernelimagecpbdlilo.confvmlinuz.embedded/mnt/flash#Runlilotoupdatethebootblock#lilo-v-Cbdlilo.conf-r/mnt/flash#echo″Settingflagstocopytoramdiskandstarttheimageatblock$KERNEL_BI#Updatethekernelimagetolinktothecompressedramdiskimage#rdev-r/mnt/flash/vmlinuz.embedded8622#UnmountthetlasthdiskUnmount/mnt/flash#Writetheramdiskimageaftertheendofthekernelfilesystem.#echo″Writingthecompressedrootfilesystemimagetothefloppyafter#thebootimage″ddif=/tmp/ram_image.gzof=/dev/hdcbs=1kseek+$KERNEL_BLOCKSmakeCompressedRamDiskscript#makeCompressedRamDiskscriptecho″Makingaramdiskdevice″#Createaramdiskbywritingzeroesusingddddif=/dev/zeroof=/dev/rambs=1kcount=4096#Makeafilesystemecho″Puttinganext2filesystemontheramdisk″mke2fs-vm0/dev/ram4096#Mounttheramdiskecho″Mountingthedisk″mount/dev/ram/mnt/ram#Copytherootfilesystemtotheramdiskecho″Copyingtherootfilesystem″cp-dpR./root/*/mnt/ram#Unmounttheramdiskecho″Unmountingthedisk″Unmount/mnt/ram#Compresstheramdiskandcopyittoafileecho″Compressingtheimage″ddif=/dev/rambs=1kcount=4096|gzip-9>/tmp/ram_image.gzbdlilo.confscriptinstall=/boot/boot.bmap=/boot/mapread-writeappend=″load_rarndisk=1ramdisk_start=430ramdisk_size=8192″backup=/dev/nullcompactimage=vmlinuz.embeddedlabel=Bootdiskroot=dev/hda]]></pre>權(quán)利要求1.一種網(wǎng)絡(luò)流量系統(tǒng),包括至少一個測量裝置;流量計算機,與至少一個測量裝置相連并被配置為從所述至少一個測量裝置接收數(shù)據(jù),所述流量計算機還是web服務(wù)器;主計算機,在本地或通過因特網(wǎng)/內(nèi)部網(wǎng)連接到所述流量計算機,其中所述主計算機被編程為根據(jù)一通信協(xié)議發(fā)送和接收數(shù)據(jù),并且所述主計算機可以利用所述主計算機和所述流量計算機之間的所述連接與所述流量計算機通信。2.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述流量計算機由URL地址標(biāo)識。3.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述主計算機以網(wǎng)頁格式從所述web服務(wù)器接收數(shù)據(jù)。4.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述通信協(xié)議是因特網(wǎng)協(xié)議。5.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述流量計算機可編程為識別所述至少一個測量裝置而無需來自所述主計算機的指示,并且所述流量計算機進行自配置以與所述至少一個測量裝置通信。6.根據(jù)權(quán)利要求4的網(wǎng)絡(luò)流量系統(tǒng),其中所述流量計算機可編程為識別所述至少一個測量裝置而無需來自所述主計算機的指示,并且所述流量計算機進行自配置以與所述至少一個測量裝置通信。7.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述流量計算機進一步包括存儲裝置,并且利用所述存儲裝置上記錄的可升級操作系統(tǒng)對所述流量計算機編程。8.根據(jù)權(quán)利要求7的網(wǎng)絡(luò)流量系統(tǒng),其中所述操作系統(tǒng)被壓縮到所述閃速盤上。9.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中至少一個所述測量裝置利用非因特網(wǎng)協(xié)議與所述流量計算機通信。10.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述主計算機可以通過所述因特網(wǎng)、內(nèi)部網(wǎng)連接遠程地對所述流量計算機編程。11.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述流量計算機被以安全方式編程,以僅在滿足預(yù)定條件時允許所述主計算機對所述流量計算機編程。12.根據(jù)權(quán)利要求1的網(wǎng)絡(luò)流量系統(tǒng),其中所述主計算機通過web瀏覽器與所述流量計算機通信。13.一種用于獲得測量數(shù)據(jù)的方法,包括(a)將一流量計算機耦合到一測量裝置,所述測量裝置適合于監(jiān)視一流體并提供相應(yīng)測量數(shù)據(jù);(b)通過一通信鏈路將所述流量計算機連接到一主計算機,所述流量計算機利用第一協(xié)議與所述測量裝置通信,并利用第二協(xié)議與所述主計算機通信,所述第二協(xié)議適于因特網(wǎng)/內(nèi)部網(wǎng)通信,其中所述主計算機通過所述流量計算機從所述測量裝置獲得所述相應(yīng)測量數(shù)據(jù)。14.根據(jù)權(quán)利要求13的方法,其中所述流量計算機以有規(guī)律的間隔詢問所述測量裝置,所述測量裝置以測量數(shù)據(jù)進行響應(yīng),其中所述流量計算機產(chǎn)生所述測量數(shù)據(jù)的記錄文件。15.根據(jù)權(quán)利要求13的方法,其中所述主計算機能夠?qū)λ隽髁坑嬎銠C編程。16.根據(jù)權(quán)利要求13的方法,其中所述主計算機能夠使用因特網(wǎng)瀏覽器軟件對所述流量計算機編程。17.根據(jù)權(quán)利要求13的方法,其中所述主計算機使用URL地址識別所述流量計算機。18.根據(jù)權(quán)利要求13的方法,其中所述流量計算機被編程以產(chǎn)生包括來自所述測量裝置的所述相應(yīng)數(shù)據(jù)的網(wǎng)頁。19.一種網(wǎng)絡(luò)流量計算機,包括第一通信端口,適合于連接到一測量裝置;第二通信端口,適合于因特網(wǎng)/內(nèi)部網(wǎng)連接;至少一個處理器;存儲裝置,附接到所述至少一個處理器,所述至少一個處理器可編程為通過所述第一通信端口接收來自所述測量裝置的數(shù)據(jù),并且可編程為通過所述第二通信端口利用所述因特網(wǎng)/內(nèi)部網(wǎng)連接發(fā)送數(shù)據(jù)。20.根據(jù)權(quán)利要求19的網(wǎng)絡(luò)流量計算機,其中在所述存儲裝置上存儲一壓縮的操作系統(tǒng)。21.根據(jù)權(quán)利要求19的網(wǎng)絡(luò)流量計算機,其中與所述網(wǎng)絡(luò)流量計算機協(xié)同使用一可升級的操作系統(tǒng)。22.根據(jù)權(quán)利要求19的網(wǎng)絡(luò)流量計算機,其中所述處理器對從所述測量裝置接收的所述數(shù)據(jù)進行計算。23.根據(jù)權(quán)利要求22的網(wǎng)絡(luò)流量計算機,其中所述處理器將來自所述計算的結(jié)果放在一個可通過所述第二通信端口訪問的網(wǎng)頁上。24.根據(jù)權(quán)利要求19的網(wǎng)絡(luò)流量計算機,其中所述處理器將從所述測量裝置接收的數(shù)據(jù)放在一個可通過所述第二通信端口訪問的網(wǎng)頁上。全文摘要一種改進的網(wǎng)絡(luò)流量系統(tǒng)包括可用于因特網(wǎng)/內(nèi)部網(wǎng)的具有至少一個流量測量裝置的網(wǎng)絡(luò)流量計算機和能夠使用因特網(wǎng)技術(shù)與流量計算機通信或本地連接到流量計算機的主計算機。在一個實施例中,可用于因特網(wǎng)的網(wǎng)絡(luò)流量計算機以原始或計算后的形式從一個或多個測量裝置接收流量測量數(shù)據(jù)。主計算機通過因特網(wǎng)、內(nèi)部網(wǎng)或在本地連接到網(wǎng)絡(luò)流量計算機。主計算機從/向網(wǎng)絡(luò)流量計算機發(fā)送/接收數(shù)據(jù),包括在主計算機上以網(wǎng)頁格式查看流量數(shù)據(jù)結(jié)果的能力,和從主計算機遠程地或在本地配置和控制流量計算機的能力。文檔編號G06F15/00GK1330765SQ99814503公開日2002年1月9日申請日期1999年12月15日優(yōu)先權(quán)日1998年12月15日發(fā)明者J·戴維·A·蘭伯特,維平·馬利克,里克·霍伊爾申請人:丹尼爾工業(yè)公司