• 招生咨詢熱線:4008-569-579 
  • 手機版
    用手機掃描二維碼直達商品手機版
招生咨詢熱線
4008-569-579
機構(gòu)主頁 > 培訓資料 > 嵌入式開發(fā):設(shè)計嵌入式軟件架構(gòu)的5個步驟——步驟4
機構(gòu)主頁 > 培訓資料>嵌入式開發(fā):設(shè)計嵌入式軟件架構(gòu)的5個步驟——步驟4

嵌入式開發(fā):設(shè)計嵌入式軟件架構(gòu)的5個步驟——步驟4

來源:廣州達內(nèi)教育        時間:2023-05-30        熱度:64℃        返回列表

本文探討了嵌入式開發(fā)設(shè)計嵌入式軟件架構(gòu)的第四步——接口和組件設(shè)計。

 

在上一篇文章中,我們探討了如何將一個系統(tǒng)分解成域和任務(wù),我們已經(jīng)確定了該系統(tǒng)的數(shù)據(jù)資產(chǎn)。你可能還記得,我們創(chuàng)建的上一張圖將我們的應用程序分為安全和非安全應用程序域、硬件獨立和依賴域(由抽象層分隔),最后分為任務(wù)。我們的系統(tǒng)分解如圖1所示。

 

 

由于blog格式的空間和時間限制,我們建議在描述如何讓任務(wù)進行交互的架構(gòu)過程中增加額外的步驟。我們想探索如何完成我們的一項任務(wù),并設(shè)計我們的界面和組件。讓我們看看如何為電機任務(wù)定義組件及其接口。

 

步驟4–接口和組件設(shè)計

組件和界面設(shè)計是密切相關(guān)的活動。事實上,如果我們查看組件的標準定義,我們會發(fā)現(xiàn)以下描述:

軟件組件是一個組合單元,具有合同規(guī)定的接口和明確的上下文依賴關(guān)系。

我們甚至不能在不討論接口的情況下定義組件!接口是軟件開發(fā)人員用來與組件交互的工具。因此,我們開始將我們的運動任務(wù)分解為組件是有意義的,然后我們可以為每個組件定義接口。

 

定義軟件組件

嵌入式開發(fā)人員可以使用許多不同的方法和技術(shù)來識別將堆疊在一起以執(zhí)行任務(wù)提供的期望行為的組件。我對幾乎任何任務(wù)的偏好都是將系統(tǒng)分解成一個分層的軟件圖,從底層驅(qū)動程序開始,一直到應用程序代碼。圖2顯示了一個示例,顯示了電機任務(wù)的這種圖。

 

這些組件的用途可能是不言自明的,但為了以防萬一,讓我定義一下每個組件的作用

pwm_drv 微控制器上用于脈寬調(diào)制的硬件外設(shè)驅(qū)動器。

Abstraction layer 打破電機驅(qū)動器和硬件之間的依賴關(guān)系。這允許我們使用PWM驅(qū)動器來驅(qū)動電機,或者用外部集成電路的驅(qū)動器來代替pwm_drv

motor_drv 設(shè)計用于控制電機的驅(qū)動器。它沒有硬件依賴性。它唯一的依賴是抽象層。

motor_sm 跟蹤電機當前狀態(tài)和所需狀態(tài)的狀態(tài)機。

motor_app 特定應用支持功能。這些功能可能包括收集遙測數(shù)據(jù)、檢查故障等。

motor_task 保存實際電機任務(wù)代碼的組件。該元件依賴于其他電機元件。電機任務(wù)可能包括RTOS應用程序交互,如信號量、隊列、互斥和事件邏輯。

 

總之,這些組件具有接收命令的所有必要行為,該命令改變控制電機的狀態(tài)機,然后啟動電機。這種分解很酷的一點是,如果電機控制鏈的各個方面發(fā)生變化,比如新的驅(qū)動芯片、新的應用程序需求等,有了適當?shù)慕涌冢?span>嵌入式開發(fā)人員只需要進行最小的更改。

 

定義接口

對于motor任務(wù),我們需要定義兩類接口。首先,有一個任務(wù)接口,它接收來自其他應用程序組件的命令,告訴它電機應該做什么,比如MOTOR_ONMOTOR_OFF。其次,每個組件都有接口。

 

電機任務(wù)接口設(shè)計

在定義與電機任務(wù)通信的接口時,回顧圖1中所示的數(shù)據(jù)資產(chǎn)是很有幫助的。我們可以看到控制器任務(wù)與電機任務(wù)交互。為了讓控制器任務(wù)告訴電機任務(wù)電機應該做什么,需要幾條信息:電機狀態(tài)、電機方向、電機轉(zhuǎn)速。

 

如果我們希望系統(tǒng)可伸縮以管理多個電機,我們甚至可以包括一個電機ID。例如,在有些應用中,狀態(tài)機通過消息控制電機,但用戶可以用消息覆蓋狀態(tài)。在這些情況下,我們甚至可能希望包含一個任務(wù)ID,以便電機任務(wù)知道哪個任務(wù)正在請求電機控制。

 

從數(shù)據(jù)接口的角度來看,嵌入式開發(fā)人員可以為數(shù)據(jù)定義一個結(jié)構(gòu),該結(jié)構(gòu)將用于控制和電機任務(wù)的接口。用C語言編寫如下代碼

 

MotorMessage_t結(jié)構(gòu)定義了命令電機任務(wù)執(zhí)行實際工作所需的數(shù)據(jù)接口。我們?nèi)绾潍@得機動任務(wù)的信息取決于項目的需求。例如,使用消息隊列、數(shù)據(jù)緩沖區(qū)或其他機制。然而,這些細節(jié)是由程序員決定的,而不是軟件架構(gòu)師。

 

定義組件接口

有幾種不同的方法來為我們的組件設(shè)計界面。首先,我們可以做一個便簽,列出我們認為需要的功能。接下來,我們可以使用一些UML圖表工具并利用類圖,即使我們沒有編寫面向?qū)ο蟮拇a。最后,我們可以直接進入代碼,開始編寫測試,迫使我們?yōu)榻M件的行為開發(fā)接口。

 

類圖很棒,因為它們允許嵌入式開發(fā)人員指定屬性、操作和類之間的關(guān)系(模塊和組件也可以)。有幾件事我們應該注意。首先,電機任務(wù)使用電機應用程序、電機狀態(tài)機和電機驅(qū)動器。這里沒有繼承關(guān)系。我們可以看到電機驅(qū)動器有一個電機接口。motor應用程序使用MotorError_t枚舉,但除此之外,組件是解耦的,不進行交互。

 

接下來,我們定義了我們認為的操作是什么,以及組件需要的功能或方法。例如,我們可以看到電機驅(qū)動器有兩個功能電機初始化和電機命令。電機命令采用電機消息類型和所有信息來命令電機,這是通過電機接口(抽象層)完成的。

 

當我們查看類圖時,我們可以看到電機任務(wù)與底層組件進行交互,并驅(qū)動電機的最終行為。首先,信息通過MotorQ進入電機任務(wù);然后,電機任務(wù)運行電機狀態(tài)機。最后,電機任務(wù)調(diào)用電機應用程序查找錯誤,并使用狀態(tài)結(jié)果通過電機驅(qū)動器命令電機。從一個可能并不明顯的類圖中可以得出很多東西。那么,我們的架構(gòu)是否遺漏了什么?

 

我們的設(shè)計缺少了什么?

我們可能有足夠的資源來開始實現(xiàn)電機應用程序代碼;然而,更多的圖表和時間可以極大地提高清晰度。例如,嵌入式開發(fā)人員可以考慮額外的UML圖,比如序列圖,來顯示控制任務(wù)與電機任務(wù)交互的時序要求。或是創(chuàng)建一個序列圖,以便開發(fā)人員了解電機任務(wù)如何與其他組件交互。比如電機任務(wù)是應該在任務(wù)結(jié)束的時候命令電機,還是先做,把抖動降到最低?如果出現(xiàn)錯誤,處理的邏輯是什么?電機應該保持運轉(zhuǎn)還是停止運轉(zhuǎn)?

 

通常會發(fā)現(xiàn),至少需要三到四個UML圖來完整地指定一項任務(wù),以便開發(fā)人員可以對其進行編碼。我們只看了幾個,這意味著還有更多的事情要做。我們可以開始開發(fā)測試,并使用測試驅(qū)動的開發(fā)來進一步發(fā)展我們的界面和對系統(tǒng)的理解。這可能是目前的發(fā)展方向。但是,我們知道的足夠多,隨著我們實現(xiàn)細節(jié),問題將會出現(xiàn),這將推動對初始架構(gòu)的更改。

 

軟件架構(gòu)設(shè)計第4步結(jié)論

正如本文所見,我們可以利用UML圖和組件堆疊圖來識別組件并定義它們的接口。此外,類圖可以成為設(shè)計師進行界面設(shè)計的優(yōu)秀工具。嵌入式開發(fā)人員必須記住,雖然我們遵循一個簡單的五步過程來開發(fā)我們的架構(gòu),但這些步驟只是一個指南,而不是全部。作為架構(gòu)師,我們經(jīng)常需要更深入。

電話咨詢

電話咨詢

咨詢電話:
4008-569-579
回到頂部

回到頂部