1 本文的介紹
1.1 內(nèi)容
雖然FC的SWS 是ARA接口規(guī)范纯赎,但有些接口需要如何使用的“指南”。這份指南確實跟規(guī)范相關(guān)南蹂,但是有些是間接的犬金,并且在每個SWS中都包含這些信息,因此讀者很難理解其用法六剥。另一個重要的角度是這些指南是AA 遵守的需求晚顷,但是FC的SWS是FC的需求規(guī)范。因此疗疟,在SWS中包含這些內(nèi)容不太合適该默,這就是這本文檔的目的。
如上所述背景策彤,這份文檔的主要內(nèi)容是應(yīng)用程序遵守的指南栓袖。不是所有的FC在這份文檔中有內(nèi)匣摘。當(dāng)它認(rèn)為有效時,它們將被添加裹刮。
內(nèi)容是按照相關(guān)的話題組織的音榜,但是一般情況下,按照FC組合一起捧弃,每個都有獨立的章節(jié)赠叼。并且,請注意這些內(nèi)容提供在單獨的AUTOSAR AP 文檔中违霞。如果是這種情況嘴办,這種文檔會被列出來或引用這份指南。
1.2 預(yù)讀
這份文檔是AP SWS的補充文檔买鸽。因此涧郊,這份文檔里的話題相關(guān)的SWS應(yīng)該同步閱讀。并且癞谒,應(yīng)該閱讀的第一份文檔是Explanations of Adaptive Platform Design, AUTOSAR_EXP_PlatformDesign.pdf.底燎,這份文檔介紹了AP的架構(gòu)
1.3 和其他AUTOSAR規(guī)范的關(guān)系
參考內(nèi)容和預(yù)讀
2. 核心類型
2.1 錯誤處理
錯誤處理對任何軟件開發(fā)都是重要的話題。對于安全關(guān)鍵軟件弹砚,它更重要双仍,因為軟件生命要依靠它。但是桌吃,目前的標(biāo)準(zhǔn)對安全關(guān)鍵軟件的開發(fā)加了很多的限制朱沃,比如創(chuàng)建工具鏈,特別是關(guān)于C++異常茅诱。對ASIL應(yīng)用程序逗物,使用C++異常通常是不可能的因為缺乏對asil認(rèn)證的c++編譯器的異常支持。
Adaptive平臺介紹了一個概念使沒有C++異常的錯誤處理成為可能并定義了大量的c++數(shù)據(jù)類型來輔助這個概念瑟俭。
從應(yīng)用程序編碼者的觀點來看翎卓,核心類型實現(xiàn)這個概念的是 ara::core::ErrorCode和ara::core::Result.
2.1.1 ErrorCode
ara::core::ErrorCode的實例表示軟件內(nèi)的一個特定的錯誤條件。和std::error_code類似摆寄,但是在很多方面都不相同失暴。
ErrorCode一直包含一個枚舉值(類型擦除為整型)和一個錯誤域的引用。這個枚舉值描述了錯誤的特定類型微饥。錯誤域引用定義了錯誤應(yīng)用的上下文逗扒。其他可選的成員一個是用戶定義的消息字符串,一個是廠商定義的補充錯誤描述值欠橘。
2.1.2 Result
類ara::core::Result遵守來自C++建議 p0786中“ValueOrError”的概念矩肩。它包含一個value或一個error。由于模板特性肃续,value和error可以是任何類型黍檩。但是叉袍,錯誤類型默認(rèn)為ara::core::ErrorCode,而且希望整個Adaptive平臺都能保持這個分配刽酱。
因為ErrorType默認(rèn)為ara::core::ErrorCode畦韭,ara::core::Result的大部分聲明僅需要給一個ValueType,比如對Result類型ara::core::Result<int>包含一個int變量或一個ErrorCode.
ARA接口使用ara::core::Result作為可恢復(fù)錯誤函數(shù)的返回類型肛跌。這個類型或者用來從對象中生成C++異常,或通過未使用異常的觀察者方法中提取錯誤信息察郁。
這部分指導(dǎo)你在應(yīng)用程序代碼中如何處理從ARA接口中返回Result對象衍慎。并且指導(dǎo)你如何在自己的Adaptive應(yīng)用程序中創(chuàng)建新的Result對象。
2.1.2.1 Result的創(chuàng)建
使用嵌入值創(chuàng)建Result皮钠,有構(gòu)造函數(shù)允許從ValueType隱式轉(zhuǎn)換稳捆。這樣用value來定義Result非常直接。
Result<int> res1(42);
Result<int> res2 = 42;
從聲明返回Result的函數(shù)中返回一個value也是同樣的直接麦轰。
Result<int> myfunction()
{
return 42;
}
把error放進Result中需要調(diào)用顯示構(gòu)造函數(shù)乔夯,比如:
ErrorCode ec = MyEnum::some_error;
Result<int> res2(ec);
另外,在靜態(tài)成員函數(shù)中構(gòu)造Result對象也是可能的款侵。比如:
Result<int> res1 = Result<int>::FromValue(42);
Result<int> res2 = Result<int>::FromError(ec);
當(dāng)Value Type或ErrorType Copy 代價非常昂貴的時候末荐,這些形式是非常有益的。比如新锈,返回的Reslut包換一個BigClass的實例甲脏。這個BigClass有兩個構(gòu)造參數(shù)"a1"和"a2"構(gòu)建。像這樣:
return Result<BigClass>::FromValue(a1, a2);
對于ErrorType妹笆,也允許ErrorCode實例的隱式構(gòu)建块请,包含一個自定義錯誤消息和/或一個支持?jǐn)?shù)據(jù)值。
return Result<BigClass>::FromError(
MyEnum::some_error, // ErrorCode enum value
"this operation did not work", // custom error message
0x12345678 // support data value
);
這種形式構(gòu)建拳缠,只需要 執(zhí)行一次構(gòu)造函數(shù)墩新。不像普通的構(gòu)造函數(shù)調(diào)用,至少要執(zhí)行兩次構(gòu)造操作窟坐,因為預(yù)先創(chuàng)建的值必須copy或move到Result實例中海渊。
2.1.2.2 提取value和error
當(dāng)試圖從Result中提取value和error的時候,首先要考慮的是value或error是否真實可用狸涌。通常情況下切省,這是未知的,所以必須小心處理者兩種情況帕胆。
當(dāng)沒有使用異常工作的時候朝捆, 要先查詢Result對象是否包含value或error.
Result<int> some_function() { … }
Result<int> res = some_function();
if (res.HasValue()) {
int theValue = res.Value();
} else {
ErrorCode const& ec = res.Error();
}
這段代碼在沒有異常的環(huán)境中也可以完全工作,包括編譯器完全不支持異常操作懒豹。
當(dāng)處理異常工作流是芙盘,查詢代碼看起來更像普通的異常代碼:
Result<int> some_function() { … }
int theValue = some_function().ValueOrThrow();
由some_function()返回的Result對象通過調(diào)用它的ValueOrThrow()成員函數(shù)快速歸到它的ValueType(int)驯用。事實上,如果Result確實包含一個ErrorCode,會立刻拋出一個對應(yīng)到嵌入的ErrorCode對象的異常類型儒老。自然蝴乔,try...catch快應(yīng)該添加到代碼中一個合適的位置。
2.1.2.3 高級話題
提取嵌入的value或error兩個借本的方法是Result::Value()和Result::Error()驮樊。但是薇正,在調(diào)用任何這些函數(shù)時,必須確定Result對象確實包含調(diào)用這些函數(shù)之一所隱含的內(nèi)容囚衔。在前面的部分挖腰,首先調(diào)用Result::HasValue(), Value()或Error()的調(diào)用依賴這個調(diào)用的輸出。
另外一個訪問嵌入value更方便的方式练湿,之前的部分已經(jīng)提過猴仑,通過調(diào)用Result::ValueOrThrow, 不需要if語句,整個調(diào)用只需要單行語句(不包含try...catch塊肥哎,這個塊可能在其他地方存在)辽俗。
其他方便的方法,比如Result::ValueOr提取value, 如果不存在就取默認(rèn)值篡诽。比如:
int res = some_function().ValueOr(42);
Result :: ValueOr的一般化稱為Result :: Resolve崖飘,它不使用默認(rèn)值作為參數(shù),而是一個Callable霞捡,它可按需創(chuàng)建默認(rèn)值:
int res = some_function().Resolve([](ErrorCode const& ec){ return 42; });
對這種特殊的例子坐漏,使用Result::Resolve而不是Result::ValueOr沒有意義。但是當(dāng)常見默認(rèn)值代價很昂貴的時候碧信,可能是有意的赊琳。通過使用Result::Resolve,只有當(dāng)確實需要的時候才會創(chuàng)建默認(rèn)值砰碴。
另外一個方便的方法是Result::Bind躏筏,允許將包含的value轉(zhuǎn)成另外一個value,甚至是另外一個類型呈枉,比如:
Result<String> res = some_function().Bind([](int v){ return v + 1; }).Bind([](int v){ return std::to_string(v); }).Bind([](String const& s) { return "'" + s + "'"); });
第一次調(diào)用Result::Bind()獲取包含在Result對象中的value趁尼,加1之后,放入一個新的Result對象中并返回猖辫。
第二次調(diào)用Result::Bind()獲取包含在Result對象中的value酥泞,將它轉(zhuǎn)換成String,返回新的帶有此字符串的Result<String>啃憎。
最后一次調(diào)用Result::Bind()獲取包含在新的Result對象中的String對象芝囤,加上引號,放入其中并返回新的Result對象。
如果Result沒有包含value悯姊,?那么這些可調(diào)用項都沒有羡藐,Result對象僅進行類型轉(zhuǎn)換驱入,但保留原始的ErrorCode棒搜。
傳遞給Result :: Bind的Callables必須采用合適的類型作為參數(shù),并且可以直接返回ValueType(如之前所說练链,或者和前面ValueType相同先壕,或者一個新的瘩扼,不同的ValueType),或Result<ValueType>垃僚。
3 執(zhí)行管理
3.1 執(zhí)行狀態(tài)
執(zhí)行狀態(tài)描述了任何進程的內(nèi)部生命周期邢隧。每個進程都需要給執(zhí)行管理報告執(zhí)行狀態(tài)的變化,使用ExecutionClient::ReportExecutionState()接口冈在。
一旦進程啟動,當(dāng)報告了KRunning狀態(tài)按摘,執(zhí)行管理就認(rèn)為進程初始化完成(見[SWS_EM_01053])包券。請注意Service Discovery會引入不確定性的延遲,因此建議在報告kRunning狀態(tài)后進行炫贤;因此進程有可能在報告KRunning狀態(tài)時初始化還沒有完成溅固。
執(zhí)行管理通過向進程發(fā)送SIGTERM信號來啟動進程終止。一旦收到SIGTERM兰珍,進程通過向執(zhí)行管理報告kTerminating狀態(tài)確認(rèn)狀態(tài)變化請求(見SWS_EM_01070)侍郭。
如果是自終止進程,進程會通過想執(zhí)行管理報告kTerminating狀態(tài)來啟動自終止(見[SWS_EM_01071)掠河。
報告kTerminating之后亮元,進程會保存持久數(shù)據(jù)并釋放所有內(nèi)部使用的資源。進程通過簡單的推出表明Terminating狀態(tài)的完成(伴隨合適的退出碼)唠摹。執(zhí)行管理不需要進程本身明確的進程終止的通知爆捞。
3.2 確定性執(zhí)行
執(zhí)行管理支持完全確定的進程多線程執(zhí)行,因此處理給定的輸入數(shù)據(jù)會在限定的時間內(nèi)產(chǎn)生一直的輸出勾拉,比如行為是可重現(xiàn)的煮甥。
在AUTOSAR Adaptive平臺中,要求這種確定性的用例包括在高安全目標(biāo)系統(tǒng)的軟件Lockstep框架中的冗余執(zhí)行和重用已驗證的軟件藕赞。更多的細節(jié)可以見Specification of Execution Management, AUTOSAR_SWS_StateManagement.pdf成肘,“Deterministic Execution”部分。
可以完全確定地執(zhí)行的進程必須以某種方式設(shè)計斧蜕,實施和集成双霍,使其獨立于其他功能和計算,零星無關(guān)事件,競爭條件店煞,偏差隨機數(shù)等導(dǎo)致的處理器負(fù)載蟹演。
不確定行為可能有不同的原因造成,比如顷蟀,計算資源不足或數(shù)據(jù)的不協(xié)調(diào)訪問酒请,很可能是由多個處理器內(nèi)核上運行的多個線程造成的。線程訪問數(shù)據(jù)的順序也會影響結(jié)果鸣个,是結(jié)果不確定羞反。
完全確定的執(zhí)行包括:
*時間確定。計算的輸出一直在給定的最后期限前產(chǎn)生囤萤。進程的資源需求需要以標(biāo)準(zhǔn)的方式描述昼窗,所以集成者能給進程分配足夠的資源。(見Specification of Execution Management, AUTOSAR_SWS_StateManagement.pdf涛舍,“Real-Time Resources”部分)澄惊。
*數(shù)據(jù)確定。給定相同的輸入和內(nèi)部狀態(tài)富雅,計算也一直會產(chǎn)生相同的輸出掸驱。這個部分剩下的部分將會描述如何達到數(shù)據(jù)確定。
執(zhí)行管理提供DeterministicClient庫功能來支持確定執(zhí)行没佑。
*?通過等待點API控制流程內(nèi)部周期WaitForNextActivation()([SWS_EM_01301])毕贼。當(dāng)API返回時,進程應(yīng)執(zhí)行一個循環(huán)蛤奢,然后再次調(diào)用API以等待下一次激活鬼癣。這個API的返回值控制進程的內(nèi)部生命周期(比如:初始化,運行啤贩,終止)待秃,必須對其進行相應(yīng)的準(zhǔn)備。([SWS_EM_01302], [SWS_EM_01303] and [SWS_EM_01304]).
*?阻塞確定性工作程序池API RunWorkerPool()([SWS_EM_01305])痹屹,用于執(zhí)行一組容器元素([SWS_EM_01306])锥余,這些容器元素由同一工作程序運行對象(即應(yīng)用程序功能)并行或順序處理。
*?APIs GetActivationTime() ([SWS_EM_01310]) 和 GetNextActivationTime() ([SWS_EM_01311]) 提供激活時間戳痢掠。這個時間戳不會改變指導(dǎo)進程達到下一個等待點驱犹。
* API?GetRandom()提供隨機數(shù)([SWS_EM_01308])。如果從工作程序池中使用足画,則將隨機數(shù)分配給特定的容器元素雄驹,以允許確定性的冗余執(zhí)行。
為了保證確定行為淹辞,確定性用戶進程只可使用只有所有可用API的“確定性”子集医舆,包括工作程序運行對象:
* 進程不允許通過自己使用普通POSIX進程創(chuàng)建線程或直接訪問任何其他POSIX APIs,以規(guī)避包含不確定行為的風(fēng)險。
* 進程只允許使用所有可用的ara::com機制的“確定性子集”蔬将。稍后將提供此類API和機制的詳細列表爷速。
* 只有下面的ara::exec接口被使用:DeterministicClient和ExecutionClient。
* 用戶進程不允許訪問其他ARA接口霞怀。
如果使用工作程序池API RunWorkerPool()惫东,處理容器元素的工作程序運行對象,比如計算工作毙石,需要滿足某些實現(xiàn)規(guī)則來確保數(shù)據(jù)確定性:
* 運行對象在它運行的時候不允許交換任何信息廉沮。比如,它不會訪問可運行對象的其他實例可以更改的數(shù)據(jù)徐矩,以避免出現(xiàn)競爭情況滞时。
原理:運行對象可以物理的并行運行或以任何順序有序運行。不能保證單個工作程序的時間滤灯。操作系統(tǒng)單個調(diào)度線程坪稽。相同數(shù)據(jù)的同時影響會導(dǎo)致不確定的結(jié)果。
* 除了通過從RunWorkerPool()返回對于所有工作程序來說通用的聯(lián)接鳞骤,沒有鎖和同步點(例如刽漂,沒有信號/互斥量,沒有鎖/阻塞)弟孟。
原理:鎖定/阻止使Process運行時不確定。提供了工作程序以增加運行時的利用率样悟。 如果需要同步拂募,則必須從RunWorkerPool()返回。
工作程序池不能用來并行處理多個不同的任務(wù)窟她。使用多個可能不同的顯式函數(shù)(工作程序可運行的對象)可能會增加不必要的復(fù)雜性陈症,并可能導(dǎo)致運行時間利用率極不相同,因為每個工作程序有不同的計算時間震糖。這會使資源部署的計劃復(fù)雜化录肯,這對于黑盒集成來說是必需的。
工作程序池用戶的實現(xiàn)例子吊说。比如:工作程序運行對象的例子:
class MyWorker1
: public DeterministicClient::WorkerrunnableBase<myContainer::
value_type, MyWorker1>
{
public:
void worker_runnable(myContainer::value_type& container_element,
DeterministicClient::WorkerThread& t)
{
// Get a unique and deterministic pseudo-random number}
uint64_t random_number = t.GetRandom();
}
};
工作程序線程對象:
class DeterministicClient::WorkerThread
{
// returns a deterministic pseudo-random number}
// which is unique for each container element}
uint64_t GetRandom();
...
};
4 狀態(tài)管理
4.1 AUTOSAR Adaptive(平臺)應(yīng)用程序的交互
4.1.1 基本的狀態(tài)管理功能
狀態(tài)管理通過ara :: com提供了一組“Trigger”和“Notifier”字段论咏。狀態(tài)管理本質(zhì)上偵聽“Trigger”,并在內(nèi)部執(zhí)行特定實現(xiàn)的狀態(tài)機處理颁井,并在“Notifier”字段(如果有)中提供效果厅贪。狀態(tài)管理還通過它們提供的標(biāo)準(zhǔn)接口與其他FC進行交互。
使用這個機制還可以達到下面的效果:
*?可以要求將功能組設(shè)置為專用狀態(tài)雅宾。
*?(部分)可以請求取消/激活網(wǎng)絡(luò)
* 可以請求機器關(guān)閉或重啟养涮。
*?其他Adaptive(平臺)應(yīng)用程序的行為可能會受到影響
*?可以執(zhí)行項目特定的動作
其中一些功能至關(guān)重要。因此,集成者必須通過IAM管理適當(dāng)?shù)乇Wo對“Trigger”字段的訪問贯吓,以免意外更改狀態(tài)管理的內(nèi)部狀態(tài)(并因此而改變相關(guān)影響)懈凹。
狀態(tài)管理的內(nèi)部狀態(tài)通過其提供的“Notifier”字段通知到系統(tǒng)。對這些字段的讀取訪問權(quán)限不太重要悄谐,因此介评,每當(dāng)狀態(tài)管理的內(nèi)部狀態(tài)發(fā)生更改時,每個Adaptive(平臺)應(yīng)用程序都可以注冊其事件以收到通知尊沸。
因此威沫,當(dāng)狀態(tài)管理的狀態(tài)發(fā)生變化時,每個Adaptive(平臺)應(yīng)用程序都可以執(zhí)行操作(需要時)洼专。
4.1.2 高級狀態(tài)管理功能
AUTOSAR Adaptive中的一些用例需要在狀態(tài)管理所管理的狀態(tài)中支持同步行為棒掠。。比如低功耗模式:一個示例可能是低功耗模式:只有當(dāng)所有參與此低功耗模式場景的Adaptive(平臺)應(yīng)用程序都最終準(zhǔn)備好用于低功耗時屁商,狀態(tài)管理才能最終切換到低功耗狀態(tài)(例如烟很,持續(xù)存在 其信息)。
因此每個要求支持這種同步工作模式的Adaptive(平臺)應(yīng)用程序必須通過ara::com提供這個字段蜡镶。狀態(tài)管理器可以通過FindService找到這個字段雾袱,狀態(tài)管理器可以在以后注冊,以便在Adaptive(平臺)應(yīng)用程序執(zhí)行其操作時收到通知官还。
Adaptive(平臺)應(yīng)用程序必須完成的三件事芹橡,才能支持同步方案:
* Adaptive(平臺)應(yīng)用程序應(yīng)注冊狀態(tài)管理器的相應(yīng)“觸發(fā)”現(xiàn)場事件(在滿足狀態(tài)管理中的條件時通知)
*?Adaptive(平臺)應(yīng)用程序應(yīng)為最終狀態(tài)做任何準(zhǔn)備工作
* Adaptive(平臺)應(yīng)用程序應(yīng)將先前操作的結(jié)果寫入其提供的字段
為了使?fàn)顟B(tài)管理認(rèn)識到一個Adaptive(平臺)應(yīng)用程序想要成為同步場景的一部分,Adaptive(平臺)應(yīng)用程序不得不盡可能的提供它的字段服務(wù)使非常有必要的望伦。并且當(dāng)Adaptive(平臺)應(yīng)用程序不想再成為其中的一部分時林说,它不得不停止提供服務(wù)(例如 申請將完成)。
Adaptive(平臺)應(yīng)用程序的接口應(yīng)該遵循狀態(tài)管理的“TriggerOut”接口的模式屯伞。
5. 參考文檔
[1]Explanations of Adaptive Platform Design, AUTOSAR_EXP_PlatformDesign.pdf.
[2]Specification of Execution Management, AUTOSAR_SWS_StateManagement.pdf.