chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

符合AUTOSAR標準的RTA-OS --Task詳解

832065824 ? 來源:汽車電子嵌入式 ? 2023-04-17 09:38 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

本系列文章將以RTA-OS為例詳細介紹AUTOSAR OS標準及概念,并分享實際使用的一些案例,本文為符合AUTOSAR標準的RTA-OS--Task介紹。

符合AUTOSAR標準的RTA-OS --功能簡介

30cd3936-dcbc-11ed-bfe3-dac502259ad0.png

正文

2.任務Task

必須同時執(zhí)行許多不同活動的系統(tǒng)稱為并發(fā)。這些活動可能包含一些軟件部分,因此提供這些活動的程序必須同時執(zhí)行。這些程序必須在任何必要的時候進行合作,例如,當它們需要共享數(shù)據(jù)時。

實時系統(tǒng)中的每個并發(fā)活動都由一個任務來表示。大多數(shù)應用程序代碼都存在于任務中。如果有許多必須同時執(zhí)行的任務,那么將需要提供一種允許并發(fā)性的方法。其中一種方法是為每個任務都有一個單獨的處理器??梢允褂貌⑿杏嬎銠C,但這個解決方案對許多應用程序來說太昂貴了。

實現(xiàn)并發(fā)行為的一個更經(jīng)濟有效的方法是在單個處理器上一次運行一個任務。然后可以在任務之間切換,以便它們看起來同時執(zhí)行。

2.1 調度Scheduling

RTA-OS提供了一個調度器,它根據(jù)在配置時分配的固定優(yōu)先級在任務之間切換。優(yōu)先級只是反映了任務的相對緊迫性??梢允褂迷S多方案來分配任務的優(yōu)先級,常見方案有:

Deadline Monotonic Assignment: 更高的優(yōu)先級被分配給最后期限較短的任務。

Rate Monotonic Assignment: 更高的優(yōu)先級被分配給需要更頻繁地運行的任務。

無論選擇分配優(yōu)先級,任務執(zhí)行的順序由調度策略決定。調度策略決定任務何時實際運行。

AUTOSAR操作系統(tǒng)支持兩種調度策略:

1.搶占式調度Preemptive Scheduling.

固定優(yōu)先級搶占式調度算法很簡單:運行準備運行的最高優(yōu)先級任務。如果任務正在運行,而優(yōu)先級較高的任務準備運行,則優(yōu)先級較高的任務優(yōu)先于正在運行的任務。這叫做任務切換。當高優(yōu)先級任務完成后,搶占任務恢復。

對于所有任務都需要在運行時滿足其最后期限的系統(tǒng),搶占式的調度是最有效的調度策略,并將保證任務被激活(準備運行)和終止之間的最短時間。這個時間被稱為對該任務的響應時間。搶占式調度的系統(tǒng)需要考慮搶占對共享數(shù)據(jù)的影響,并且可能需要引入并發(fā)控制機制。

30e6867a-dcbc-11ed-bfe3-dac502259ad0.png

圖2.1 任務的搶占式調度

2.非搶占式調度 Non-Preemptive scheduling.

操作系統(tǒng)運行優(yōu)先級已準備運行的最高任務,和搶占式調度一樣。然而,搶占式調度不同的是,如果一個更高優(yōu)先級的任務準備好了,那么它就會一直準備好運行,直到正在運行的任務終止——它不會搶占正在允許的低優(yōu)先級的任務。這意味著,開始運行的非搶占式任務將始終運行到完成,然后終止。

非搶占式調度導致系統(tǒng)比搶占式調度的響應性更低(即任務通常有更長的響應時間),但系統(tǒng)不需要擔心訪問共享數(shù)據(jù)時出現(xiàn)的并發(fā)問題,因為調度模型不允許并發(fā)訪問共享數(shù)據(jù)。

實際上,AUTOSAR OS提供了第三種類型的調度支持,因為它允許非搶占任務告訴操作系統(tǒng)什么時候可以被搶占。我們說AUTOSAR操作系統(tǒng)支持2個策略的原因是只有兩個配置——第三個配置,必須自己構建。

30fb1edc-dcbc-11ed-bfe3-dac502259ad0.png

圖2.2 任務的非搶占式調度

3.協(xié)同調度Cooperative scheduling.

操作系統(tǒng)將運行優(yōu)先級最高的準備運行的任務。如果一個更高優(yōu)先級的任務準備好了,那么它會一直準備運行直到:正在運行的任務終止(就像非搶占式調度);或者正在運行的任務調用Schedule() API來告訴操作系統(tǒng)它可以被搶占。當Schedule()調用時,高優(yōu)先級任務搶占正在運行的任務,任務切換就發(fā)生了(就像搶占調度一樣)。當高優(yōu)先級任務完成后,被搶占的任務恢復。

通過仔細的設計,協(xié)同模式提供的系統(tǒng)雖然不像完全搶占式系統(tǒng)那樣響應迅速,但不會像非搶占式調度那樣缺乏響應能力。

310f0820-dcbc-11ed-bfe3-dac502259ad0.png

圖2.3 任務的協(xié)同調度

對于所有這些類型的調度,重要的是要意識到任何任務,無論是否搶占人,都可以被中斷服務例程中斷(搶占)。

2.2基本和擴展任務Basic and Extended Tasks

RTAOS支持兩種類型的Task:

l基本任務Basic Task

基本任務的開始、執(zhí)行和結束(通常稱為單次任務模式)。一個基本任務只有在它被終止或被一個更高優(yōu)先級的任務搶占時才釋放處理器。這種行為使它們非常適合嵌入式控制功能?;救蝿帐强焖俑咝У?。

l擴展任務Extended Task

擴展任務啟動、執(zhí)行、等待事件和(可選)終止。擴展任務在執(zhí)行期間自動掛起自身的能力為任務提供了一種具有同步點的方法。這個特性使得擴展任務比基本任務更適合需要執(zhí)行中間同步的功能(例如,等待用戶交互)。

2.2.1 任務狀態(tài)Task State

基本任務在三狀態(tài)模型上運行?;救蝿沼幸韵聨追N狀態(tài):

l掛起Suspended

l準備Ready

l允許Running

擴展任務可以在等待事件時進入一個額外的狀態(tài):

l等待Waiting

圖2.4展示了任務3或者4狀態(tài)模型。

所有任務的默認狀態(tài)是掛起。任務通過激活過程進入就緒狀態(tài)。重要的是要理解激活并不會導致任務運行——它只是讓任務準備好運行。激活可以通過多種方式發(fā)生,例如在代碼中調用ActivateTask()API,或者作為某些觸發(fā)器的結果,例如警報(Alarm)到期或調度表到期點( schedule table expiry point)。

當一個任務成為系統(tǒng)中優(yōu)先級最高的任務時,RTA-OS將該任務移至運行狀態(tài),并在任務中的第一條語句開始執(zhí)行任務。這通常被稱為調度任務。一個任務可能在執(zhí)行過程中被其他準備就緒的高優(yōu)先級任務搶占。

31283b42-dcbc-11ed-bfe3-dac502259ad0.png

圖2.4 任務狀態(tài)模型

如果有更高優(yōu)先級的任務準備運行,則當前正在執(zhí)行的任務將被搶占,并從運行狀態(tài)移至就緒狀態(tài)。這意味著在同一時間內(nèi)只能有一個任務處于運行狀態(tài)。

任務終止后返回掛起狀態(tài)。任務可以在以后再次準備好,整個過程可以重復。

基本任務和擴展任務在準備、運行和掛起狀態(tài)方面表現(xiàn)相同。但是,擴展任務也可以進入等待狀態(tài)。當擴展任務通過等待事件自動掛起自己時,它將從運行狀態(tài)轉移到等待狀態(tài)。

事件只是一個OS對象,用于為系統(tǒng)事件提供指示器。事件的例子包括數(shù)據(jù)準備使用或傳感器值正在讀取。

當擴展任務進入等待狀態(tài)時,操作系統(tǒng)將分派準備運行的最高優(yōu)先級任務。當設置事件時,任務將從等待狀態(tài)移動到準備狀態(tài)。注意,擴展任務返回到就緒狀態(tài),而不是運行狀態(tài)。這是因為,在擴展任務處于等待狀態(tài)期間,其他一些更高優(yōu)先級的任務可能已經(jīng)被激活,然后被分派。

2.2.2 任務優(yōu)先級Task Priorities

AUTOSAR OS允許任務共享優(yōu)先級。當任務具有相同優(yōu)先級時,具有共享優(yōu)先級的每個任務將相互排斥運行。這意味著如果一個任務正在運行,那么它的執(zhí)行將與所有其他具有相同優(yōu)先級的任務序列化。

當任務共享優(yōu)先級時,它們將按照先進先出(FIFO)的順序從就緒狀態(tài)釋放。

Note:當共享優(yōu)先級和排隊任務激活一起使用時,RTA-OS在優(yōu)先級級別上維護一個內(nèi)部隊列。如果想要一個快速高效的操作系統(tǒng),你應該避免這種類型的配置。


如果需要序列化一組任務的執(zhí)行,那么最好使用惟一的優(yōu)先級和AUTOSAR OS的內(nèi)部資源來實現(xiàn),而不是共享任務優(yōu)先級。使用內(nèi)部資源保證了序列化,就像共享優(yōu)先級一樣,任務優(yōu)先級的唯一性意味著當多個任務同時就緒時,操作系統(tǒng)有一個靜態(tài)定義的分派順序。

Note:在任務之間共享優(yōu)先級是一種糟糕的實時編程實踐,因為它會阻止您在系統(tǒng)上執(zhí)行可調度性分析。這是因為,在一般情況下,共享優(yōu)先級使得任務的釋放點(即測量響應時間的點)在計算上無法計算。如果不可能計算出何時發(fā)布,那么就不可能決定任務是否會在截止日期前完成!

2.2.3 任務隊列激活Queued Task Activation

在大多數(shù)情況下,只能在任務處于掛起狀態(tài)時激活它。AUTOSAR OS在任務處于就緒、運行或等待狀態(tài)時將其激活視為錯誤情況。

然而,在某些情況下,我們可能需要實現(xiàn)這樣一個系統(tǒng):相同的任務必須多次激活,但連續(xù)激活之間的最短時間可能小于運行任務所需的時間。例如,您可能正在一個任務中解包CAN總線幀,并且需要處理網(wǎng)絡上幀的瞬時爆發(fā)( transient bursting)。

這意味著我們需要在運行時排隊等待任務激活。AUTOSAR OS操作系統(tǒng)允許排隊激活基本任務,以幫助構建這類應用程序。與自動共享操作系統(tǒng)中的其他東西一樣,任務隊列的大小也是靜態(tài)配置的。我們必須指定該任務可以掛起的最大激活數(shù)。

如果在嘗試激活任務時隊列已滿,則這將作為錯誤處理,激活將被忽略。

當然,您可能會有共享優(yōu)先級并使用隊列激活的任務。在這種情況下,任務按FIFO順序在一個隊列中排隊,其長度等于共享相同優(yōu)先級的每個任務的隊列長度之和。但是,每個任務只能使用它自己的條目數(shù)量。

2.2.4 異步任務激活Asynchronous Task Activation

AUTOSAR OS允許從內(nèi)核激活任務,而不是任務實際運行的內(nèi)核。雖然這可能很有用,但可能會有性能影響,因為要完全兼容AUTOSAR,所有任務激活(包括SetEvent)必須阻塞調用方,直到任務狀態(tài)更新。在內(nèi)部,操作系統(tǒng)必須使用內(nèi)部自旋鎖與擁有的核協(xié)調狀態(tài)更改。這可能會對所有核的性能產(chǎn)生重大影響。

RTA-OS提供了一個OS選項異步任務激活,它改變了激活的行為,這樣就不會阻塞內(nèi)核,而是將消息發(fā)送到擁有要激活任務的內(nèi)核上的隊列。擁有的核心是執(zhí)行任務的實際激活的核心,因此它是唯一更改任務狀態(tài)的核心。不使用任務自旋鎖,因為不需要保護任何狀態(tài)。

任務激活隊列的大小默認設置為10。如果該隊列已滿,則返回錯誤碼E_OS_SYS_XCORE_QFULL。隊列大小可以使用AsyncQ OS選項更改。

Note: 當選擇異步TASK激活時,E_OS_LIMIT指示會在擁有該任務的核上發(fā)出,而不是在激活它的核上。

2.3 一致性類Conformance Classes

我們現(xiàn)在知道,任務可以:

l基本的或擴展的

l可以共享優(yōu)先級

l可以排隊激活

然而,AUTOSAR操作系統(tǒng)對一起使用的特性進行了一些限制。這些特性被稱為一致性類,用于對任務特征進行分組,以便于理解,支持標準的部分實現(xiàn),并為不同類別的應用程序提供了可伸縮性。

AUTOSAR操作系統(tǒng)有四個一致性類:

BCC1-基本任務,唯一的優(yōu)先級和沒有排隊的激活( Basic tasks, unique priority and no queued activation).

BCC2- 基本任務、共享優(yōu)先級和/或排隊激活(Basic tasks, shared priorities and/or queued activation).

ECC1- 擴展的任務,唯一的優(yōu)先級和沒有排隊的激活。ECC1任務類似于BCC1任務,但它可以等待事件(Extended tasks, unique priority and no queued activation. An ECC1 task is like

a BCC1 task, but it can wait on events.)

ECC2- 擴展的任務,共享的優(yōu)先級和沒有排隊的激活。請注意,與BCC2任務不同,ECC2任務不能排隊激活(Extended tasks, shared priorities and no queued activation. Note that, unlike

BCC2 tasks, ECC2 tasks cannot queue activations.)

3145ea5c-dcbc-11ed-bfe3-dac502259ad0.png

下表給出了可以在不同類型的AUTOSAR操作系統(tǒng)中使用的任務類型的快速摘要:

每個一致性級別都需要更多的資源——BCC1的系統(tǒng)將比ECC2的系統(tǒng)更快更小。您不需要關心使用哪個一致性類- RTA-OS支持所有一致性類,并將從您的操作系統(tǒng)配置中計算一致性類。

1但僅針對ECC2系統(tǒng)中的基本任務。擴展任務的激活不能被排隊。

2.4 最大化性能和最小化內(nèi)存Maximizing Performance and Minimizing Memory

RTA-OS被設計成非常積極地最小化目標應用程序上的代碼和數(shù)據(jù)使用。它將分析應用程序的特性,并生成一個只包含所需特性的系統(tǒng)。

任務特征的選擇對最終應用程序的大小和速度有很大影響。所以當你在應用程序中添加使用更高級任務類型的任務時,系統(tǒng)將不可避免地變得稍微大一點和慢一點。

具有一個或多個BCC2任務的系統(tǒng)比僅具有BCC1任務的系統(tǒng)具有更大的開銷。一個沒有共享優(yōu)先級的系統(tǒng),即使允許進行多個激活,也將比一個具有共享優(yōu)先級的系統(tǒng)更有效。

帶有ECC1任務的系統(tǒng)開銷更大,而具有一個或多個ECC2任務的系統(tǒng)開銷是最大的。

為了使RTA-OS盡可能高效,您應該只使用基本任務,而不是共享優(yōu)先級。

2.5 任務配置Task Confifiguration

與您可能見過的其他實時操作系統(tǒng)不同,AU TOSAR OS(因此,RTA-OS)中的任務是靜態(tài)定義的。

這種技術被廣泛使用,因為它節(jié)省了RAM和執(zhí)行時間。

任務不能動態(tài)創(chuàng)建或銷毀。關于任務的大部分信息可以離線計算,允許它存儲在ROM中。

RTA-OS支持的最大任務數(shù)取決于您的端口,您應該參考目標/編譯器端口指南了解更多細節(jié)。

對于所有端口,RTA-OS可以提供一個高度優(yōu)化的系統(tǒng),如果你限制你的任務數(shù)量到你的微控制器的本機字大小。

3158e490-dcbc-11ed-bfe3-dac502259ad0.png

在配置任務屬性時,您很可能會使用rtaoscfg配置工具。圖2.5顯示了任務配置條目。

317096ee-dcbc-11ed-bfe3-dac502259ad0.png

圖2.5 任務配置

一個AUTOSAR任務有5個屬性:

Name.該名稱用于引用或提供要用來實現(xiàn)任務功能的C代碼的句柄。

Priority.調度程序使用優(yōu)先級來確定任務何時運行。優(yōu)先值不能動態(tài)更改。在RTA-OS中,0是最低的任務優(yōu)先級。更高的任務優(yōu)先級由更大的整數(shù)表示。任務可以共享優(yōu)先級,但如果您正在構建一個實時系統(tǒng),那么就不應該這樣做,因為它不能被分析。

Scheduling.任務可以完全搶先運行,也可以非搶先運行。一般來說,為了獲得最佳的應用程序性能,應該選擇完全搶占式調度而不是非搶占式調度。

Activations.可在就緒狀態(tài)下排隊的任務激活的最大數(shù)量。對于一個BCC1、ECC1和ECC2任務,激活的次數(shù)為1。這意味著這些類型的任務只有在處于掛起狀態(tài)時才能被激活。任何嘗試在未掛起的情況下激活這樣的任務都會導致錯誤。大于1的值表示操作系統(tǒng)將排隊激活(例如平滑應用程序中的瞬時峰值負載)。

Autostart.這將控制在啟動操作系統(tǒng)時是否自動啟動任務。

Note: 可以為每個目標定義的任務的數(shù)量是固定的(通常是256或1024,這取決于目標處理器)。目標的目標/編譯器端口指南將包含更多的信息。

2.5.1 調度策略Scheduling Policy

完全可搶占的任務可以被更高優(yōu)先級的任務搶占。這意味著當一個更高優(yōu)先級的任務準備好運行時,它將優(yōu)先運行。

可以通過在配置時將任務聲明為不可搶占來防止其被搶占。聲明為非搶占的任務不能被其他任務搶占。當一個非搶占任務移動到運行狀態(tài)時,它將運行到完成,然后終止(除非它進行Schedule()調用)。因此,使任務具有非搶占性意味著,如果低優(yōu)先級任務在高優(yōu)先級任務之前啟動,那么在低優(yōu)先級任務運行期間,高優(yōu)先級任務將被阻止執(zhí)行。這叫做阻塞。通常情況下,使用非搶占式任務的系統(tǒng)比搶先式運行的系統(tǒng)響應速度要慢。

即使一個任務不是可搶占的,它仍然可以被ISR中斷。

使用不可搶占的任務是不必要的,因為有其他更合適的方法可以用來實現(xiàn)相同的效果。如果使用這些其他技術,通常會產(chǎn)生一個響應性更強的系統(tǒng)。稍后將介紹更多關于這些技巧的內(nèi)容,其中包括:

l使用標準資源來序列化對數(shù)據(jù)或設備的訪問。

l使用內(nèi)部資源來精確地指定哪些其他任務不能導致?lián)屨肌?/p>

2.5.2 排隊激活Queued Activation

在大多數(shù)情況下,只有在任務處于掛起狀態(tài)時才會激活它。但是,可能需要實現(xiàn)一個系統(tǒng),其中同一任務必須被激活多次,并且連續(xù)激活之間的最短時間小于運行任務所需的時間。

如果發(fā)生這種情況,將在任務處于就緒狀態(tài)或運行狀態(tài)時激活該任務。這意味著激活將會丟失。

要防止失去激活,必須指定任務所需的多次激活的最大激活數(shù)。

Note: 根據(jù)AUTOSAR操作系統(tǒng)標準,此功能僅可用于基本任務。您不能為擴展的任務指定多個激活。

您將使用rtaoscfg指定同時激活任務的最大數(shù)量。圖2.6顯示,對于本例中的任務,最大激活次數(shù)已設置為20。

3194b2b8-dcbc-11ed-bfe3-dac502259ad0.png

圖2.6 指定排隊激活的數(shù)量

當指定多個激活時,RTA-OS會自動識別該任務是BCC2。在構建應用程序時,RTA-OS將計算每個BCC2任務所需的多個激活隊列的最大大小。

當BCC2任務共享優(yōu)先級時,RTA-OS使用FIFO隊列來保存掛起的激活。如果一個BCC2任務在您的AUTOSAR OS應用程序中具有唯一的優(yōu)先級,那么RTA-OS將自動優(yōu)化排隊策略以計數(shù)激活。計數(shù)激活法比先進先出激活法效率高得多,應在任何可能的地方使用。

2.5.3 自動啟動任務Auto-starting Tasks

任務可以自動啟動,這意味著當操作系統(tǒng)啟動時,它們將在StartOS()期間自動激活。

對于啟動、運行然后終止的基本任務,自動啟動任務將使它只運行一次,然后才返回掛起狀態(tài)(在那里它可以再次被激活)。

自動啟動主要用于啟動等待事件的擴展任務,因為它不需要編寫代碼來激活任務。

Rtaoscfg可用于指定任務僅在特定應用程序模式下自動激活,選擇相關的應用程序模式并選擇您希望自動激活的任務。

在圖2.7中,TaskD在OSDEFAULTAPPMODE和ServiceMode應用程序模式下是自動啟動的,而在LimpHomeMode和NormalOperatingMode下不是自動啟動的。

31b80902-dcbc-11ed-bfe3-dac502259ad0.png

圖2.7 配置自動啟動的任務

2.6 棧管理Stack Management

RTA-OS使用單堆棧模型,這意味著所有任務和ISR都運行在單個堆棧上。單個堆棧就是應用程序的C堆棧。

當任務運行時,它的堆棧使用量會正常增長和減少。當任務被搶占時,更高優(yōu)先級任務的堆棧使用將繼續(xù)在同一堆棧上進行(就像標準函數(shù)調用一樣)。當任務終止時,它所使用的堆??臻g將被回收,然后重新用于運行下一個最高優(yōu)先級的任務(同樣,就像標準函數(shù)調用一樣)。圖2.8顯示了單個堆棧在聲明、搶占和終止任務時的行為。

31e30e0e-dcbc-11ed-bfe3-dac502259ad0.png

圖2.8 單堆棧行為

在單堆棧模型中,堆棧大小與系統(tǒng)中優(yōu)先級的數(shù)量成正比,而不是任務/ ISR的數(shù)量。這意味著共享優(yōu)先級的任務,無論是直接共享,還是通過共享內(nèi)部資源,或者通過配置為非搶占,都不能同時在堆棧上。在硬件上共享優(yōu)先級的ISR也是如此。這意味著您可以通過簡單地更改配置來交換系統(tǒng)響應性(即任務或ISR完成所需的時間),以換取堆??臻g。

圖2.9顯示了相同任務集的執(zhí)行,具有與圖2.8相同的到達模式,但這次任務是非搶先調度的。您可以看到,高優(yōu)先級任務的響應時間比t時要長得多,但總體堆棧消耗要低得多。

單堆棧模型還顯著簡化了鏈接時的堆??臻g分配,因為您只需要為整個系統(tǒng)堆棧分配一個內(nèi)存部分,就像您完全不使用操作系統(tǒng)一樣。

2.6.1 使用擴展任務Working with Extended Tasks

RTA-OS獨特地擴展了單堆棧模型,以提供對擴展任務的支持,而對基本任務的性能沒有任何影響。

在RTA-OS中,擴展任務的生命周期如下:

Suspended ? Ready該任務將被添加到已準備就緒的隊列中。

Ready ? Running任務被分派了,但與基本任務不同的是,上下文被放置在堆棧的頂部,上下文被放置在堆??臻g中,位于所有低優(yōu)先級任務的預先計算的最壞情況搶占深度。

Running ? Ready擴展任務被搶占。如果搶占任務是一個基本任務,那么它將正常地在堆棧頂部分派。如果搶占任務是一個擴展任務,那么它將按照所有低優(yōu)先級任務預先計算的最壞情況搶占深度進行分派。

Running ? Waiting任務的等待事件堆棧上下文,包括操作系統(tǒng)上下文、本地數(shù)據(jù)、函數(shù)調用的堆棧幀等,被保存到一個內(nèi)部操作系統(tǒng)緩沖區(qū)。

32007bb0-dcbc-11ed-bfe3-dac502259ad0.png

圖2.9 具有非搶占式任務的單堆棧行為

Waiting ? Ready該任務將被添加到已準備就緒的隊列中。

Ready ? Running任務的“等待事件堆?!鄙舷挛膹膬?nèi)部操作系統(tǒng)緩沖區(qū)復制到堆棧中,并以所有低優(yōu)先級任務的預先計算的最壞情況搶占深度進行計算。

此流程允許管理擴展任務的額外成本僅應用于擴展任務本身。包含擴展任務的系統(tǒng)中的基本任務與僅包含基本任務的系統(tǒng)具有相同的性能。

這個生命周期的關鍵部分是在最壞情況下的分派/恢復,以及在堆棧上和從堆棧上復制。在最壞情況搶占點的分派可以保證,無論何時擴展任務在等待后恢復,它都可以在內(nèi)存中完全相同的位置恢復其局部變量。它保證了低優(yōu)先級任務的每種可能的搶占模式都不會超過擴展任務的分派點。擴展任務D的調度-等待-恢復周期如圖2.10所示。

復制和打開允許恢復擴展任務堆棧上下文。這是必要的,因為高優(yōu)先級任務和/或isr可能在擴展任務等待時發(fā)生。這些可能會消耗比最壞情況搶占點更大的堆??臻g(記住,最壞情況搶占點只適用于較低優(yōu)先級的對象),因此會超過寫入擴展任務的上下文。但是,固定優(yōu)先級搶占調度。

32267a4a-dcbc-11ed-bfe3-dac502259ad0.png

圖2.10 具有擴展任務的單堆棧管理

保證在擴展任務恢復時沒有更高優(yōu)先級的任務可以準備好運行(如果是這種情況,它就不能恢復)。

擴展任務管理需要告訴RTA-OS任務和ISR使用了多少堆棧。下面幾節(jié)描述各種配置參數(shù)。

2.6.2 強制性堆棧信息Mandatory Stack Information

計算出的最壞情況分派點定義了字節(jié)數(shù),相對于調用StartOS()時堆棧指針的地址,擴展任務需要從該地址開始。這些偏移量作為ROM數(shù)據(jù)存儲在擴展任務控制塊中,并在運行時添加到堆棧的基址中。

這意味著需要告訴RTA-OS有關堆棧使用的各種參數(shù)。捕獲的值是特定于端口的,您應該閱讀您的端口的目標/編譯器端口指南以獲得額外的指導。

RTA-OS提供了運行時特性,用于測量任務和ISR的最壞情況下的堆棧值。

通常,所有端口都將允許您指定以下值。所有數(shù)字均以字節(jié)為單位:

用于C啟動的堆棧(Stack used for C-startup,SpPreStartOS)在調用StartOS()時已經(jīng)在使用的堆棧量。

該值被簡單地添加到操作系統(tǒng)在運行時支持所有任務和中斷所需的總堆棧大小中。

通常,您使用它來獲得鏈接器必須分配的堆棧數(shù)量。

在計算最壞情況分派點時不需要這個值,可以安全地將其設置為零,除非您希望在堆棧使用情況報告中計算最壞情況的總體堆棧使用情況。

正常情況下,當操作系統(tǒng)配置發(fā)生變化時,該值不會改變。

空閑時使用的堆棧(Stack used when idle,SpStartOS)

操作系統(tǒng)處于空閑狀態(tài)(通常在Os_Cbk_Idle()內(nèi)部)時使用的最大堆棧量。這只是調用StartOS()時使用的堆棧與沒有任務或中斷運行時使用的堆棧之間的區(qū)別。如果沒有使用Os_Cbk_Idle(),該值可以為零。它必須包含在空閑狀態(tài)下被調用的任何函數(shù)所使用的堆棧。

正常情況下,當操作系統(tǒng)配置發(fā)生變化時,該值不會改變。

ISR激活的堆棧開銷(Stack overheads for ISR activation,SpIDisp)

與從task中激活任務相比,從ISR中激活任務所需的額外堆棧量。如果一個任務在類別2 ISR中被激活,并且該任務比任何當前運行的任務具有更高的優(yōu)先級,那么對于一些與激活優(yōu)先級較低的任務相比,目標操作系統(tǒng)可能需要使用更多的堆棧。這個值說明了這一點。在大多數(shù)目標上,這個值為零。

該值用于最壞情況下的堆棧大小計算。

當操作系統(tǒng)配置有較大變化時,該值可能會發(fā)生變化。

ECC任務的堆棧開銷(Stack overheads for ECC tasks,SpECC)

啟動ECC任務所需的額外堆棧量。ECC任務在啟動時需要比BCC任務在堆棧上保存更多的狀態(tài)。此值包含差值。

這個值可以通過測量堆棧值得到:

l在基本任務(向上)激活之前,立即在被激活任務的入口函數(shù)中。

l在擴展任務(向上)激活之前,立即在激活任務的入口函數(shù)中。

然后用第一個值減去第二個值。

當操作系統(tǒng)配置有較大變化時,該值可能會發(fā)生變化。還需要注意的是,如果你正在使用堆棧重定位(將不受信任的代碼堆棧對齊以適應MPU),那么你將需要減少調整量的值。

ISR的堆棧開銷(Stack overheads for ISR SpPreemption)

32630cc6-dcbc-11ed-bfe3-dac502259ad0.png

圖2.11 基本堆棧值

用于服務第二類ISR的堆棧數(shù)量。當二類ISR中斷一個任務時,它通常會在堆棧上放置一些數(shù)據(jù)。如果ISR測量堆棧以確定被搶占的任務是否超過了它的堆棧預算,那么它將高估堆棧使用情況,除非從測量的大小中減去這個值。

該值也用于計算系統(tǒng)最壞情況下的堆棧使用情況。該值可以通過在中斷之前測量堆棧值,并在測試期間立即在類別2 ISR的輸入函數(shù)中獲得。注意要準確地設置這個值。如果它的值太高,那么當發(fā)生減法時,就會發(fā)生32位下溢,并導致操作系統(tǒng)認為已經(jīng)檢測到預算超支。

當操作系統(tǒng)配置有較大變化時,該值可能會發(fā)生變化。

Note: 除了ISR (SpPreemption)的堆棧開銷外,所有的強制堆棧值都會在檢查期間添加到堆棧值中。這意味著指定比實際發(fā)生的更大的值是安全的。但是,ISR的堆棧開銷(SpPreemption)將從進入ISR時的堆棧指針的當前值中減去,以檢查被搶占的任務或ISR是否已經(jīng)超過了它的堆棧使用量。因此,在這里指定一個大的值可能會導致報告一個沒有發(fā)生的錯誤(即RTA-OS堆棧管理將報告一個“false positive”。

2.6.3 指定任務堆棧分配Specifying Task Stack Allocation

在只包含基本任務的系統(tǒng)中,沒有必要告訴RTA-OS任何堆棧分配,除非正在進行堆棧監(jiān)控。只需要在鏈接器/定位器中為應用程序分配一個足夠大的堆棧部分。這是單棧架構的好處之一。

對于使用擴展任務的應用程序,可以像以前一樣分配鏈接器部分,但是還必須告訴RTA-OS配置中優(yōu)先級低于最高優(yōu)先級擴展任務的每個任務的堆棧分配,即使它們是基本任務。RTA-OS使用堆棧分配信息為每個離線擴展任務計算最壞情況下的搶占點。

指定的堆棧分配是用于該任務的整個堆棧,包括:

?操作系統(tǒng)上下文

?任務主體中局部變量的空間

?任務體中調用的任何函數(shù)(以及它們的局部函數(shù))所需的空間

可以使用RTA-OS的堆棧度量特性來獲取堆棧分配的準確值。

Note: RTA-OS僅使用提供的堆棧信息來計算最壞情況下的搶占點。RTA-OS不保留任何堆??臻g。必須按照與普通應用程序相同的方式指定堆棧應用程序堆棧空間。

3281bee6-dcbc-11ed-bfe3-dac502259ad0.png

圖2.12顯示了如何配置堆棧分配。

圖2.12 堆棧分配配置Stack Allocation Configuration

雖然RTA-OS使用單堆棧模型,但在某些端口上,這并不一定意味著只使用一個物理堆棧。

可能是編譯器或硬件自動將數(shù)據(jù)強制放到不同的堆棧上。例如,TriCore設備使用CSA內(nèi)存快速保存呼叫上下文。RTA-OS將其視為等同于堆棧。當在你的配置中輸入堆棧值時,你應該提供兩個逗號分隔的值;第一個用于Supervisor堆棧,第二個用于Context堆棧。

即使有多個物理堆棧,RTA-OS仍然提供了單一堆棧架構的好處——當任務和/或isr共享優(yōu)先級時,每個物理堆棧上所需的堆棧空間可以疊加。但是,為了使堆棧分配正確工作,您需要指定每個堆棧上所需的空間。

如果您配置了需要此信息的目標,RTA-OS將要求您提供多個堆棧值。圖2.13顯示了這樣一個配置的對話框,其中有兩個堆棧:' Supervisor '和' Context '。

32bf9b26-dcbc-11ed-bfe3-dac502259ad0.png

圖2.13針對多個堆棧的堆棧分配配置Stack Allocation Configuration for multiple stacks

32dcca16-dcbc-11ed-bfe3-dac502259ad0.png

圖2.14 指定WaitEvent()堆棧分配

2.6.4 優(yōu)化擴展任務上下文保存Optimizing the Extended Task context save

回顧第2.6.1節(jié),每當擴展任務進入等待狀態(tài)時,RTA-OS保存任務的“等待事件堆棧”上下文,當任務重新進入運行狀態(tài)時,上下文將恢復。

RTA-OS將“等待事件堆?!鄙舷挛谋4嬖趦?nèi)部緩沖區(qū)中。默認情況下,RTAOS分配的緩沖區(qū)等于您為該任務指定的最壞情況堆棧分配。假設您的堆棧分配是正確的,這應該總是足以在調用WaitEvent()時保持最壞情況下的堆棧使用情況。

不過,大多數(shù)使用擴展任務的應用程序通常只從任務的入口函數(shù)調用WaitEvent()。此時,堆棧上只有少量本地數(shù)據(jù)(可能為零)。在使用擴展任務時,您可以通過僅分配足夠的緩沖區(qū)空間來保存最壞情況下的“等待事件堆?!鄙舷挛?,而不是任務所需的絕對最壞情況空間,從而最小化RTA-OS預留的RAM大小。

可以通過在WaitEvent()執(zhí)行時給出RTA-OS最差的值(圖4.14)來指定為這個緩沖區(qū)保留多少字節(jié)。請記住,最壞情況的值可能包括WaitEvent()調用本身使用的一些堆棧。獲得正確值的一種方法是從一個小值開始,一直增加它,直到在Os_Cbk_StackOverrunHook()調用中不再看到OS_ECC_WAIT錯誤。如果無法保存堆棧上下文,RTA-OS將不會將ECC TASK置于等待狀態(tài)。

Note: 如果保留等待事件()堆棧分配為“未定義的”,那么RTA-OS將默認使用您為堆棧分配指定的字節(jié)數(shù)。

使用默認值

雖然您應該為每個任務設置一個堆棧值,但RTA-OS允許您設置一個被所有任務使用的全局默認值。這可以在常規(guī)?默認堆棧值中找到。

如果沒有為任務配置堆棧分配,則RTA-OS將使用默認值:

l計算最壞情況下的堆棧偏移量

l配置等待事件(WaitEvent())保存/恢復區(qū)域

l堆棧監(jiān)控(當配置時)

特定于任務/ ISR的堆棧分配的規(guī)范將覆蓋默認值。

2.6.5 處理堆棧溢出Handling Stack Overrun

如果您提供給RTA-OS的堆棧分配數(shù)字是錯誤的(即它們太小),那么在運行時這是一個潛在的錯誤來源。

有三件事可能會出錯:

1. 當RTA-OS試圖分發(fā)補丁擴展任務時,由于堆棧指針的當前值高于計算出的最壞情況分派點,因此無法啟動擴展任務。這意味著堆棧上的一個(或多個)低優(yōu)先級任務消耗了太多空間。

后面章節(jié)中描述的堆棧監(jiān)視可用于確定哪個任務出現(xiàn)故障。

2. 擴展任務不能從等待狀態(tài)恢復,因為堆棧指針高于它應有的位置。當為擴展任務正在等待的事件調用SetEvent()并且擴展任務現(xiàn)在是系統(tǒng)中最高優(yōu)先級的任務時,可能會發(fā)生這種情況。

3.擴展任務不能進入等待狀態(tài),因為該任務當前使用的堆棧數(shù)量大于配置的' WaitEvent()堆棧'的大小。

當RTA-OS檢測到擴展任務堆棧管理的問題時,它將調用ShutdownOS(),錯誤代碼為E_OS_STACKFAULT。

如果你想調試這個問題,那么你可以啟用堆棧故障鉤子,如圖2.15所示。

32fea83e-dcbc-11ed-bfe3-dac502259ad0.png

圖2.15 使能Os_Cbk_StackOverrunHook()

#ifdef OS_STACKOVERRUNHOOK FUNC(void, OS_CALLOUT_CODE) Os_Cbk_StackOverrunHook(Os_StackSizeType Overrun, Os_StackOverrunType Reason) { /* Identify problem */ for(;;) { /* Do not return! */ } } #endif /* OS_STACKOVERRUNHOOK */

Example 2.1: Minimum recommended Os_Cbk_StackOverrunHook()

當配置了Os_Cbk_StackOverrunHook(),當發(fā)生堆棧故障時,RTA-OS將調用用戶提供的回調Os_Cbk_StackOverrunHook(),而不是關閉OS()。該回調被傳遞了兩個參數(shù):

1.溢出數(shù)的字節(jié)數(shù)

2.溢出原因

對于未啟用堆棧監(jiān)視的擴展任務系統(tǒng),溢出可以是以下情況之一:

?OS_ECC_START—擴展任務無法啟動,因為當前堆棧指針超過了構建時計算的最壞情況分派點。此故障的原因是一個(或多個)低優(yōu)先級任務超過了配置的堆棧分配。要解決這個問題,您需要確定哪個任務出錯了。棧監(jiān)控和測量章節(jié)解釋了如何使用RTA-OS的堆棧監(jiān)視特性來做到這一點。

?OS_ECC_RESUME—擴展任務不能從等待中恢復,因為當前堆棧指針超過了構建時計算的最壞情況分派點。此故障的原因是一個(或多個)低優(yōu)先級任務超過了配置的堆棧分配。

要解決這個問題,您需要確定哪個任務出錯了。棧監(jiān)控和測量章節(jié)解釋了如何使用RTA-OS的堆棧監(jiān)視特性來做到這一點。

?OS_ECC_WAIT—擴展任務使用的堆??臻g超過WaitEvent()設置的堆棧大小,無法進入等待狀態(tài)。要解決這個問題,您應該至少將WaitEvent()堆棧大小增加到溢出參數(shù)所指示的字節(jié)數(shù)。

2.7 實現(xiàn)任務Implementing Tasks

任務類似于C函數(shù),當它們被RTA-OS調用時,它會實現(xiàn)某種形式的系統(tǒng)功能。

TASK(task_identifier) { /* Your code */ }

Note: 不需要為任務輸入功能提供任何C函數(shù)原型。這些都是通過RTA-OS生成的Os.h頭文件提供的。

當任務開始運行時,將從任務輸入函數(shù)開始執(zhí)行。任務輸入函數(shù)是使用示例2.2中的C語法編寫的。

請記住,基本的任務是一次性的。這意味著它們從固定的任務入口點執(zhí)行,并在完成后終止。

示例2.3顯示了一個名為BCC_Task的基本任務的代碼。

#include TASK(BCC_Task) { do_something(); /* Task must finish with TerminateTask() or equivalent. */ TerminateTask(); }

Example 2.3: A Basic Task

現(xiàn)在,將示例2.3中的示例與示例2.4進行比較。示例2.4顯示,擴展的任務不一定需要終止,并且可以保持在一個循環(huán)中等待事件。

#include TASK(ECC_Task) { InitializeTheTask(); while (WaitEvent(SomeEvent)==E_OK) { do_something(); ClearEvent(SomeEvent); } /* Task never terminates. */ }

Example 2.4: Extended Task Waiting for Events

2.8 激活任務Activating Tasks

任務只有激活后才能運行。激活可以將任務從掛起狀態(tài)移動到就緒狀態(tài),也可以將另一個條目添加到就緒任務隊列(如果任務支持多個激活)。該任務將為每個激活運行一次。

超過激活計數(shù)是一個錯誤,當這種情況發(fā)生時,應用程序將生成E_OS_LIMIT錯誤(即使在標準構建狀態(tài)下)。

任務可以從兩個任務和(第2類)ISRs中激活。

激活任務并不會使任務立即開始執(zhí)行,它只是使任務準備好運行。然而,RTA-OS需要檢查激活的任務是否比當前運行的任務具有更高的優(yōu)先級,如果是,則導致上下文切換,以便新任務可以搶占當前運行的任務。

當您從另一個任務激活一個任務RTA-OS時,確切的行為取決于相對的任務優(yōu)先級。如果激活的任務優(yōu)先級高于當前運行的任務,則新激活的任務將搶占當前任務。否則,該任務將保持在就緒隊列中,直到它成為最高優(yōu)先級的就緒任務。在一個設計良好的實時系統(tǒng)中,一個任務激活一個更高優(yōu)先級的任務是不尋常的。通常isr捕獲系統(tǒng)觸發(fā)器,然后激活任務以執(zhí)行任何相關處理。反過來,這些任務可能激活較低優(yōu)先級的任務,以實現(xiàn)具有較長截止日期的觸發(fā)器響應。

觀察這一事實導致了RTA-OS中的一個主要優(yōu)化。如果指定任務從不激活高優(yōu)先級任務,RTA-OS可以消除測試每次激活后是否需要上下文切換的內(nèi)部代碼。這是通過選擇“禁止向上激活”優(yōu)化來配置的。

這類似于從ISR激活任務時的行為。所有ISR都有一個嚴格高于最高任務優(yōu)先級的優(yōu)先級。

當一個任務從ISR激活時,它永遠不會立即進入運行狀態(tài),因此不需要檢查上下文切換。

只有在離開ISR時才需要這樣的檢查。

2.8.1 直接激活Direct Activation

任務可以通過許多不同的方式激活。任務激活的基本機制是ActivateTask() API調用,它直接激活任務。ActivateTask(TaskID)調用將指定任務置于就緒狀態(tài)。ChainTask(TaskID)調用終止了調用任務(見2.11節(jié)),并將命名任務置于就緒狀態(tài)。

334240b2-dcbc-11ed-bfe3-dac502259ad0.png

2.8.2 間接激活Indirect Activation

除了直接激活任務外,還可以使用其他AUTOSAR OS機制間接激活任務。這些方法在后面的章節(jié)中有更詳細的描述。

報警激活(Activation by an Alarm)。對于系統(tǒng)中的每個告警,您可以指定每次告警過期時激活的任務。

#include TASK(Task1) { /* Task1 functionality. */ ActivateTask(Task2); TerminateTask(); } TASK(Task2) { /* Task2 functionality. */ ActivateTask(Task3); TerminateTask(); } TASK(Task3) { /* Task3 functionality. */ TerminateTask(); }

Example 2.5: Using Direct Activation Chains

通過調度表激活(Activation by a Schedule Table)。對于系統(tǒng)中的每個調度表,可以指定在表上的一個或多個到期點上激活的任務。

2.9 控制任務執(zhí)行順序Controlling Task Execution Ordering

在許多情況下,您需要限制特定任務的執(zhí)行順序。在基于數(shù)據(jù)流的設計中尤其如此,其中一個任務需要在另一個任務使用計算值之前執(zhí)行一些計算。如果執(zhí)行順序不受約束,則可能出現(xiàn)競態(tài)條件,應用程序行為將不可預知??梢酝ㄟ^以下方式控制任務的執(zhí)行順序:

?直接激活鏈(見2.9.1節(jié))。

?優(yōu)先級(見章節(jié)2.9.2)。

?非搶占任務

2.9.1 直接激活鏈Direct Activation Chains

當使用直接激活鏈來控制執(zhí)行順序時,任務對必須在進行調用的任務之后執(zhí)行的任務執(zhí)行ActivateTask()調用。

有三個任務Task1、Task2和Task3,它們必須按照Task1、Task2、Task3的順序執(zhí)行。

示例2.5給出了任務體示例。

圖2.16顯示了假設Task1優(yōu)先級最高,Task 3優(yōu)先級最低,這些任務將如何執(zhí)行。

33694270-dcbc-11ed-bfe3-dac502259ad0.png

圖2.16 控制任務執(zhí)行順序的直接激活

2.9.2 使用優(yōu)先級Using Priority Levels

約束任務執(zhí)行順序的優(yōu)先級級方法可以用來利用搶占調度策略的性質來控制激活順序。

回顧第2.1節(jié),在固定優(yōu)先級搶占調度下,調度器總是運行最高優(yōu)先級的任務。如果許多任務被釋放到就緒隊列中,它們將按優(yōu)先級順序執(zhí)行。這意味著您可以使用任務優(yōu)先級來控制執(zhí)行順序。

從前面的例子來看,在例2.5中,讓我們假設Task1的優(yōu)先級最高,Task3的優(yōu)先級最低。這意味著可以重寫任務主體以利用優(yōu)先級控制的激活。這可以在例2.6中看到。

圖2.17顯示了如何執(zhí)行這些任務。

#include TASK(Task1) { /* Task1 functionality. */ ActivateTask(Task2); /* Runs when Task1 terminates. */ /* More Task1 functionality. */ ActivateTask(Task3); /* Runs when Task2 terminates. */ TerminateTask(); } TASK(Task2) { /* Task2 functionality. */ TerminateTask(); } TASK(Task3) { /* Task3 functionality. */ TerminateTask(); }

Example 2.6: Using Priority Level Controlled Activation

3391c452-dcbc-11ed-bfe3-dac502259ad0.png

圖2.17 使用優(yōu)先級來控制任務的執(zhí)行順序

2.10 RTA-OS中的合作調度Co-operative Scheduling in RTA-OS

當一個任務是非搶占式運行時,它會阻止任何任務(包括那些高優(yōu)先級的任務)的執(zhí)行。然而,有時對于非搶占式任務來說,提供可以進行重調度的顯式位置是有用的。這比簡單地非搶先運行更有效,因為高優(yōu)先級任務對系統(tǒng)刺激的響應時間更短。在一個系統(tǒng)中,任務以非搶先的方式運行,并為重新調度提供點,這種系統(tǒng)被稱為協(xié)作調度系統(tǒng)。

Schedule() API調用可用于暫時消除非搶占任務和使用內(nèi)部資源的任務施加的搶占約束。

當調用Schedule()時,允許運行任何優(yōu)先級高于調用任務的就緒任務。Schedule()直到所有高優(yōu)先級任務結束才返回。

例2.7展示了一個非搶占任務Cooperative,它包括一系列函數(shù)調用。一旦啟動,每個函數(shù)運行到完成時不會搶占,但是任務本身可以在每個函數(shù)調用之間被搶占。

圖2.18顯示了Task1和Task2這兩個相互協(xié)作的任務在戰(zhàn)時如何發(fā)揮作用。白色部分表示不可搶占的代碼部分。

#include TASK(Cooperative){ Function1(); Schedule();/* Allow preemption */ Function2(); Schedule();/* Allow preemption */ Function3(); Schedule();/* Allow preemption */ Function4(); TerminateTask(); }

Example 2.7: Making a task run co-operatively

33b641ce-dcbc-11ed-bfe3-dac502259ad0.png

圖2.18 合作任務Co-operative tasks

2.10.1 優(yōu)化Schedule() API Optimizing out the Schedule() API

Schedule()在完全搶占式系統(tǒng)中沒有用處。如果不打算使用它,可以使用“優(yōu)化,RTA-OS, disallow Schedule()”來禁止在rtaoscfg中調用Schedule()。如果不允許對Schedule()的調用,那么將看到系統(tǒng)的最差情況堆棧需求降低了。

2.11 終止任務Terminating Tasks

在AUTOSAR操作系統(tǒng)中終止的任務必須通過API調用來告訴操作系統(tǒng)正在發(fā)生這種情況。AUTOSAR OS標準為任務終止定義了兩個API調用。必須使用其中一個來終止任何任務。這些API調用是:

?TerminateTask ()

?ChainTask (TaskID)

當一個任務完成時,它必須調用這些API中的一個。這確保RTA-OS可以正確地調度下一個準備運行的任務。

TerminateTask()強制調用任務進入掛起狀態(tài)。然后RTA-OS將在就緒狀態(tài)下運行下一個優(yōu)先級最高的任務。

ChainTask(TaskID)終止調用任務,激活任務TaskID。因此,該API就像執(zhí)行一個TerminateTask(),然后立即執(zhí)行ActivateTask(TaskID)。鏈接任務將指定的任務置于就緒狀態(tài)。

2.11.1 優(yōu)化RTA-OS中的任務終止Optimizing Termination in RTA-OS

AUTOSAR OS標準允許任務在任何時候調用任務終止API調用,包括在嵌套很深的函數(shù)調用集中。

這是一種糟糕的編程實踐——相當于goto的使用。

在運行時,RTA-OS必須存儲允許它在任務終止時清除堆棧的信息,而不是入口函數(shù)。這通常使用setjmp/longjmp對來完成。

例2.8顯示了對其他函數(shù)進行嵌套調用的任務。Task1運行時,它調用Function1()。

Function1()然后調用Function2()。Function2()包含可以終止調用任務的代碼(在本例中是Task1)。

然而,單堆棧架構的一個關鍵好處是,在其入口函數(shù)中終止的任務可以簡單地返回- TerminateTask()不需要做任何事情。如果所有的任務都沒有終止,或者只是在它們的入口函數(shù)中終止,那么RTA-OS保存的允許從任何地方返回的上下文都不需要存儲。

RTA-OS允許您使用快速終止優(yōu)化(Optimizations?fast Terminate)來開發(fā)良好的應用程序設計。當所有執(zhí)行TerminateTask()或ChainTask() api的任務只在它們的entry函數(shù)中執(zhí)行此優(yōu)化時,您可以啟用此優(yōu)化。優(yōu)化告訴RTA-OS不生成代碼以節(jié)省不必要的上下文,從而節(jié)省堆??臻g。

#include void Function1(void) { ... Function2(); ... } void Function2(void) { if (SomeCondition) { TerminateTask(); } } TASK(Task1) { /* Make a nested function call. */ Function1(); /* Terminate the task in the entry function*/ TerminateTask(); }

Example 2.8: Terminating a Task

2.12 延遲任務Delayed Tasks

OS選項“支持延遲任務執(zhí)行”可用于添加對api Os_SetDelayedTasks()、Os_AddDelayedTasks()和Os_RemoveDelayedTasks()的支持。

這些api允許您告訴RTA-OS延遲一組任務的執(zhí)行。延遲任務可以被激活,但直到從集合中刪除它們才會實際運行。

Os_SetDelayedTasks()用于指定需要延遲哪些任務。如果一個任務在調用之前被延遲,但它不在新的延遲任務集中,那么如果它的優(yōu)先級高于調用方,那么它將在此調用返回之前執(zhí)行。

您必須只設置在調用核心上運行的任務。

Os_AddDelayedTasks()用于向已有的延遲任務集中添加任務。多次添加任務是允許的,但沒有效果。必須只添加在調用核心上運行的任務。

Os_RemoveDelayedTasks()用于從去袒護的任務集中移除任務。如果被刪除的任務的優(yōu)先級高于調用方,則它們將在此調用返回之前執(zhí)行。

注意,如果某個特定核心上的任務共享優(yōu)先級,則必須指定共享優(yōu)先級的所有任務或不指定優(yōu)先級。當啟用延遲任務時,任務狀態(tài)模型變得有點復雜。下表試圖解釋可能的轉換。

33fa0dbe-dcbc-11ed-bfe3-dac502259ad0.png

2.13 空閑機制The Idle Mechanism

當沒有任務或ISR要運行時,任何搶占式操作系統(tǒng)都必須有事可做。在AUTOSAR OS中,這是通過空閑機制實現(xiàn)的。在RTA-OS中,當沒有任務或ISR要運行時,操作系統(tǒng)將處于繁忙等待循環(huán)中,什么也不做。

但是,可以通過聲明一個名為Os_Cbk_Idle的回調來提供您自己的空閑機制實現(xiàn),從而覆蓋默認行為。

Os_Cbk_Idle的行為與任務相同,除了:

?無法激活

?不能終止

?它不能等待事件

?它不能被束縛

?不能使用內(nèi)部資源

Os_Cbk_Idle的優(yōu)先級比系統(tǒng)中的任何任務都低,因此它只在沒有準備運行的任務(或ISR)時運行。

因此,空閑機制為您提供了一個幾乎完全不受系統(tǒng)開銷影響的“額外任務”。

例2.9顯示了Os_Cbk_Idle用于控制RTA的實現(xiàn)。

Os_Cbk_Idle在退出時返回一個布爾值,告訴RTA-OS是否再次調用Os_Cbk_Idle。當返回TRUE時,RTA-OS立即再次調用Os_Cbk_Idle。當返回FALSE時,RTA-OS停止調用Os_Cbk_Idle,并進入繁忙等待循環(huán)的默認行為。

#include FUNC(boolean, OS_CALLOUT_CODE) Os_Cbk_Idle(void) { #ifdef OS_TRACE CheckTraceOutput(); UploadTraceData(); #endif /* OS_TRACE */ return TRUE; } OS_MAIN() { /* System hardware initialization. */ StartOS(OSDEFAULTAPPMODE); /* The call never returns */ }

2.14 任務開始和結束的構子函數(shù)Pre and Post Task Hooks

假設需要在每個任務開始之前和/或在每個任務結束之后執(zhí)行一些代碼,例如分析執(zhí)行的跟蹤??梢允褂肁UTOSAR OS提供的PreTask和PostTask鉤子來實現(xiàn)這一點。

當任務進入運行狀態(tài)時,RTA-OS會調用PreTask鉤子。

這意味著當一個任務在搶占后恢復時,PreTask鉤子也將被調用。

當任務移出運行狀態(tài)時,RTA-OS會調用PostTask鉤子。

PostTask鉤子將在任務終止時調用,并且每次任務被搶占時調用。

圖2.19顯示了相對于任務搶占,PreTask和PostTask鉤子被調用的位置。

這兩個鉤子只有在配置時才被調用。圖2.20顯示了如何啟用鉤子。

3416d70a-dcbc-11ed-bfe3-dac502259ad0.png

圖2.19 PreTaskHook()和PostTaskHook()相對于任務搶占

343b1854-dcbc-11ed-bfe3-dac502259ad0.png

圖2.20 Enabling the PreTaskHook() and PostTaskHook()

FUNC(void, OS_CALLOUT_CODE) PreTaskHook(void) { /* PreTask hook code. */ } FUNC(void, OS_CALLOUT_CODE) PostTaskHook(void) { /* PostTask hook code. */ }

Example 4.10: The PreTaskHook and PostTaskHook

例2.10展示了鉤子應該如何出現(xiàn)在代碼中。

在任務進入和退出時以及每次搶占/恢復時調用PreTask和PostTask鉤子。這意味著可以使用這些鉤子記錄應用程序的執(zhí)行跟蹤。由于應用程序中的所有任務都必須使用相同的PreTask和PostTask鉤子,因此有必要使用GetTaskID() API調用來確定在進入鉤子例程時哪個任務已經(jīng)或將要運行。

RTA-OS定義了一組宏,這些宏僅在對應的鉤子被啟用時才被定義。這些宏被稱為:

?OS_PRETASKHOOK

?OS_POSTTASKHOOK

#ifdef OS_PRETASKHOOK FUNC(void, OS_CALLOUT_CODE) PreTaskHook (void) { /* Your code */ } #endif /* OS_PRETASKHOOK */

Example 2.11: Conditional Compilation of PreTaskHook

這允許編寫代碼,其中可以有條件地編譯鉤子,如示例2.11所示。

2.15 通過搶占保存硬件寄存器Saving Hardware Registers across Preemption

RTA-OS在上下文切換時盡可能少地保存上下文—只保存操作系統(tǒng)正確操作的上下文。但是,可能會發(fā)現(xiàn)需要在運行時保存和恢復附加的依賴于應用程序的上下文。例如,可能有使用浮點寄存器的任務,因此需要通過上下文切換保存微控制器的浮點上下文。

可以選擇使用PreTask和PostTask鉤子和應用程序管理的堆棧手動實現(xiàn)這一點。但是,很難在不改變操作系統(tǒng)配置的情況下優(yōu)化這種類型的實現(xiàn)。可以:

?始終保存每個交換機上的上下文到一個任務,然后在每個交換機上恢復。這個模型意味著你可能會做不必要的保存和恢復(例如,當切換到一個不使用它的任務時,保存一個寄存器集);或

?離線計算所需的保存,然后編寫一個更復雜的鉤子對,使用GetTaskID()/GetISRID()來計算是否需要保存/恢復。這個模型是脆弱的,因為對配置的更改,例如添加新的任務/ isr或修改優(yōu)先級,將意味著需要重新工作。為了避免這些問題,RTA-OS提供了一種簡單的通用機制,用于保存特定于用戶的上下文和操作系統(tǒng)上下文。RTA-OS能夠利用其優(yōu)先級空間的knowl edge來精確計算哪些任務需要在運行時保存寄存器集,從而優(yōu)化掉不必要的保存,節(jié)省上下文切換所需的時間和堆棧。例如:

?如果你只有一個任務或二類ISR使用一個給定的寄存器集,那么不需要保存或恢復。

?如果多個任務使用相同的寄存器集,但不能同時執(zhí)行(因為它們不可搶占,共享內(nèi)部資源或共享優(yōu)先級),那么RTA-OS不需要保存寄存器集。

346e5980-dcbc-11ed-bfe3-dac502259ad0.png

圖2.21 Register saving in action

?上下文切換到使用寄存器集的最低優(yōu)先級任務不需要進行保存,因為可以保證沒有其他任務可以使用該集(因為如果高優(yōu)先級任務正在使用寄存器集,則最低優(yōu)先級任務不可能運行)。

?類似地,從使用寄存器集的最高優(yōu)先級任務進行上下文切換不需要進行保存,因為沒有更高優(yōu)先級的任務使用寄存器集,因此不會破壞上下文。

圖2.21顯示了由任務1、3和5共享的寄存器集??梢钥吹剑敳恍枰4鏁r(當切換到不使用寄存器集的任務時),就不會進行上下文保存。

需要保存的每個寄存器集都需要在配置時聲明給RTA-OS。Rtaosgen使用聲明定義兩個回調函數(shù),必須提供它們來保存和恢復寄存器集。圖2.22顯示了三個寄存器集的定義。

使用寄存器集的每個任務都需要在運行時聲明這一點,以便rtaosgen可以計算需要保存的最大集數(shù)。圖2.23顯示了如何為任務執(zhí)行此操作。

RTA-OS不知道如何或在哪里保存和恢復寄存器集——它只知道需要保存多少次以及何時保存和重新存儲它們。對于定義的每個寄存器集,RTA-OS生成一個宏OS_REGSET__SIZE,用于定義所需的最壞情況下的寄存器集保存數(shù)量。應該在應用程序代碼中使用它來定義一個大小為OS_REGSET__SIZE的數(shù)組,其中數(shù)組的每個元素都包含保存的寄存器集。

34913f2c-dcbc-11ed-bfe3-dac502259ad0.png

圖2.22 寄存器集定義

34c97e3c-dcbc-11ed-bfe3-dac502259ad0.png

圖23. 在一個任務中使用寄存器集

typedef volatile uint32 RegType; #define VOLATILEREGISTER (*(RegType*)(0xDEAFBEEF)) uint32 VolatileRegisterSaveArea[OS_REGSET_VolatileRegister_SIZE]; FUNC(void, OS_CALLOUT_CODE) Os_Cbk_RegSetSave_VolatileRegister(Os_RegSetDepthType Depth) { VolatileRegisterSaveArea[Depth] = VOLATILEREGISTER; } FUNC(void, OS_CALLOUT_CODE) Os_Cbk_RegSetRestore_VolatileRegister(Os_RegSetDepthType Depth) { VOLATILEREGISTER = VolatileRegisterSaveArea[Depth]; }

Example 2.12: Register Set Save And Restore

你還需要為保存和恢復操作提供回調函數(shù):

?Os_Cbk_RegSetSave_(Os_RegSetDepthType Depth)在需要保存寄存器集時被RTA-OS調用。

?Os_Cbk_RegSetRestore_(Os_RegSetDepthType Depth)在需要恢復寄存器集時被RTA OS調用。

兩個回調函數(shù)都傳遞了一個Depth值,該值指示要保存或恢復的寄存器集。

例2.12顯示了回調函數(shù)應該如何出現(xiàn)在你的代碼中。

2.16 小結

?任務是一個并發(fā)活動。

?有兩類任務:基本任務和擴展任務。

?任務可以共享優(yōu)先級,但建議不要這樣做。

?根據(jù)優(yōu)先級安排任務。

?當一個高優(yōu)先級的任務準備好運行時,它將搶占低優(yōu)先級的任務,但它不會搶占任何已配置為非搶占的任務。

?任務以就緒、運行、掛起或等待狀態(tài)存在(但是,只有已擴展的任務可以進入等待狀態(tài))。

?如果一個任務終止,它必須調用TerminateTask()或ChainTask(TaskID)來終止。

?所有任務在其入口函數(shù)中終止的系統(tǒng)可以使用“快速終止”優(yōu)化來最小化堆棧使用和上下文切換時間。

?任務只能在處于掛起狀態(tài)時被激活,除非指定了多個激活。?PreTask和PostTask鉤子允許你在任務開始前和結束后執(zhí)行代碼。這可用于在運行時分析應用程序。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 操作系統(tǒng)

    關注

    37

    文章

    7152

    瀏覽量

    125582
  • AUTOSAR
    +關注

    關注

    10

    文章

    380

    瀏覽量

    22667
  • 調度器
    +關注

    關注

    0

    文章

    98

    瀏覽量

    5502

原文標題:符合AUTOSAR標準的RTA-OS --Task詳解

文章出處:【微信號:汽車電子嵌入式,微信公眾號:汽車電子嵌入式】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    介紹AUTOSAR支持的四種功能安全機制

    內(nèi)存分區(qū)用于解決不同軟件組件之間的互相干擾,造成對內(nèi)存存儲的數(shù)據(jù)段或代碼段的篡改,需要限制對內(nèi)存和內(nèi)存映射的硬件外設的訪問。在AUTOSAR架構下,分區(qū)是以OS-Application為對象劃分
    發(fā)表于 06-10 17:33

    AUTOSAR功能安全機制之內(nèi)存分區(qū)與實現(xiàn)

    AUTOSAR中稱為Runnables?! unnables不能由它們自己執(zhí)行;它們必須分配給 OS的可執(zhí)行實體。可以通過將Runnables的函數(shù)調用插入OS任務主體來執(zhí)行此類分配?! ∪缓?/div>
    發(fā)表于 09-19 15:55

    “E:\NXP\AUTOSAR\S32K_AUTOSAR_OS_4_0_98_RTM_1_0_0sample\standard\sc1”編譯時無法生成sample1_cfg.o怎么解決?

    ccarm_oil /obj/Os_prop.h\"" E:\\NXP\\AUTOSAR\\AS32K_AUTOSAR4098 \\樣本\\標準\\sc1\\output_gccar
    發(fā)表于 04-06 07:42

    RTA-OS實時操作系統(tǒng)中的Task對象

      OSEK是由歐洲自動化協(xié)會對汽車電氣制定的開放式系統(tǒng),全程為OSEK/VDX。RTA-OS是基于OSEK OS符合AUTOSAR規(guī)范的OS
    的頭像 發(fā)表于 04-15 16:43 ?4081次閱讀

    經(jīng)緯恒潤自主研發(fā)出符合AUTOSAR標準的軟件產(chǎn)品

    INTEWORK-EAS(ECU AUTOSAR Software,以下簡稱EAS)是經(jīng)緯恒潤自主研發(fā),符合 AUTOSAR 標準的軟件產(chǎn)品。解決方案涵蓋了嵌入式
    的頭像 發(fā)表于 05-12 17:50 ?2639次閱讀

    開發(fā)支持符合AUTOSAR標準的軟件組件的建模特定領域的語言

    開發(fā)支持符合AUTOSAR標準的軟件組件的建模特定領域的語言。支持建模軟件組件的應用是基于TextX python模塊和內(nèi)部開發(fā)的建??蚣?。
    的頭像 發(fā)表于 10-08 11:19 ?1324次閱讀

    RTA OS系列介紹01-Task

    AUTOSAR OS主要包含Task, ISRs, Events, Resources, Application, Counter, Alarms, Schedule Table等OS
    的頭像 發(fā)表于 12-21 14:13 ?2797次閱讀

    Events(事件)概述、配置及使用方法

    在《RTA-OS系列介紹-Task》部分我們介紹了任務分為基礎任務與擴展任務,兩者的主要區(qū)別為,擴展任務多了waiting狀態(tài),那Waiting狀態(tài)等待的是什么呢?其實就是我們今天要介紹
    的頭像 發(fā)表于 01-12 10:27 ?7686次閱讀

    簡析符合AUTOSAR標準RTA-OS功能

    RTA-OS是一種靜態(tài)可配置的搶占式實時操作系統(tǒng)(RTOS),用于高性能、資源受限的應用程序。
    的頭像 發(fā)表于 02-10 10:44 ?5976次閱讀

    符合AUTOSAR標準RTA-OS--Interrupts介紹

    中斷提供了應用程序與現(xiàn)實世界中發(fā)生的事情之間的接口。例如,你可以使用中斷來捕捉被按下的按鈕,來標記時間的流逝或捕捉一些其他事件。
    的頭像 發(fā)表于 04-26 09:31 ?5978次閱讀
    <b class='flag-5'>符合</b><b class='flag-5'>AUTOSAR</b><b class='flag-5'>標準</b>的<b class='flag-5'>RTA-OS</b>--Interrupts介紹

    符合AUTOSAR標準RTA-OS-Resources詳解

    訪問需要在任務和ISR之間共享的硬件或數(shù)據(jù)可能是不可靠和不安全的。這是因為當較低優(yōu)先級的任務或ISR正在更新共享數(shù)據(jù)時,可能會發(fā)生任務或ISR搶占。
    的頭像 發(fā)表于 05-06 09:28 ?4455次閱讀
    <b class='flag-5'>符合</b><b class='flag-5'>AUTOSAR</b><b class='flag-5'>標準</b>的<b class='flag-5'>RTA-OS</b>-Resources<b class='flag-5'>詳解</b>

    AUTOSAR ComM功能及配置參數(shù)詳解

    AUTOSAR ComM模塊的分享分為ComM模塊概念詳解和ComM模塊配置及代碼分析
    的頭像 發(fā)表于 06-01 10:00 ?1w次閱讀
    <b class='flag-5'>AUTOSAR</b> ComM功能及配置參數(shù)<b class='flag-5'>詳解</b>

    符合AUTOSAR標準RTA-OS--Counters介紹

    計數(shù)器以tick為單位記錄操作系統(tǒng)中發(fā)生了多少“事情”。滴答是一個抽象的單位。
    的頭像 發(fā)表于 06-25 09:04 ?3572次閱讀
    <b class='flag-5'>符合</b><b class='flag-5'>AUTOSAR</b><b class='flag-5'>標準</b>的<b class='flag-5'>RTA-OS</b>--Counters介紹

    一文入門AUTOSAR OS

    Autosar OsAutosar 框架中上至RTE 下至驅動,中間可以和BSW 基礎模塊進行交互。是整個autosar 框架下最重要的組成部分。
    的頭像 發(fā)表于 06-29 10:34 ?5402次閱讀
    一文入門<b class='flag-5'>AUTOSAR</b> <b class='flag-5'>OS</b>

    AUTOSAR OS操作系統(tǒng)功能特性

    AUTOSAR OS AUTOSAR OS(AUTomotive Open System ARchitecture Operating System)是
    的頭像 發(fā)表于 10-27 16:55 ?2631次閱讀