正文
4.資源Resources
訪問需要在任務和ISR之間共享的硬件或數(shù)據(jù)可能是不可靠和不安全的。這是因為當較低優(yōu)先級的任務或ISR正在更新共享數(shù)據(jù)時,可能會發(fā)生任務或ISR搶占。這種情況被稱為競態(tài)條件,非常難以測試。
訪問共享數(shù)據(jù)的語句序列稱為臨界區(qū)。為了提供對臨界區(qū)中引用的代碼和數(shù)據(jù)的安全訪問,需要強制互斥。換句話說,必須確保在臨界段期間,系統(tǒng)中沒有其他任務或二類中斷能夠搶占正在執(zhí)行的任務。
在Task章節(jié)中,看到可以將任務聲明為非搶占式可以防止出現(xiàn)互斥問題。然而,這種方法是治標不治本的,因為它通過防止出現(xiàn)搶占來防止搶占帶來的問題。
操作系統(tǒng)提供基于資源的互斥機制。資源Resources只是一個二進制信號量。當一個任務或二類ISR獲得資源時,其他任務或ISR無法獲得該資源。這可以防止任何其他任務或ISR同時進入相同的臨界區(qū)。當臨界區(qū)結束時,任務或ISR釋放資源,另一個任務/ISR可以進入臨界區(qū)。
當高優(yōu)先級任務被低優(yōu)先級任務阻止執(zhí)行時,這稱為優(yōu)先級反轉,因為高優(yōu)先級任務比低優(yōu)先級任務需要更長的時間來完成它的執(zhí)行。較低優(yōu)先級的任務似乎優(yōu)先于較高優(yōu)先級的任務運行,這與實際優(yōu)先級分配的預期相反。高優(yōu)先級的任務被低優(yōu)先級的任務阻塞。
由于優(yōu)先級反轉會在系統(tǒng)中引入無界阻塞,二進制信號量在傳統(tǒng)操作系統(tǒng)中經(jīng)常有不好的名聲。例如,如果低優(yōu)先級任務阻止高優(yōu)先級任務執(zhí)行,但它本身被一個不需要訪問共享資源的中等優(yōu)先級任務搶占,那么高優(yōu)先級任務也將被中等優(yōu)先級任務的執(zhí)行阻塞。由于低優(yōu)先級任務在持有共享資源時可能會被搶占多次,因此高優(yōu)先級任務遭受的阻塞可能是無限的,如果需要確定任務響應所需的最長時間,則會帶來嚴重的問題。在極端情況下,任務可能會達到一種被稱為“死鎖”的狀態(tài),在這種狀態(tài)下,每個任務都在等待進入一個臨界區(qū),而這個臨界區(qū)正在被其他任務使用。
在AUTOSAR OS中,避免了通常與優(yōu)先級反轉和死鎖相關的問題,因為資源是根據(jù)鎖定協(xié)議鎖定的。這個鎖協(xié)議稱為優(yōu)先級上限協(xié)議(優(yōu)先級天花板協(xié)議),特別是稱為立即繼承優(yōu)先級上限協(xié)議(或堆棧資源協(xié)議)的版本。
優(yōu)先級上限協(xié)議使用了優(yōu)先級上限的概念。系統(tǒng)中的每個資源都被分配了一個上限優(yōu)先級,該優(yōu)先級等于需要訪問該資源的任何任務或ISR的最高優(yōu)先級。當任務或ISR獲得資源時,任務/ISR的運行優(yōu)先級將增加到資源的最高優(yōu)先級(當且僅當該優(yōu)先級高于任務/ISR當前的運行優(yōu)先級)。當資源被釋放時,任務或ISR的優(yōu)先級恢復到該任務或ISR發(fā)出呼叫之前的優(yōu)先級。如圖4.1所示。
圖4.1 提升至最高優(yōu)先級
立即繼承優(yōu)先級上限協(xié)議提供了兩個主要優(yōu)點:
1)優(yōu)先級反轉被最小化。
每次高優(yōu)先級任務或ISR準備就緒時,它的執(zhí)行最多只能被一個已經(jīng)持有資源的低優(yōu)先級任務或ISR延遲一次。這意味著沒有累積阻塞,因此可以對任務遭受的阻塞設置上限-最大阻塞時間是低優(yōu)先級任務/ISR持有共享資源的最長時間。此外,這種阻塞總是在執(zhí)行開始時發(fā)生。這樣做的結果是,資源在需要鎖定時總是處于空閑狀態(tài)。在AUTOSAR操作系統(tǒng)中不需要等待資源被釋放。
2)它保證沒有死鎖。
一個任務或ISR必須在執(zhí)行中才能產(chǎn)生鎖。假設一個任務(或ISR)試圖獲取資源。如果另一個任務或ISR已經(jīng)擁有資源,那么由于該任務或ISR必須以最高優(yōu)先級運行,因此發(fā)出請求的任務不會執(zhí)行(它不會是系統(tǒng)中最高優(yōu)先級的任務或ISR),因此不能嘗試鎖定資源。
4.1 配置資源Resource Configuration
在最基本的級別上,資源只需要命名和分配類型。AUTOSAR OS中有三種類型的資源:
1)標準資源Standard Resources是普通的操作系統(tǒng)信號量。配置標準資源將創(chuàng)建具有指定名稱的資源。
2)鏈接資源Linked Resources允許為標準(或另一個鏈接的)資源設置別名,以便可以對同一資源進行嵌套鎖定。這些將在第4.4節(jié)中詳細討論。
2)內(nèi)部資源Internal Resources是在進入任務時自動鎖定并在任務結束時自動釋放的資源。這些將在第4.5節(jié)中詳細討論。
圖4.2:在rtaoscfg上配置資源
RTA-OS需要知道哪些任務和ISRs使用了哪些資源。然后,它可以計算優(yōu)先級上限協(xié)議所使用的上限優(yōu)先級。
#includeTASK(Task1) { ... GetResource(Resource1); /* Critical section. */ ReleaseResource(Resource1); ... TerminateTask(); }
Example 4.1: Using Resources
可以在任務或ISR配置期間配置每個任務或ISR的其他資源使用信息。
圖4.2顯示了已經(jīng)聲明了一個名為Resource1的資源。在程序中引用此資源時,必須使用相同的名稱。
4.2 中斷級別的資源Resources on Interrupt Level
在AUTOSAR OS中,任務和中斷之間共享的資源是可選的。RTA-OS支持這個可選特性。
RTA-OS將自動識別組合資源,因此您不需要進行任何特殊配置。
當任務獲得與ISR共享的資源時,RTA-OS將屏蔽所有中斷,中斷優(yōu)先級小于或等于共享資源的最高優(yōu)先級中斷。
這只是優(yōu)先級上限協(xié)議的擴展。在任務和ISR之間共享資源意味著提供了比啟用/禁用和暫停/恢復API調用更大的對內(nèi)部中斷屏蔽的控制,因為它們可以將中斷子集屏蔽到特定的優(yōu)先級級別。因此,當使用支持嵌套中斷的RTA-OS端口時,中斷級別的資源特別有用。
4.3 使用資源Using Resources
可以使用GetResource() API調用獲取資源。然后,您可以使用ReleaseResource()調用釋放資源。一個任務或ISR必須在釋放了它所鎖定的所有資源之后才能終止。
任務或ISR只能使用在RTA-OS配置過程中指定的資源。例4.1展示了如何在Task1中使用資源。
對GetResource()和ReleaseResource()的調用必須匹配。無法獲取已鎖定的資源。無法釋放尚未鎖定的資源。
圖4.3:執(zhí)行具有資源鎖的任務
當執(zhí)行GetResource()時,它將調用任務或ISR的優(yōu)先級提升到資源的最高優(yōu)先級。資源的上限優(yōu)先級是共享該資源的所有任務或ISR的最高優(yōu)先級,由RTA-OS自動計算。如果任何優(yōu)先級低于上限優(yōu)先級的任務準備好運行,那么它將被阻止執(zhí)行(它將被阻塞),直到正在運行的任務的優(yōu)先級恢復正常。
圖4.3通過以下配置顯示了此效果:
Task 2的第一次激活被阻塞,因為Task 1已經(jīng)鎖定了R2。Task 2的第二次激活也被阻塞,但這次是因為Task 1鎖定了R1。Task 3的第一次激活同樣被阻塞,因為Task 1持有R1。當Task 1釋放R1時,操作系統(tǒng)運行優(yōu)先級最高的就緒任務Task 3。在Task 3終止時,執(zhí)行Task 2,最后,當Task 2終止時,繼續(xù)執(zhí)行Task 1。
4.3.1 嵌套資源調用Nesting Resource Calls
可以同時獲得多個資源,但是API調用必須嚴格嵌套。我們來看兩個例子;一個顯示嵌套錯誤的調用,另一個顯示嵌套正確的API調用。
例4.2顯示Resource1和Resource2以錯誤的順序被釋放。
例4.3展示了一個正確嵌套的示例。所有的資源都被保留,然后按正確的順序釋放。
GetResource(Resource1); GetResource(Resource2); ReleaseResource(Resource1);/*Illegal!*/ /* You must release Resource2 before Resource1 */ ReleaseResource(Resource2);
Example 4.2: Illegal Nesting of Resource Calls
GetResource(Resource1); GetResource(Resource2); GetResource(Resource3); ReleaseResource(Resource3); ReleaseResource(Resource2); ReleaseResource(Resource1);
Example 4.3: Correctly Nested Resource Calls
4.4 鏈接資源Linked Resources
在AUTOSAR操作系統(tǒng)中,對相同資源的GetResource() API調用不能嵌套。但是,有時可能需要嵌套資源鎖。
應用程序可能使用在多個任務之間共享的函數(shù)。如果共享函數(shù)需要獲得一個任務使用的資源,而其他任務不需要,會發(fā)生什么情況?看一下例4.4。
#includevoid SomeFunction(void) { GetResource(Resource1); /* !!! Not allowed if caller is Task1 !!! */ ... ReleaseResource(Resource1); /* !!! Not allowed if caller is Task1 !!! */ } TASK(Task1) { GetResource(Resource1); /* Critical section. */ SomeFunction(); ReleaseResource(Resource1); } TASK(Task2) { SomeFunction(); }
Example 4.4: Illegal locking of previously locked resource
在這些情況下,(可能)持有的資源的嵌套必須使用鏈接的資源。鏈接資源是現(xiàn)有資源的別名,并保護相同的共享對象。
圖4.4顯示了如何使用rtaoscfg聲明鏈接的資源。
圖4.4:配置鏈接資源
使用鏈接的資源,例4.4將被重寫為例4.5所示。
#includevoid SomeFunction(void) { GetResource(LinkedToResource1); /* Okay */ ... ReleaseResource(LinkedToResource1); /* Okay */ } TASK(Task1) { GetResource(Resource1); /* Critical section. */ SomeFunction(); ReleaseResource(Resource1); } TASK(Task2) { SomeFunction(); }
Example 4.5: Using Linked Resources
鏈接的資源使用與標準資源相同的API調用來保持和釋放(這些將在4.3節(jié)中解釋)。
也可以創(chuàng)建鏈接資源到已有的鏈接資源。
4.5 內(nèi)部資源Internal Resources
如果一組任務非常緊密地共享數(shù)據(jù),那么就運行時成本而言,使用標準資源來保護對每個數(shù)據(jù)項的每次訪問可能過于昂貴。甚至可能無法確定需要保存資源的所有位置。
可以通過使用內(nèi)部資源來防止對共享數(shù)據(jù)的并發(fā)訪問。內(nèi)部資源是為任務的生命周期分配的資源。使用rtaoscfg離線配置內(nèi)部資源。然而,與普通資源不同的是,無法獲取和釋放它們。
從概念上講,RTA-OS在啟動任務之前立即鎖定內(nèi)部資源,并在任務結束后立即釋放資源。
當任務進入運行狀態(tài)時,RTA-OS中內(nèi)部資源的實現(xiàn)不會產(chǎn)生運行時成本,因為rtaosgen會計算任務脫機運行的優(yōu)先級,并按此優(yōu)先級簡單地調度任務。共享內(nèi)部資源的任務集在配置時使用rtaoscfg靜態(tài)定義。
注意:在AUTOSAR OS中,內(nèi)部資源僅對任務可用。但是,也沒有理由不能由第一類和第二類ISR共享內(nèi)部資源。RTA-OS提供了AUTOSAR OS的擴展,允許ISR使用內(nèi)部資源。當任務鎖定與ISR共享的內(nèi)部資源時,則任務在中斷的IPL處執(zhí)行,并且在任務期間阻塞所有同等或更低優(yōu)先級的中斷。
圖4.5顯示了一個內(nèi)部資源(稱為InternalResource)的聲明,它在任務t1和任務t3之間共享。
圖4.5 使用rtaoscfg聲明內(nèi)部資源
如果任務使用內(nèi)部資源,RTA-OS將在調用任務的入口函數(shù)之前自動獲取內(nèi)部資源。然后,在任務終止、調用Schedule()或WaitEvent()之后,資源將自動釋放。
在任務執(zhí)行過程中,所有其他共享內(nèi)部資源的任務將被阻止運行,直到內(nèi)部資源釋放。
圖4.6顯示了共享相同內(nèi)部資源的三個任務的執(zhí)行情況。
圖4.6 內(nèi)部資源的執(zhí)行
重要的是要注意,當一個擁有內(nèi)部資源的任務完成時,操作系統(tǒng)會根據(jù)就緒任務的正常(基本)優(yōu)先級做出調度決策。如果一個任務正在運行,并且共享相同內(nèi)部資源的多個任務已經(jīng)激活,那么在運行的任務終止時,將選擇優(yōu)先級最高的就緒任務來運行,然后按內(nèi)部資源的最高優(yōu)先級調度。
任何優(yōu)先級低于內(nèi)部資源優(yōu)先級上限的任務(包括不共享內(nèi)部資源的任務)在執(zhí)行共享內(nèi)部資源的任務時將被阻塞。可以在圖4.6中看到一個示例,其中優(yōu)先級為1的Task1與優(yōu)先級為3的Task共享內(nèi)部資源。如果Task1在Task2或Task3啟動之前開始運行,那么這兩個任務將被延遲(阻塞),直到Task1完成。
然而,所有不共享內(nèi)部資源的高優(yōu)先級任務仍然可以搶占。圖4.7顯示,Task 1最初以優(yōu)先級3運行,因為它與優(yōu)先級3的任務共享一個內(nèi)部資源。當Task 1運行時,Task 2就可以運行了。task2的優(yōu)先級低于Task1的活動優(yōu)先級,因此它不能搶占。當Task4被激活時,它可以搶占Task1,因為它的優(yōu)先級是4,即它的優(yōu)先級高于Task1的活動優(yōu)先級。任務2只能在任務1終止時運行。
圖4.7 內(nèi)部資源阻塞了不共享資源的任務
從這種行為可以清楚地看出,鎖定內(nèi)部資源的任務將阻止任何優(yōu)先級高于自身但優(yōu)先級低于內(nèi)部資源最高優(yōu)先級的任務在整個任務期間運行。當?shù)蛢?yōu)先級任務阻止高優(yōu)先級任務執(zhí)行時,稱為阻塞。共享內(nèi)部資源的任務相對于彼此非搶占性地運行。
一旦共享內(nèi)部資源的集合中的任務獲得了對CPU的訪問權,它將在不被集合中的任何其他任務搶占的情況下運行。這樣做的結果是,與完全搶占式系統(tǒng)相比,高優(yōu)先級任務可能需要更長的時間才能訪問CPU。
4.6 使用資源以最小化堆棧使用Using Resources to Minimize Stack Usage
資源在應用程序中的主要作用是在關鍵部分上提供互斥。然而,RTA-OS的單堆棧模型意味著資源有一個有用的次要角色——最小化堆棧使用。回想一下,共享資源的任務不會相互搶占。在RTA-OS使用的單堆棧模型中,這意味著它們的堆棧使用是有效覆蓋的。
可以利用這個特性來權衡系統(tǒng)中的時間和堆棧使用情況。下面幾節(jié)介紹對應用程序的簡單修改如何減少堆棧使用。所有這些修改都會在系統(tǒng)中引入額外的阻塞因素。
這些阻礙因素的影響取決于系統(tǒng)。回想一下,優(yōu)先級上限協(xié)議確保任務或ISR在執(zhí)行期間最多被阻塞一次。最壞阻塞時間是任何低優(yōu)先級任務或ISR可以占用相同資源的最大時間。
這意味著,如果額外的阻塞因素小于或等于當前任務/ISR所遭受的最壞情況阻塞,則不會對響應時間產(chǎn)生影響,并且減少的堆棧使用將被釋放。如果額外的阻塞因素比當前的最壞情況阻塞更長,那么響應時間將更長。如果響應時間保持在任務/ ISR所需的截止日期之內(nèi),系統(tǒng)仍將正常運行。
4.6.1 內(nèi)部資源Internal Resources
給定一組共享內(nèi)部資源的任務,RTA操作系統(tǒng)使用的最壞情況堆棧等于使用最多堆棧的任務所需的最大堆棧空間。在傳統(tǒng)操作系統(tǒng)中,最大堆棧空間等于任務堆棧的總和,而不是它們的最大值。
如果需要最小化堆棧空間,那么可以通過在消耗大量堆棧的任務之間共享內(nèi)部資源來利用RTA-OS的單一堆棧架構的優(yōu)勢。圖4.8中的第一個堆棧顯示了5個搶占任務A、B、C、D和E的最壞情況堆棧消耗情況。通過在任務B和C之間以及任務D和E之間共享內(nèi)部資源,可以顯著節(jié)省堆棧空間。圖4.8中的其他四個堆棧顯示了現(xiàn)在可能發(fā)生的情況——最壞的情況是A被B的最壞情況搶占,或者C被D和e的最壞情況搶占。從圖中可以看到,A被C搶占,被D搶占,這是最壞的情況,這比不使用內(nèi)部資源時的堆棧要少得多。
圖4.8:使用內(nèi)部資源節(jié)省堆棧空間
4.6.2 標準資源Standard Resources
如果一個任務調用一個使用大量堆棧的函數(shù),那么可以考慮鎖定函數(shù)調用周圍的資源,并與優(yōu)先級更高的任務共享資源。任務不需要在代碼中鎖定資源或調用函數(shù)——共享只是為了強制任務的執(zhí)行以更高的優(yōu)先級運行。這將防止高優(yōu)先級任務在使用大量堆棧時搶占任務,從而減少總堆棧需求。
禁用函數(shù)調用周圍的中斷具有類似的效果——有效地用臨時屏蔽的ISR覆蓋函數(shù)調用的堆棧使用情況。
4.7 作為資源的調度程序The Scheduler as a Resource
如果一個任務有一個必須在不被系統(tǒng)中任何其他任務搶占的情況下執(zhí)行的關鍵段(回想一下,調度程序是用來執(zhí)行任務切換的),則該任務可以保留調度程序。為此目的,所有任務都可以使用一個名為RES_SCHEDULER的預定義資源。RES_SCHEDULER是任務共享數(shù)據(jù)的一種方便方法,無需手動聲明在所有任務之間共享的資源。
當一個任務獲得RES_SCHEDULER時,所有其他任務將被阻止搶占,直到該任務釋放RES_SCHEDULER。這實際上意味著任務在RES_SCHEDULER被占用的時間內(nèi)是非搶占性的。
這比使整個任務非搶占性要好,特別是當任務只需要在其總執(zhí)行時間的一小部分防止搶占時。
必須指定應用程序是否使用RES_SCHEDULER。這是在“一般”中設置的。如果配置RES_SCHEDULER,那么RTA-OS將自動生成一個稱為RES_SCHEDULER的標準資源,并在配置中的每個任務之間共享它。由于RES_SCHEDULER的行為類似于標準資源,可以創(chuàng)建鏈接到RES_SCHEDULER的鏈接資源,如圖4.9所示。
圖4.9:Linking to RES_SCHEDULER
使用RES_SCHEDULER可以改善低優(yōu)先級任務的響應時間,否則這些任務可能會受到應用程序中其他任務的多次搶占,但代價是高優(yōu)先級任務的響應時間更長。
如果您不需要在應用程序中使用RES_SCHEDULER,那么您可以通過禁用它的生成來節(jié)省ROM和RAM空間,如圖4.10所示。
圖4.10:Disabling RES_SCHEDULER
4.8 選擇一個搶占控制機制Choosing a Preemption Control Mechanism
如果在一對GetResource()和ReleaseResource()調用之間出現(xiàn)不需要鎖的代碼,則可能會降低系統(tǒng)的響應性。考慮到這一點,當您在應用程序中使用資源時,應該將GetResource()調用盡可能地放置在您使用該資源保護的代碼段附近。
然而,這條規(guī)則有一個例外。當有一個短時間運行的任務或ISR對同一資源進行多次GetResource()和ReleaseResource()調用時,就會出現(xiàn)此異常。API調用的成本可能會占整個任務執(zhí)行時間的很大一部分,因此也可能占響應時間的很大一部分。
可能會發(fā)現(xiàn),將整個任務或ISR主體放在GetResource()和ReleaseResource()調用之間實際上縮短了最壞情況下的響應時間。
應該盡可能避免使用非搶占式任務并獲取RES_SCHEDULER。當資源被占用的時間最少,并且影響的任務數(shù)量最少時,系統(tǒng)的響應性和可調度性就會得到改善。
4.9 避免競態(tài)條件Avoiding Race Conditions
調用TerminateTask()。在某些情況下,這可能會在應用程序中引入競態(tài)約束條件。這可能會導致錯過任務激活(您在本章開頭了解了競爭條件)。
例4.6展示了競態(tài)條件可能成為問題的系統(tǒng)類型。假設兩個BCC1任務在有界緩沖區(qū)上交換數(shù)據(jù)。
在例4.6中,在資源被釋放到任務結束之間,Read可以被Write搶占。當“寫”任務與“讀”任務連接時,激活將丟失。這是因為Read仍在運行。換句話說,一個任務正在被激活,但它沒有處于掛起狀態(tài)。
要解決這個問題,可以允許排隊激活Read任務。這意味著您應該將任務設置為BCC2。
#includeTASK(Write) /* Highest priority .*/ WriteBuffer(); GetResource(Guard); BufferNotEmpty = True; ReleaseResource(Guard); ChainTask(Read); } TASK(Read) /* Lowest priority. */ ReadBuffer(); GetResource(Guard); if( BufferNotEmpty ) { ReleaseResource(Guard); /* !!! Race condition occurs here !!! */ ChainTask(Read); } else { ReleaseResource(Guard); /* !!! Race condition occurs here !!! */ TerminateTask(); } }
Example 4.6: A System where a Race Condition can Occur
4.10 小結
?資源用于在訪問共享數(shù)據(jù)或硬件資源時提供互斥。
?任務和ISR可以共享任意數(shù)量的資源。
?所有GetResource()和ReleaseResource()調用必須正確嵌套。
?所有資源必須在任務或ISR終止前釋放。
?調度器可以作為資源使用,但如果可能的話,應該優(yōu)先使用內(nèi)部資源。
?內(nèi)部資源為控制任務組和ISR之間的搶占提供了一種自由(Free)機制。
審核編輯:劉清
-
操作系統(tǒng)
+關注
關注
37文章
6895瀏覽量
123745 -
AUTOSAR
+關注
關注
10文章
363瀏覽量
21779 -
ISR
+關注
關注
0文章
38瀏覽量
14471 -
WIPL
+關注
關注
0文章
2瀏覽量
6199
原文標題:符合AUTOSAR標準的RTA-OS --Resources詳解
文章出處:【微信號:汽車電子嵌入式,微信公眾號:汽車電子嵌入式】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
相關推薦
TC397如何同時運行CP Autosar OS和FreeRTOS?
TC387配置Autosar OS后主核跑飛了怎么解決?
如何開發(fā)符合AUTOSAR規(guī)范的電機控制器軟件
“E:\NXP\AUTOSAR\S32K_AUTOSAR_OS_4_0_98_RTM_1_0_0sample\standard\sc1”編譯時無法生成sample1_cfg.o怎么解決?
RTA-OS實時操作系統(tǒng)中的Task對象
經(jīng)緯恒潤自主研發(fā)出符合AUTOSAR標準的軟件產(chǎn)品
開發(fā)支持符合AUTOSAR標準的軟件組件的建模特定領域的語言
RTA OS系列介紹01-Task
簡析符合AUTOSAR標準的RTA-OS功能
符合AUTOSAR標準的RTA-OS --Task詳解
符合AUTOSAR標準的RTA-OS--Interrupts介紹
![<b class='flag-5'>符合</b><b class='flag-5'>AUTOSAR</b><b class='flag-5'>標準</b>的<b class='flag-5'>RTA-OS</b>--Interrupts介紹](https://file1.elecfans.com/web2/M00/82/47/wKgZomRIf3-ACPP4AAAyAofz6c8723.png)
評論