當(dāng)前位置:首頁 > 嵌入式 > 嵌入式分享
[導(dǎo)讀]大多數(shù)嵌入式系統(tǒng)本質(zhì)上是被動(dòng)的。他們用傳感器測量環(huán)境的某些特性,并對變化作出反應(yīng)。例如,它們顯示某些東西,移動(dòng)一個(gè)馬達(dá),或向另一個(gè)系統(tǒng)發(fā)送通知。一個(gè)反應(yīng)系統(tǒng)最好由一個(gè)狀態(tài)機(jī)來表示--一個(gè)系統(tǒng)總是在一個(gè)有限的和定義明確的可能狀態(tài)集中。

大多數(shù)嵌入式系統(tǒng)本質(zhì)上是被動(dòng)的。他們用傳感器測量環(huán)境的某些特性,并對變化作出反應(yīng)。例如,它們顯示某些東西,移動(dòng)一個(gè)馬達(dá),或向另一個(gè)系統(tǒng)發(fā)送通知。一個(gè)反應(yīng)系統(tǒng)最好由一個(gè)狀態(tài)機(jī)來表示--一個(gè)系統(tǒng)總是在一個(gè)有限的和定義明確的可能狀態(tài)集中。

手動(dòng)編程有限狀態(tài)機(jī)可以成為壓倒性的任務(wù),并產(chǎn)生錯(cuò)綜復(fù)雜且難以維護(hù)的結(jié)果。圖形化設(shè)計(jì)工具幫助您跟蹤系統(tǒng)的所有可能狀態(tài)和動(dòng)作。本文將為您介紹一個(gè)狀態(tài)機(jī)編程,重點(diǎn)是圖形化設(shè)計(jì)工具。此外,您將學(xué)習(xí)如何將生成的平臺無關(guān)代碼與自定義硬件專用代碼集成,以便與硬件進(jìn)行交互--在本例中,這是一個(gè)Arduno板。

狀態(tài)機(jī)是開發(fā)反應(yīng)系統(tǒng)的理想范例。這些反應(yīng)系統(tǒng)最重要的特點(diǎn)是,它們使用傳感器和執(zhí)行器與環(huán)境相互作用。傳感器的例子是運(yùn)動(dòng)、亮度或溫度傳感器。常見的執(zhí)行機(jī)構(gòu)包括LED、顯示器、閥門和電動(dòng)機(jī)。這些系統(tǒng)的另一個(gè)重要特點(diǎn)是,它們有一個(gè)有限的可能狀態(tài)集,而且它們總是在其中之一,使用狀態(tài)機(jī)可以很容易地實(shí)現(xiàn)。

對于具有實(shí)際意義的狀態(tài)機(jī)來說,可能最簡單的例子是光開關(guān)控制,如圖1所示。不出所料,兩個(gè)進(jìn)程中只有一個(gè)進(jìn)程可以同時(shí)活動(dòng)。當(dāng)一個(gè)所謂的進(jìn)程 過渡 已經(jīng)帶走了。在這個(gè)例子中,這種情況發(fā)生在 按按鈕的 事件就會發(fā)生。

圖1光開關(guān)控制的兩種狀態(tài)和過渡.(資料來源:項(xiàng)目組)

畫出你的系統(tǒng)的所有狀態(tài)可以幫助你提前計(jì)劃,并清楚地看到你的系統(tǒng)在不同情況下的預(yù)期行為。然后,您可以使用該圖表作為藍(lán)圖,以基礎(chǔ)源代碼和測試。然而,如果以后改變代碼,就像通常情況下的情況一樣,而圖表沒有改變,則兩者都有分歧。如果有人試圖根據(jù)現(xiàn)在已經(jīng)過時(shí)的圖表開發(fā)測試,那么他們就會失敗。如果模型僅僅用于規(guī)范或文檔,它就會成為一個(gè)巨大的問題。因此,圖表不應(yīng)該只是代碼的藍(lán)圖,它應(yīng)該是 成為 密碼。

如果您已經(jīng)繪制了圖表,為什么要自己編寫代碼?所有需要的邏輯已經(jīng)在圖表中指定.將圖表轉(zhuǎn)換為等效的源代碼,比如java或c,只是一個(gè)機(jī)械任務(wù),可以由機(jī)器執(zhí)行。使用圖表作為唯一的真相源并自動(dòng)生成代碼,被稱為模型驅(qū)動(dòng)方法。然而,要利用這一原則,簡單的繪圖板是做不到的。

相反,你應(yīng)該使用適當(dāng)?shù)慕9ぞ呃L制狀態(tài)圖(狀態(tài)圖)。用這種工具創(chuàng)建的圖表很容易掌握。它們改善了軟件開發(fā)人員和領(lǐng)域?qū)<抑g的溝通。此外,與紙張上的圖表或繪圖應(yīng)用程序中的圖表不同,建模工具對狀態(tài)機(jī)是什么有正式的理解。這使他們(和你)能夠模擬和測試他們的行為--甚至不編寫一行代碼。模型本身是獨(dú)立于平臺的,因此您可以從它們生成任何您喜歡的語言中的源代碼。工具通常支持C,C++,Java,和比頓。

如果您仍然不確定模型驅(qū)動(dòng)的軟件開發(fā)是如何工作的,請不要擔(dān)心--我們現(xiàn)在將通過實(shí)例來探索它。我們將使用標(biāo)桿和代碼生成來開發(fā)一個(gè)非常簡單的自動(dòng)化光,只需要一些輸入和輸出。

我們的例子:自動(dòng)和動(dòng)作激活燈

自動(dòng)照明的任務(wù)相當(dāng)簡單:只有在黑暗的時(shí)候才應(yīng)該有光,但是它不應(yīng)該浪費(fèi)能量,而實(shí)際上沒有人在周圍。為了實(shí)現(xiàn)這一點(diǎn),大多數(shù)樓梯燈都是由定時(shí)器控制的。按下按鈕,燈就會被激活,在一段時(shí)間后,它會自動(dòng)關(guān)閉。然而,作為一個(gè)狀態(tài)示例,這將是相當(dāng)乏味的,因此本文通過加入一個(gè)由運(yùn)動(dòng)傳感器驅(qū)動(dòng)的附加模式,使其更加有趣。

光線應(yīng)該有三種可能的操作方式:

· 永久地離開

· 有時(shí)間控制的關(guān)閉

· 自動(dòng)帶有運(yùn)動(dòng)傳感器

一個(gè)按鈕允許用戶循環(huán)這些模式.兩個(gè)LED顯示當(dāng)前選定的操作模式。

通過這些規(guī)范,您可以很容易地推導(dǎo)出狀態(tài)機(jī)的基本結(jié)構(gòu),如圖2所示:

圖2自動(dòng)和動(dòng)作激活燈。

在這兩者之間的變化 離開 , 計(jì)時(shí)器 和 自動(dòng)動(dòng)作 進(jìn)程是由 事件-或者按下按鈕,或者在計(jì)時(shí)器過期后。如果用戶按一次按鈕,計(jì)時(shí)器模式被激活,燈就會打開,30秒后自動(dòng)關(guān)閉。如果用戶在30秒運(yùn)行完畢前再次按下按鈕,則激活運(yùn)動(dòng)傳感器模式。當(dāng)運(yùn)動(dòng)傳感器檢測到某人(或某物)在移動(dòng)時(shí),如果需要的話,燈就會被打開30秒。每次檢測到某一動(dòng)作時(shí),計(jì)時(shí)器都會重置.表明當(dāng)前模式的兩個(gè)發(fā)光二極管在進(jìn)入或離開各自的狀態(tài)時(shí)按需要被激活和停用。這樣,整個(gè)控制器邏輯完全封裝在狀態(tài)機(jī)中,也稱為自動(dòng)機(jī)。

如果自動(dòng)機(jī)是要運(yùn)行在一個(gè)嵌入式系統(tǒng),我們現(xiàn)在可以直接從圖表生成C或C++代碼。生成的代碼包含來自模型的所有邏輯。只需要手動(dòng)編寫與實(shí)際硬件接口的代碼。在這個(gè)例子中,這包括提高 按鈕 當(dāng)實(shí)際按鈕按下時(shí),控制實(shí)際的樓梯燈,控制狀態(tài)LED。這種手動(dòng)編程是需要的,因?yàn)樯傻拇a與目標(biāo)平臺無關(guān)。計(jì)時(shí)器也是如此--在不同的目標(biāo)平臺上,時(shí)間處理方式非常不同。

實(shí)現(xiàn)狀態(tài)機(jī)有許多可能的方法.最常使用的方法是狀態(tài)表、基于開關(guān)的案例構(gòu)造或狀態(tài)模式--通常在面向?qū)ο缶幊陶Z言中使用。如果你想更深入地了解這個(gè)話題,你可以找到一個(gè)廣泛的比較.在默認(rèn)情況下,雅辛杜狀態(tài)工具使用開關(guān)案例語句生成狀態(tài)機(jī)代碼。這確保了良好的性能,同時(shí)也保持了源代碼的良好可讀性。

生成的代碼是如何工作的

如上所述,狀態(tài)機(jī)代碼是作為開關(guān)案例語句實(shí)現(xiàn)的。執(zhí)行的主要部分將在 循環(huán)車 職能:

void Lightswitch::runCycle()

{

clearOutEvents();

for (stateConfVectorPosition = 0;

stateConfVectorPosition < maxOrthogonalStates;

stateConfVectorPosition++)

{

switch (stateConfVector[stateConfVectorPosition])

{

case lightswitch_Off :

{

lightswitch_Off_react(true);

break;

}

case lightswitch_Timer :

{

lightswitch_Timer_react(true);

break;

}

case lightswitch_Motion_Automatic_motion_Motion :

{

lightswitch_Motion_Automatic_motion_Motion_react(true);

break;

}

case lightswitch_Motion_Automatic_motion_No_Motion :

{

lightswitch_Motion_Automatic_motion_No_Motion_react(true);

break;

}

default:

break;

}

}

clearInEvents();

}

… 循環(huán)車 每當(dāng)出現(xiàn)事件時(shí),就會調(diào)用功能.它迭代所有正交的狀態(tài)來做任何要做的事情。開關(guān)案例語句決定調(diào)用哪個(gè)函數(shù)來執(zhí)行相應(yīng)的狀態(tài)反應(yīng)。例如,離開狀態(tài)有一個(gè)輸入反應(yīng),將輕變量設(shè)置為假,只在進(jìn)入狀態(tài)時(shí)執(zhí)行。它有一個(gè)向外和一個(gè)向外過渡。如果 按鈕 事件發(fā)生后,進(jìn)程將退出。這種行為在 lightswitch_Off_react 職能:

sc_boolean Lightswitch::lightswitch_Off_react(const sc_boolean try_transition) {

/* The reactions of state Off. */

sc_boolean did_transition = try_transition;

if (try_transition)

{

if (iface.button_raised)

{

exseq_lightswitch_Off();

enseq_lightswitch_Timer_default();

react();

} else

{

did_transition = false;

}

}

if ((did_transition) == (false))

{

did_transition = react();

}

return did_transition;

}

所以,假設(shè)說退出狀態(tài)已經(jīng)進(jìn)入了。每次 循環(huán)車 函數(shù)被調(diào)用,它必須檢查按鈕事件是否被提升。在 lightswitch_Off_react 職能。如果 按鈕 事件的確發(fā)生了,必須做兩件事: 出口 當(dāng)前狀態(tài)的順序和執(zhí)行 加入 目標(biāo)狀態(tài)的順序:

if (iface.button_raised)

{

exseq_lightswitch_Off();

enseq_lightswitch_Timer_default();

react();

}

關(guān)于一個(gè)Arduino聯(lián)合國組織的實(shí)施

圖3Arduino原理圖。

圖3顯示了一個(gè)ArduinoUNO實(shí)現(xiàn)的示意圖。實(shí)際的樓梯燈是象征著機(jī)上的LED,以保持電路簡單。這兩個(gè)顯示模式的發(fā)光二極管連接到針9和10,運(yùn)動(dòng)傳感器到針7。如果需要,這些密碼可以更改。按鈕必須連接到銷2或銷3,因?yàn)橹挥羞@些才能觸發(fā)中斷。LED系列的電阻為220歐,按鈕連接到22kc拉下電阻。

該軟件由兩個(gè)核心組件組成:由狀態(tài)生成的C++代碼和用于連接非平板獨(dú)立狀態(tài)機(jī)邏輯和硬件的手寫膠水代碼。

代碼生成器根據(jù)模型中定義的事件和變量創(chuàng)建狀態(tài)機(jī)的接口:空升-按鈕();空升-運(yùn)動(dòng)();SCOOLOL-光();SCOST;SCOL-運(yùn)動(dòng)();CXOOL-運(yùn)動(dòng)();SXOOL-內(nèi)();球形進(jìn)入();

對于接口狀態(tài)機(jī),必須定義特定狀態(tài)機(jī)類型的對象,這里:光開關(guān)。這個(gè)對象代表實(shí)際的狀態(tài)機(jī),可以用編程方式與實(shí)際的狀態(tài)機(jī)進(jìn)行交互。例如:

光開關(guān);

Lightswitch lightswitch;

int main(){

lightswitch.init();

lightswitch.enter();

lightswitch.raise_button();

}

有了這個(gè)簡單的實(shí)現(xiàn),光開關(guān)狀態(tài)機(jī)將被初始化,輸入,按鈕事件將被提升。當(dāng)然,這不是辦法。目標(biāo)是連接硬件(在這種情況下,阿爾杜伊諾與連接的LED,傳感器和按鈕)到狀態(tài)機(jī)。為此,我們將在一個(gè)非常簡單的輸入過程輸出模式中使用狀態(tài)機(jī)。這是一個(gè)簡單的循環(huán):

· 檢查硬件和傳感器是否有變化

· 把這些信息轉(zhuǎn)移到進(jìn)程機(jī)器的輸入中

· 讓狀態(tài)機(jī)處理這些輸入

· 檢查狀態(tài)機(jī)的輸出并對其作出反應(yīng)。

最初,計(jì)時(shí)器用當(dāng)前時(shí)間刷新。在阿杜伊諾號上,我們使用 米利斯 函數(shù),以獲得系統(tǒng)啟動(dòng)以來所經(jīng)過的毫秒數(shù)。如果需要,計(jì)時(shí)器將觸發(fā)狀態(tài)機(jī)中的時(shí)間事件。

long now = millis();

if(now - time_ms > 0) {

timerInterface->proceed(now - time_ms);

time_ms = millis();

}

基于其他輸入,如按鈕按或運(yùn)動(dòng)檢測,我們可以提高狀態(tài)機(jī)的"在"事件。這里,我們不必?fù)?dān)心狀態(tài)機(jī)當(dāng)前的模式--生成的狀態(tài)機(jī)代碼封裝了所有的邏輯。我們只是提出事件,然后讓進(jìn)程機(jī)器決定它是否要對它作出反應(yīng)。

// handle button press from ISR

if(buttonPressed) {

lightswitch.raise_button();

buttonPressed = false;

}

// read out motion sensor

if(digitalRead(7)) {

lightswitch.raise_motion();

}

在處理了所有"內(nèi)"事件之后,狀態(tài)機(jī)已經(jīng)正確地設(shè)置了布爾變量。我們可以用它們來控制"樓梯燈"和指示燈。

// set light

digitalWrite(13, lightswitch.get_light());

// set mode LEDs

digitalWrite(9, lightswitch.get_led_timer());

digitalWrite(10, lightswitch.get_led_motion());

最后,我們將把阿杜伊諾放到睡眠模式中,如果它是在 離開 為了省點(diǎn)體力。如果用戶按下這個(gè)按鈕,它的中斷服務(wù)例程將被調(diào)用,并且Arduno再次醒來。請注意更新 米利斯 在睡眠狀態(tài)下沒有更新。依靠軟件計(jì)時(shí)器 米利斯 因此在睡眠狀態(tài)下不會更新。在這個(gè)例子中,沒有計(jì)時(shí)器運(yùn)行 離開 狀態(tài)是活躍的,所以我們可以安然入睡。

// if in Off-state, go to sleep (wake up by ISR)

if(lightswitch.isStateActive(Lightswitch::lightswitch_Off)) {

enterSleep();

}

閃爍的阿杜伊諾是完成了通常的阿杜伊諾。為此,我們導(dǎo)入了將狀態(tài)機(jī)作為庫的項(xiàng)目,并只手動(dòng)編寫上面的ArduinnoIDI中所示的與Arduino相關(guān)的代碼。

結(jié)論

這個(gè)例子清楚地顯示了在軟件開發(fā)中使用模型的優(yōu)點(diǎn),比如說使用標(biāo)桿。主要優(yōu)勢是:

· 狀態(tài)機(jī)是正式的,可以執(zhí)行.

· 進(jìn)程記錄是圖形化的,易于理解。

· 設(shè)備的執(zhí)行邏輯和相關(guān)硬件相關(guān)代碼完全脫鉤。

· 解除硬件和設(shè)備邏輯的連接提高了可移植性,減少了更改或進(jìn)一步版本所需的努力。

· 它們可以分開開發(fā)。

這個(gè)例子可以擴(kuò)展,并提供一個(gè)完美的游樂場進(jìn)行狀態(tài)機(jī)的實(shí)驗(yàn)。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉