LabVIEW中的錯誤處理
默認的,LabVIEW是會(huì )進(jìn)行自動(dòng)錯誤處理的。這表現在當程序執行過(guò)程中出現錯誤時(shí)(如加載文件失?。?,程序會(huì )掛起,LabVIEW會(huì )自動(dòng)彈出錯誤對話(huà)框,并高亮導致錯誤產(chǎn)生的子VI或函數模塊。在LabVIEW中可以通過(guò):1)工具>>選項>>程序框圖>>錯誤處理:該分支下有兩個(gè)選項可以決定是否使能自動(dòng)錯誤處理;2)對于單個(gè)VI,文件>>VI屬性>>執行:該分支下可以選擇是否對當前VI關(guān)閉自動(dòng)錯誤處理。
如果希望程序在執行過(guò)程中出現錯誤時(shí)能給出更有意義的提示信息,我們可以使用自定義錯誤處理。首先評估一下該應用中,有可能會(huì )出現哪些錯誤,并給這個(gè)錯誤賦特定的錯誤代碼(error code)和描述信息(description)。LabVIEW預留了以下錯誤代碼供用戶(hù)自定義錯誤使用:-8999到-8000,5000到9999,500000到599999。比如:在一個(gè)數據采集應用中,需要監測外部信號的幅值,當幅值大于8V時(shí),我們可以定義該錯誤碼為6000,并通過(guò)General Error Handler函數彈出相應對話(huà)框。(參考basic error handling.vi)

圖1.通用錯誤處理
上述這種方式,如果程序很大時(shí),為了不遺漏掉各部分可能產(chǎn)生的錯誤,我們需要不斷的放置General Error Handler函數,并給它不斷的配置“用戶(hù)自定義代碼”和“用戶(hù)自定義描述信息”,時(shí)間長(cháng)了,就難于維護,而且很難面面俱到,而且增大代碼的體積和占用配圖的空間。有沒(méi)有一種全局的方式呢?答案是肯定的,在LabVIEW中通過(guò):工具>>高級>>編輯錯誤代碼,彈出錯誤代碼編輯對話(huà)窗口,可以新建或修改現有的文件。在錯誤編輯窗口中可以添加自定義錯誤代碼和相應的文本描述信息。如果是新建的文件,點(diǎn)擊Save按鈕時(shí)會(huì )彈出對話(huà)框提示保存,文件名稱(chēng)必須是xxx-errors.txt,xxx是用戶(hù)可以自由命名部分。xxx-errors.txt文件的存放目錄必須在:盤(pán)符:Program FilesNational InstrumentsLabVIEW 2011user.liberrors目錄下(這里以L(fǎng)abVIEW 2011為例,其中盤(pán)符為L(cháng)abVIEW所在的安裝目錄),如果沒(méi)有errors目錄,可以手動(dòng)創(chuàng )建。xxx-errors.txt文件在LabVIEW關(guān)閉并重啟后才生效。

圖2. 錯誤代碼編輯對話(huà)窗口
到這里的時(shí)候,如果只是一個(gè)人在孤獨的寫(xiě)程序,那么通過(guò)xxx-errors.txt文件對自定義錯誤代碼進(jìn)行管理就基本上能滿(mǎn)足一個(gè)LabVIEW開(kāi)發(fā)者在同一臺計算機上的要求了。但是在很多情況下,我們開(kāi)發(fā)的應用程序最終可能會(huì )在其它計算機上部署或運行,或者要共享給其他開(kāi)發(fā)人員,那怎么使得xxx-errors.txt得以復用。
如果是把源代碼共享給另一個(gè)開(kāi)發(fā)人員,只需要從原來(lái)的計算機上將xxx-errors.txt文檔拷貝到對方計算機上的相應目錄:盤(pán)符:Program FilesNational InstrumentsLabVIEW 2011user.liberrors下即可。如果是生成Executable文件,那么在Executable的屬性配置窗口的高級頁(yè)面中,勾選上“拷貝錯誤代碼文件”,這樣在生成Executable時(shí),會(huì )自動(dòng)將”盤(pán)符:Program FilesNational InstrumentsLabVIEW 2011user.liberrors”下所有的xxx-errors.txt復制到”C:Program FilesNational InstrumentsSharedLabVIEW Run-Time2011errors”目錄下(這里以L(fǎng)abVIEW 2011為例,該路徑為L(cháng)abVIEW Run-Time的目錄)。

圖3. Executable的屬性配置窗口
但這只是在原來(lái)的計算機上做了一次復制,要在目標計算機上運行,除了拷貝Executable文件,必須將xxx-errors.txt文件手動(dòng)拷貝到目標計算機的LabVIEW Run-time目錄下。大家可能會(huì )有疑問(wèn),要是這樣的話(huà),那圖3中的勾選項還有什么用!確實(shí),如果只是在目標機上運行Executable,是否勾選上都無(wú)所謂。但是當我們勾選上之后,進(jìn)一步生成安裝文件時(shí),在安裝文件的屬性配置窗口的附加安裝頁(yè)面中,勾選上LabVIEW Run-time Engine,這樣安裝文件中將會(huì )包含LabVIEW Run-time Engine,而xxx-errors.txt在之前生成Executable時(shí)已經(jīng)拷貝到LabVIEW Run-time Engine目錄下了,也將包含在Installer中,所以在目標計算機上安裝Installer時(shí),就不再需要手動(dòng)拷貝xxx-errors.txt文件了。
好了,到這里為止?;A知識我們介紹完了,接下來(lái)我們介紹對于可預見(jiàn)的錯誤,是否可以選擇直接忽略,或者前幾次嘗試忽略直到該特定錯誤出現很多次后才通知用戶(hù)需要糾正該錯誤了;是否可以對重要的錯誤進(jìn)行存檔;當主VI中多個(gè)線(xiàn)程時(shí),如果某一個(gè)線(xiàn)程出錯,如何保證其它線(xiàn)程進(jìn)行適當的收尾后同樣優(yōu)雅的退出,避免一錯再錯。這里我編寫(xiě)了一個(gè)參考VI,我們將詳細介紹:

圖4.項目文件概覽
打開(kāi)Error Handling in LabVIEW.vi的程序框圖,其包含三個(gè)循環(huán),分別是Producer loop,Consumer loop,Display Loop。Producer loop用于響應用戶(hù)事件,并通過(guò)隊列通知Consumer loop執行相應的操作;Display loop用于對前面板顯示控件進(jìn)行更新。

圖5.項目原理圖
Error Handling in LabVIEW.vi中關(guān)于錯誤處理部分最核心的VI是Error Module.vi。它其實(shí)是一個(gè)功能全局變量,包含Initialize,Handle Errors和Report Errors三個(gè)分支。Initialize分支中定義好哪些錯誤代碼是直接被忽略的,哪些錯誤代碼是允許出現若干次,并且為了實(shí)現在主VI Error Handling in LabVIEW.vi的任何一個(gè)循環(huán)出現錯誤時(shí),所有的其它循環(huán)也能夠退出,在Initialize分支中將分別獲取三個(gè)循環(huán)中的相應隊列引用或用戶(hù)事件引用。

圖6.Error Module模塊

圖7. Initialize分支
先介紹一下Error Handling Info簇控件,它包含兩個(gè)數組。數組Ignore中定義的Error Code即我們希望Error Module.vi直接忽略的;Retry是簇數組,每個(gè)簇中包含三個(gè)元素:Code即我們希望出錯后重試的代碼,Retry times為允許出錯的次數,Current Iteration記錄了該特定錯誤已經(jīng)發(fā)生的次數(在主VI中不要設置,讓它為0)。我們希望當Current Iteration < Retry times時(shí),如果該錯誤出現,我們可以忽略該錯誤,但是Current Iteration值加1。對于本次測試,主VI給Error Module.vi的傳遞的參數如下,我們將在后面看到,5556的錯誤將被直接忽略,而5557的錯誤第三次出現時(shí)程序將彈出對話(huà)框提示出錯。

圖8. Error Handling Info簇控件信息
Error Module.vi中最重要的是Handle Errors分支,簡(jiǎn)單的說(shuō),它其實(shí)是包含兩層條件結構嵌套,三種處理情況。1)錯誤直接被忽略;2)錯誤符號Retry的條件;3)錯誤不能被預處理,將錯誤存檔。

圖9. Handle Errors分支
當錯誤不能被預處理時(shí),將錯誤存檔后,我們調用General Error Handler函數,這樣就會(huì )彈出錯誤對話(huà)框,對話(huà)框中包含xxx-errors.txt文件中定義好的描述信息。除了將錯誤存檔,在程序中同時(shí)通過(guò)元素入隊列、產(chǎn)生用戶(hù)事件使得主VI中的Consumer loop,Display loop和Producer loop都能夠優(yōu)雅的退出。
接下來(lái)我們來(lái)看一下程序的測試:

圖10.主VI前面板
1.點(diǎn)擊Acquire按鈕,將獲取波形;
2.點(diǎn)擊Generate error for consumer,將使得Consumer loop產(chǎn)生error 5555,由于5555不包含在預處理的情況中,Error Module.vi的Handle Errors分支將該錯誤存檔并彈出錯誤對話(huà)框,同時(shí)其它循環(huán)通過(guò)元素入隊列,產(chǎn)生用戶(hù)事件而退出,整個(gè)程序停止運行;
3.重新運行程序,點(diǎn)擊Generate error for Ignore按鈕,可以看到,程序將繼續正常運行,完全忽略該錯誤;
4.點(diǎn)擊Generate error for Retry按鈕,當點(diǎn)擊第三次時(shí),才彈出錯誤對話(huà)框,程序停止運行。如下圖所示:

圖11. 錯誤代碼5557重復出現3次
評論