LabVIEWCompactRIO 開發(fā)指南4 第三章LabVIEW實(shí)時(shí)應(yīng)用程序的設(shè)計(jì)
LabVIEWCompactRIO?開發(fā)指南4
第三章LabVIEW實(shí)時(shí)應(yīng)用程序的設(shè)計(jì)
在為CompactRIO創(chuàng)建LabVIEW實(shí)時(shí)應(yīng)用程序時(shí),從第1章:設(shè)計(jì)CompactRIO軟件體系結(jié)構(gòu)中描述的設(shè)計(jì)圖開始。如果開始軟件開發(fā)時(shí)沒有某種架構(gòu)或流程圖可供參考,那可能很難跟蹤所有軟件組件和通信路徑。一旦創(chuàng)建了一個(gè)設(shè)計(jì)圖,下一步就是實(shí)現(xiàn)LabVIEW實(shí)時(shí)代碼了。
頂層RTOS的設(shè)計(jì)VI
設(shè)計(jì)LabVIEW實(shí)時(shí)程序的一個(gè)很好的起點(diǎn)是創(chuàng)建一個(gè)類似于圖3.1所示VI的頂層框架。在這個(gè)框架VI中,進(jìn)程(循環(huán))包含在子VI中。將進(jìn)程包含在子VI中有助于創(chuàng)建可讀且可維護(hù)的應(yīng)用程序。每個(gè)子VI可能包含一個(gè)或多個(gè)進(jìn)程。

圖3.1?創(chuàng)建包含程序總體結(jié)構(gòu)的頂層VI
一旦設(shè)計(jì)了頂級(jí)RTOS?VI,下一步就是實(shí)現(xiàn)每個(gè)過程。本章提供了在LabVIEW?Real-Time中設(shè)計(jì)進(jìn)程的最佳實(shí)踐,包括確定性與非確定性進(jìn)程、進(jìn)程間數(shù)據(jù)通信、設(shè)計(jì)模式和內(nèi)存管理。
確定性和非確定性過程
對(duì)于許多工程師和科學(xué)家來(lái)說,在安裝了通用操作系統(tǒng)(如Windows)的標(biāo)準(zhǔn)PC上運(yùn)行測(cè)量或控制程序是不可接受的。在任何時(shí)候,操作系統(tǒng)都可能由于多種原因延遲用戶程序的執(zhí)行:運(yùn)行病毒掃描、更新圖形、執(zhí)行系統(tǒng)后臺(tái)任務(wù)等等。此外,對(duì)運(yùn)行時(shí)間有要求的應(yīng)用程序,意味著應(yīng)用程序需要在不重新啟動(dòng)的情況下運(yùn)行數(shù)天、數(shù)周或數(shù)年,此時(shí)通常需要RTOS。
在設(shè)計(jì)實(shí)時(shí)應(yīng)用程序時(shí),可以從兩個(gè)級(jí)別的可靠性中進(jìn)行選擇。
第一級(jí)的可靠性保證程序以一定的速度運(yùn)行而不會(huì)中斷。CompactRIO上使用的RTOS提供了這種級(jí)別的可靠性,而不需要任何特殊的編程技術(shù)??梢詫⑦M(jìn)程實(shí)現(xiàn)為帶有定時(shí)函數(shù)的常規(guī)While循環(huán),以獲得比使用通用操作系統(tǒng)高得多的可靠性。
第二級(jí)的可靠性涉及確定性和抖動(dòng)。如果確定性描述流程如何響應(yīng)外部事件或在給定的時(shí)間限制內(nèi)執(zhí)行操作,那么抖動(dòng)是執(zhí)行時(shí)間無(wú)法滿足這些期望的程度的度量。一些應(yīng)用程序需要定時(shí)行為在一個(gè)可接受的抖動(dòng)內(nèi)執(zhí)行,如圖3.2所示。

圖3.2?抖動(dòng)是對(duì)任務(wù)在后續(xù)迭代中執(zhí)行時(shí)間差異的度量
CompactRIO能夠限制抖動(dòng)量,這可能是關(guān)鍵任務(wù)應(yīng)用程序的要求。在設(shè)計(jì)具有一個(gè)或多個(gè)進(jìn)程的確定性應(yīng)用程序時(shí),可以從兩個(gè)選項(xiàng)中進(jìn)行選擇,這些進(jìn)程需要對(duì)抖動(dòng)量進(jìn)行硬性限制:
1.使用LabVIEW?FPGA實(shí)現(xiàn)關(guān)鍵任務(wù)——由于LabVIEWFPGA代碼運(yùn)行在硬件中而不是在操作系統(tǒng)中,因此可以保證關(guān)鍵任務(wù)不會(huì)崩潰或掛起。RTOS比通用操作系統(tǒng)更具確定性和可靠性,但如果編程不正確,它仍然容易導(dǎo)致軟件崩潰。
2.在LabVIEW?Real?-?Time中使用定時(shí)循環(huán)實(shí)現(xiàn)關(guān)鍵任務(wù)——比While循環(huán)稍微復(fù)雜一點(diǎn),定時(shí)循環(huán)旨在以最小的抖動(dòng)執(zhí)行確定性任務(wù)。
下一節(jié)描述使用定時(shí)循環(huán)和VI優(yōu)先級(jí)實(shí)現(xiàn)確定性流程。如果應(yīng)用程序不包含任何需要有界抖動(dòng)的任務(wù),請(qǐng)使用定時(shí)函數(shù)While?Loops而不是Timed?Loops。定時(shí)循環(huán)提供了許多有用的內(nèi)置功能,但也比While循環(huán)涉及更多的開銷和復(fù)雜性。在不使用定時(shí)循環(huán)的情況下,您可以從RTOS的可靠性中獲益,但您不能對(duì)抖動(dòng)進(jìn)行限制或最小化抖動(dòng)。
實(shí)現(xiàn)確定性流程
第1章討論了設(shè)計(jì)CompactRIO應(yīng)用程序的一種方法——分離任務(wù)并將它們識(shí)別為進(jìn)程(循環(huán))。應(yīng)用程序可能由確定性和非確定性任務(wù)組成。確定性進(jìn)程每次都必須按時(shí)完成,因此需要專用的處理器資源來(lái)確保及時(shí)完成。將確定性任務(wù)與所有其他任務(wù)分開,以確保它們接收到足夠的處理器資源。例如,如果控制應(yīng)用程序定期獲取數(shù)據(jù)并將數(shù)據(jù)存儲(chǔ)在磁盤上,則可能需要確定地處理數(shù)據(jù)獲取的時(shí)間和控制。然而,在磁盤上存儲(chǔ)數(shù)據(jù)本質(zhì)上是一個(gè)不確定的任務(wù),因?yàn)槲募蘒/O操作具有不可預(yù)測(cè)的響應(yīng)時(shí)間,這取決于硬件和硬件資源的可用性。因此,希望為數(shù)據(jù)采集任務(wù)使用定時(shí)循環(huán),為數(shù)據(jù)記錄使用While循環(huán)。While循環(huán)應(yīng)該用于不確定的任務(wù)或無(wú)界代碼(文件I/O、網(wǎng)絡(luò)通信等)。
表3.1包括確定性和非確定性任務(wù)例子。

設(shè)置確定性任務(wù)的優(yōu)先級(jí)
如果編程正確,RTOS可以保證程序以一致的定時(shí)運(yùn)行。RTOSs通過向程序員提供對(duì)任務(wù)優(yōu)先級(jí)的高度控制以及確保重要的截止日期被滿足的能力來(lái)做到這一點(diǎn)??梢酝ㄟ^使用定時(shí)循環(huán)或設(shè)置子VI的優(yōu)先級(jí)來(lái)設(shè)置LabVIEW實(shí)時(shí)任務(wù)的優(yōu)先級(jí)。如果出于可讀性的考慮,在設(shè)置優(yōu)先級(jí)時(shí),通常最好使用定時(shí)循環(huán)。對(duì)于定時(shí)循環(huán),優(yōu)先級(jí)被標(biāo)注在框圖上供任何開發(fā)人員查看,而子VI的優(yōu)先級(jí)僅在VI屬性對(duì)話框中顯示。
定時(shí)循環(huán)
定時(shí)循環(huán)類似于While循環(huán),但包含了用于確定地執(zhí)行代碼的附加特性。使用定時(shí)循環(huán),可以指定代碼執(zhí)行的周期和優(yōu)先級(jí)。一個(gè)定時(shí)循環(huán)的優(yōu)先級(jí)越高,該結(jié)構(gòu)相對(duì)于框圖上的其他定時(shí)結(jié)構(gòu)的優(yōu)先級(jí)就越高。框圖上具有最高優(yōu)先級(jí)的定時(shí)循環(huán)被稱為時(shí)間關(guān)鍵循環(huán)。可以在框圖上動(dòng)態(tài)配置優(yōu)先級(jí)和周期,也可以通過雙擊Timed?Loop上的左側(cè)輸入節(jié)點(diǎn)時(shí)啟動(dòng)的配置窗口動(dòng)態(tài)配置。

圖3.3?通過定時(shí)循環(huán)配置對(duì)話框可以指定定時(shí)循環(huán)的周期和優(yōu)先級(jí)。
在RTOS上使用定時(shí)循環(huán)時(shí),定時(shí)是很重要的。當(dāng)調(diào)用時(shí)間關(guān)鍵型循環(huán)時(shí),它是框圖上唯一執(zhí)行的循環(huán)。如果將時(shí)間關(guān)鍵型循環(huán)設(shè)置為100%的時(shí)間運(yùn)行并且從不進(jìn)入睡眠狀態(tài),那么它將完全壟斷系統(tǒng)的一個(gè)核心。一定要為時(shí)間關(guān)鍵循環(huán)指定一個(gè)合理的周期,但允許應(yīng)用程序中的其他后臺(tái)任務(wù)執(zhí)行。
防止不良計(jì)時(shí)行為的一種方法是為應(yīng)用程序創(chuàng)建時(shí)間預(yù)算。時(shí)間預(yù)算包括確定在應(yīng)用程序中執(zhí)行每個(gè)循環(huán)所需的時(shí)間量,并相應(yīng)地設(shè)置循環(huán)的速率。時(shí)間預(yù)算應(yīng)該限制應(yīng)用程序使用不超過80%的可用CPU。
VI優(yōu)先級(jí)
還可以設(shè)置代碼的確定性部分的優(yōu)先級(jí),將其放置在子VI中,并通過VI屬性對(duì)話框修改VI優(yōu)先級(jí),如圖3.4所示。

圖3.4。通過“執(zhí)行”類別下的“VI屬性”對(duì)話框指定VI的優(yōu)先級(jí)。
盡量避免在同一個(gè)應(yīng)用程序中使用定時(shí)循環(huán)和VI優(yōu)先級(jí)。如果必須使用兩者,應(yīng)該對(duì)它們之間的關(guān)系有一個(gè)清晰的理解。如果VI的優(yōu)先級(jí)中包含了具有優(yōu)先級(jí)的定時(shí)循環(huán),則定時(shí)循環(huán)將忽略該VI的優(yōu)先級(jí)。與圖3.4所示的VI優(yōu)先級(jí)相比,Timed?Loops的執(zhí)行優(yōu)先級(jí)略低于時(shí)間關(guān)鍵優(yōu)先級(jí)(最高),略高于具有高優(yōu)先級(jí)的VI。具有時(shí)間關(guān)鍵優(yōu)先級(jí)設(shè)置的VIs優(yōu)先于定時(shí)循環(huán)。While循環(huán)以正常優(yōu)先級(jí)執(zhí)行。
為了理解LabVIEW是如何基于優(yōu)先級(jí)調(diào)度并行任務(wù)的,圖3.5總結(jié)了可用的優(yōu)先級(jí)和執(zhí)行系統(tǒng)。執(zhí)行系統(tǒng)是一個(gè)相關(guān)線程池。更多信息可以在LabVIEW實(shí)時(shí)幫助文檔中找到,了解基于優(yōu)先級(jí)的調(diào)度模型。

圖3.5?LabVIEW實(shí)時(shí)中可用的優(yōu)先級(jí)和執(zhí)行系統(tǒng)
用子VI創(chuàng)建模塊化代碼
根據(jù)定義,模塊化意味著使用模塊或較小的部分來(lái)實(shí)現(xiàn)總體目標(biāo)。在LabVIEW中,程序模塊化意味著創(chuàng)建被稱為子VI的更小的代碼段。子VI與VI相同。它們包含前面板和方框圖,但可以在VI中調(diào)用它們。子VI類似于基于文本的編程語(yǔ)言中的子程序。渦輪測(cè)試實(shí)時(shí)VI使用圖3.6所示的子VI來(lái)計(jì)算一次從DMA?FIFO讀取多少元素以避免緩沖區(qū)溢出或下溢情況。這個(gè)子VI從數(shù)據(jù)采集和分析循環(huán)中調(diào)用。

圖3.6?通過創(chuàng)建子VI來(lái)創(chuàng)建模塊化代碼
進(jìn)程間數(shù)據(jù)通信
在設(shè)計(jì)嵌入式應(yīng)用程序時(shí)要考慮的最重要的因素之一是數(shù)據(jù)通信。本節(jié)將討論第1章中討論的用于實(shí)時(shí)目標(biāo)上的進(jìn)程間通信的每種數(shù)據(jù)通信模型的推薦數(shù)據(jù)傳輸機(jī)制。表3.2給出了每種通信模型的推薦數(shù)據(jù)通信機(jī)制。推薦用于兩個(gè)不確定性循環(huán)之間的數(shù)據(jù)傳輸?shù)臄?shù)據(jù)通信機(jī)制,通常比用于涉及時(shí)間關(guān)鍵型或確定性循環(huán)的數(shù)據(jù)傳輸?shù)耐扑]機(jī)制更靈活。
表3.2?每種通信模型的推薦進(jìn)程間數(shù)據(jù)通信機(jī)制

請(qǐng)注意,在選擇數(shù)據(jù)通信機(jī)制時(shí),傳輸類型只是考慮因素之一??赡苡惺褂没诿畹臋C(jī)制實(shí)現(xiàn)更新的有效用例,反之亦然,這取決于前面提到的其他考慮因素,如易于實(shí)現(xiàn)、可靈活性或性能。下一節(jié)提供了在LabVIEW?Real-Time中實(shí)現(xiàn)每種通信模型的最佳實(shí)踐。
單進(jìn)程共享變量
共享變量是指可以在框圖中無(wú)法通過網(wǎng)線連接的兩個(gè)位置之間、運(yùn)行在實(shí)時(shí)目標(biāo)上的兩個(gè)VIs之間或運(yùn)行在不同目標(biāo)上的兩個(gè)VIs之間,跨網(wǎng)絡(luò)發(fā)送數(shù)據(jù)的配置軟件項(xiàng)。使用單進(jìn)程共享變量共享實(shí)時(shí)目標(biāo)上的當(dāng)前值數(shù)據(jù)或標(biāo)簽,并使用網(wǎng)絡(luò)發(fā)布的共享變量在不同目標(biāo)上的VIs之間共享數(shù)據(jù)。單進(jìn)程共享變量在底層被實(shí)現(xiàn)為全局變量。

圖3.7?使用單進(jìn)程共享變量在多個(gè)進(jìn)程之間進(jìn)行變量通信。
要?jiǎng)?chuàng)建單進(jìn)程共享變量,請(qǐng)?jiān)赑roject?Explorer窗口中右鍵單擊實(shí)時(shí)目標(biāo),并從快捷菜單中選擇New?variable。在“共享變量屬性”對(duì)話框中,可以將變量類型設(shè)置為“單進(jìn)程”(單進(jìn)程共享變量是全局變量)。

圖3.8?每種通信模型的推薦進(jìn)程間數(shù)據(jù)通信機(jī)制
如果應(yīng)用程序包含相對(duì)大量的變量,并且需要?jiǎng)討B(tài)標(biāo)記查找等標(biāo)記管理特性,則應(yīng)該考慮下面描述的當(dāng)前值表,它旨在有效地處理大量標(biāo)記。
由于單進(jìn)程共享變量基于全局變量,因此它們充當(dāng)共享資源,如果在時(shí)間關(guān)鍵型循環(huán)中使用,可能會(huì)引入抖動(dòng)。如果對(duì)在時(shí)間關(guān)鍵型循環(huán)中使用單進(jìn)程共享變量感興趣,請(qǐng)確保在變量屬性對(duì)話框中啟用RT?FIFO。啟用了RT?FIFO的單進(jìn)程共享變量將在下一節(jié)RT?FIFO中討論。????
?
需要說明的是,上述的例程和文檔,都是可以下載的,雙擊即可打開,其中壓縮文件是可以采用粘貼復(fù)制的方式,拷貝到硬盤上。這不是圖片,各位小伙伴看到后嘗試一下,這個(gè)問題就不用加微信咨詢了。有關(guān)LabVIEW編程、LabVIEW開發(fā)等相關(guān)項(xiàng)目,可聯(lián)系們。附件中的資料這里無(wú)法上傳,可去公司網(wǎng)站搜索下載。