正文
計數(shù)器以tick為單位記錄操作系統(tǒng)中發(fā)生了多少“事情”。滴答是一個抽象的單位。
這是由你來決定你想要一個滴答的意思。
可以這樣定義tick:
?時間Time,例如毫秒,微秒,分鐘等,然后計數(shù)器告訴你已經(jīng)過去了多少時間。
?旋轉(zhuǎn)Rotation,例如以度或分鐘為單位,在這種情況下,計數(shù)器會告訴你物體旋轉(zhuǎn)了多少。
?按鈕按下Button Presses,在這種情況下,計數(shù)器會告訴你按鈕被按了多少次。
?錯誤Errors,在這種情況下,計數(shù)器計算錯誤發(fā)生的頻率。
一個ISR(有時是一個任務(wù))用于驅(qū)動一個計數(shù)器。驅(qū)動程序負責(zé)進行正確的RTA-OS API調(diào)用來“tick”計數(shù)器,或者告訴RTA-OS計數(shù)器已經(jīng)“tick”到一個必需的值。
6.1配置計數(shù)器Configurting Counters
每個計數(shù)器都有4個強制性屬性:
Name 是計數(shù)器的名稱。RTA-OS使用與計數(shù)器具有相同名稱的標識符為每個計數(shù)器創(chuàng)建一個句柄。
Type 定義計數(shù)器模型。AUTOSAR提供兩種型號
軟件Software計數(shù)器是由操作系統(tǒng)內(nèi)部維護的計數(shù)值。User需要提供一個計數(shù)器驅(qū)動程序,告訴RTA-OS將計數(shù)器增加一個tick。在6.2.1節(jié)中提供了進一步的細節(jié)。
硬件Hardware計數(shù)器是由外設(shè)維護的計數(shù)值。User需要提供一個計數(shù)器驅(qū)動程序,該驅(qū)動程序告訴操作系統(tǒng)何時已經(jīng)過了請求的tick數(shù)。操作系統(tǒng)還將要求您的驅(qū)動程序支持支持RTA-OS用于在運行時管理外圍設(shè)備的回調(diào)例程的實現(xiàn)。章節(jié)6.2.2提供了進一步的細節(jié)。
當(dāng)需要相對較低的分辨率(例如一毫秒或更高)時,軟件計數(shù)器就足夠了。當(dāng)需要非常高的分辨率(例如在微秒范圍內(nèi)),或者需要將RTA-OS中的任務(wù)調(diào)度精確地同步到外部源(例如TPU或全局(網(wǎng)絡(luò))時間源)時,應(yīng)該使用硬件計數(shù)器。
Maximum Value定義計數(shù)器的最大計數(shù)值。在達到最大允許值后,所有計數(shù)器在刻度上自動歸零。對于16位計數(shù)器將為65535(216?1),對于32位計數(shù)器將為4294967295(232?1)。這對應(yīng)于AUTOSAR OS計數(shù)器屬性MAXALLOWEDVALUE。端口的最大可能計數(shù)器值由文件Os.h中TickType類型的大小決定。
集成指南:對于硬件計數(shù)器,必須確保最大匹配值+1等于外圍設(shè)備的模量。
Minimum Cycle最小周期定義在為Alarm或者schedule table偏移量設(shè)置周期值時允許的最短刻度數(shù)。在大多數(shù)情況下,希望它是1個刻度。但是,如果希望構(gòu)建的系統(tǒng)在計數(shù)器上強制執(zhí)行最小的警報間隔,那么可以選擇更大的值。這對應(yīng)于AUTOSAR OS計數(shù)器屬性MINCYCLE。
Ticks per base是一個屬性,可用于定義計數(shù)器上每個刻度所需的基礎(chǔ)計數(shù)器驅(qū)動刻度的數(shù)量??梢詾檫@個屬性賦任何值,因為RTA-OS不使用它。這對應(yīng)于AUTOSAR操作系統(tǒng)屬性TICKSPERBASE。
還有一個附加的可選屬性:
Seconds Per Tick以秒為單位定義計數(shù)器滴答的持續(xù)時間。如果想要使用AUTOSAR OS提供的刻度/時間轉(zhuǎn)換功能,則應(yīng)該定義此選項。進一步的細節(jié)在第6.5節(jié)中給出。
圖6.1 聲明一個計數(shù)器
6.2 計數(shù)器驅(qū)動Conuter Drivers
RTA-OS不控制任何硬件來提供計數(shù)器驅(qū)動程序。這使得RTA-OS非常容易與任何tick源集成,例如計時器滴答,錯誤計數(shù),按鈕按壓,TPU外設(shè)等。這意味著需要為在RTA-OS中聲明的每個計數(shù)器提供驅(qū)動程序,并將其接口到操作系統(tǒng)。
驅(qū)動程序和計數(shù)器之間的接口取決于計數(shù)器的類型:
Software Counters由API調(diào)用遞增。
Hardware Counters該計數(shù)值保存在外部硬件外圍設(shè)備中。應(yīng)用程序必須提供一個更復(fù)雜的驅(qū)動程序,該驅(qū)動程序告訴RTA-OS請求的滴答數(shù)已經(jīng)過了。RTA-OS使用特殊的回調(diào)來設(shè)置請求的tick數(shù),取消請求,獲取當(dāng)前計數(shù)值并獲取計數(shù)器的狀態(tài)。
6.2.1 軟件計數(shù)器驅(qū)動Software Counter Drivers
對于每個軟件計數(shù)器,需要提供提供刻度的驅(qū)動程序。RTA-OS在StartOS()期間將所有軟件計數(shù)器初始化為零并向上計數(shù)。
軟件計數(shù)器驅(qū)動模型在AUTOSAR OS中標準化,如圖6.2所示。
圖6.2 Ticked Counter Driver Model
實現(xiàn)軟件計數(shù)器:
使用API調(diào)用IncrementCounter(CounterID)來增加RTA-OS中保存的計數(shù)器值。當(dāng)向MAXALLOWEDVALUE中添加1時,軟件計數(shù)器會自動歸零。
可以從應(yīng)用程序代碼中的大多數(shù)地方調(diào)用IncrementCounter(CounterID)。計數(shù)器最常見的用途之一是為RTA-OS提供基于Alarm或Schedule table激活任務(wù)的時間基礎(chǔ)。在這種情況下,需要提供一個周期性計時器中斷,在每次到期時調(diào)用IncrementCounter(CounterID)。
例6.1展示了毫秒中斷如何驅(qū)動一個名為TimeCounter的計數(shù)器。
#includeISR(HandleTimerInterrupt) { DismissTimerInterrupt(); IncrementCounter(TimeCounter); }
Example 6.1: Using a periodic interrupt to tick a software counter
軟件計數(shù)器的另一個常見用途是作為容錯系統(tǒng)的一部分,在超過錯誤閾值時需要采取某些操作。軟件計數(shù)器可用于記錄錯誤的數(shù)量,然后可以使用警報來觸發(fā)恢復(fù)操作(例如,激活錯誤恢復(fù)任務(wù))。
例6.2展示了名為Critical的任務(wù)如何在名為ErrorCounter的計數(shù)器上記錄錯誤。
#includeTASK(Critical){ ... if (Error) { IncrementCounter(ErrorCounter); } ... TerminateTask(); }
Example 6.2: Using a periodic Task to tick a software counter
靜態(tài)計數(shù)器接口Static Counter Interface:
由于AUTOSAR API調(diào)用將計數(shù)器的名稱作為參數(shù),這意味著RTA-OS必須在更新OS數(shù)據(jù)結(jié)構(gòu)之前在內(nèi)部取消對參數(shù)的引用。這也意味著編譯器需要在進入時將參數(shù)壓入堆棧。
然而,通常情況下,在構(gòu)建時就知道將從何處計時哪個計數(shù)器??赡苄枰獜闹袛嗵幚沓绦蝌?qū)動計數(shù)器。
RTA-OS認識到這一點,并為配置文件中聲明的每個計數(shù)器生成一個專用的API調(diào)用Os_IncrementCounter_
集成指南:API調(diào)用Os_IncrementCounter_
例如,考慮一個包含兩個計數(shù)器的應(yīng)用程序:一個名為TimeCounter,另一個名為AngularCounter。rtaosgen將生成例6.3中所示的兩個API調(diào)用。
為定時器和角中斷提供服務(wù)的中斷處理程序必須調(diào)用這些API調(diào)用。
例6.4展示了這些中斷處理程序。
#includeISR(HandleTimerInterrupt) { ServiceTimerInterrupt(); Os_IncrementCounter_TimeCounter(); } ISR(HandleAngularInterrupt) { ServiceAngularInterrupt(); Os_IncrementCounter_AngularCounter(); }
Example 6.4: Interrupt Handlers for Example 6.3
#includeISR(MillisecondInterrupt) { ServiceTimerInterrupt(); Os_IncrementCounter_Counter1(); Os_IncrementCounter_Counter2(); ... Os_IncrementCounter_CounterN(); }
Example 6.5: Making multiple calls to the static software counter interface
如果您有多個軟件計數(shù)器,您需要以相同的速率tick,可以在處理程序中進行多個Os_IncrementCounter_
對于聲明的每個計數(shù)器,都有一個Os_IncrementCounter_
6.2.2 硬件計數(shù)器驅(qū)動Hardware Counter Drivers
對于每個硬件計數(shù)器,User需要提供調(diào)用RTA-OS的硬件計數(shù)器驅(qū)動程序和RTA-OS使用的一組回調(diào)。與軟件計數(shù)器一樣,RTA-OS提供了一個定義良好的接口,用于將高級計數(shù)器驅(qū)動程序連接到操作系統(tǒng)。
集成指南:AUTOSAR OS標準沒有指定處理硬件計數(shù)器的標準API調(diào)用。如果要將應(yīng)用程序從另一個操作系統(tǒng)移植到RTA-OS,則可能需要更改硬件計數(shù)器驅(qū)動程序API調(diào)用。
對于每個硬件計數(shù)器,RTA-OS知道該計數(shù)器驅(qū)動的下一個動作是什么,是使警報過期,還是處理調(diào)度表上的過期點,或者兩者兼而有之。RTA-OS還知道在發(fā)生這種情況之前需要經(jīng)過多少滴答。這被稱為匹配值。
圖6.3 Advanced Counter Driver Model
當(dāng)使用軟件計數(shù)器時,驅(qū)動程序會在每次計時結(jié)束時告訴RTA-OS。RTA-OS在內(nèi)部對刻度進行計數(shù),當(dāng)達到匹配值時,采取操作。然后RTA-OS計算下一個匹配值并重復(fù)該過程。
相比之下,當(dāng)使用硬件計數(shù)器時,RTA-OS通過回調(diào)函數(shù)告訴驅(qū)動程序何時需要進行下一個操作。外設(shè)計算請求的滴答數(shù),并在正確的滴答數(shù)耗盡時生成中斷。在中斷處理程序中,可以調(diào)用Os_AdvanceCounter_CounterID() API來告訴RTA-OS處理CounterID上的下一個操作。RTA-OS這樣做,然后重復(fù)這個過程。
通常,User將使用中斷來驅(qū)動軟件和硬件計數(shù)器。對于軟件計數(shù)器,無論RTA-OS是否有任何事情要做,每個計數(shù)器滴答都會發(fā)生中斷。對于硬件計數(shù)器,只有當(dāng)RTA-OS需要做某事時才會發(fā)生中斷。這意味著硬件計數(shù)器將中斷干擾減少到所需的絕對最小值。
Advancing Hardware Counters
User使用API調(diào)用Os_AdvanceCounter_
集成指南:User負責(zé)編寫調(diào)用Os_AdvanceCounter_
Os_AdvanceCounter_
Callback Functions
對于軟件計數(shù)器,RTA-OS在內(nèi)部計算經(jīng)過的滴答數(shù)。這意味著RTA-OS總是知道當(dāng)前的計數(shù)器值,在下一次到期之前有多少個滴答等等。
對于硬件計數(shù)器,外設(shè)計算經(jīng)過的滴答數(shù)。這意味著RTA-OS必須告訴硬件計數(shù)器它需要計數(shù)多少個節(jié)拍,并且必須詢問外設(shè)當(dāng)前的計數(shù)值,到下一個到期的節(jié)拍數(shù)等。
這種交互是使用回調(diào)函數(shù)在RTA-OS和您想用作計數(shù)器驅(qū)動程序的任何類型的硬件外設(shè)之間進行接口的?;卣{(diào)函數(shù)的確切功能性取決于用作硬件計數(shù)器驅(qū)動程序的外設(shè)。
然而,通過一個簡短的概述,需要四個回調(diào):
Os_Cbk_Set_
這個回調(diào)為下一個動作到期時發(fā)生的中斷設(shè)置狀態(tài)。回調(diào)函數(shù)被傳遞一個計數(shù)器的絕對值,在這個計數(shù)器上應(yīng)該發(fā)生一個動作。對于計數(shù)器,這個回調(diào)在兩種不同的情況下使用:
1. 開始Starting
當(dāng)Schedule Table或Alarm在計數(shù)器上啟動時,設(shè)置初始中斷源。
2. 重置Resetting
縮短到下一個計數(shù)器到期的時間。這是必要的,例如,當(dāng)下一個中斷超過100個滴答時,做一個SetRelAlarm(WakeUp, 100)調(diào)用。
AlarmBaseType Info; GetAlarmBase(Alarm2, &Info); MaxValue = Info.maxallowedvalue; BaseTicks = Info.ticksperbase; MinCycle = Info.mincycle;
Example 6.6: Using GetAlarmBase() to read static counter attributes
Os_Cbk_State_
此回調(diào)返回計數(shù)器上的下一個操作是否掛起,以及(通常)在達到匹配值之前剩余的tick數(shù)。
Os_Cbk_Now_
此回調(diào)需要返回外部計數(shù)器的當(dāng)前值。這用于GetCounterValue() API調(diào)用。
Os_Cbk_Cancel_
這個回調(diào)必須為計數(shù)器清除任何掛起的中斷,并確保中斷不能成為掛起,直到一個Os_Cbk_Set_
集成指南:硬件計數(shù)器可用于多核系統(tǒng)。RTA-OS將確保State, Set和Cancel回調(diào)只在擁有計數(shù)器的核心上被調(diào)用。這意味著User可以從擁有計數(shù)器的不同核心啟動alarm和ScheduleTables, RTA-OS將向計數(shù)器的核心發(fā)送消息,告訴它調(diào)用適當(dāng)?shù)幕卣{(diào)。
6.3運行時獲取計數(shù)器屬性Accessing Counter Attributes at Run time
RTA-OS API調(diào)用GetAlarmBase()總是返回配置的計數(shù)器值。GetAlarmBase()的結(jié)構(gòu)如例6.6所示。
配置的值也可以以符號常量的形式訪問,如下所示。
? OSMAXALLOWEDVALUE_
? OSTICKSPERBASE_
? OSMINCYCLE_
因此,上面的例6.6也可以寫成例6.7:
MaxValue = OSMAXALLOWEDVALUE_Alarm2; BaseTicks = OSTICKSPERBASE_Alarm2; MinCycle = OSMINCYCLE_Alarm2;
Example 6.7: Using macros to read static counter attributes
6.3.1 特殊的計數(shù)器名Special Counter Names
如果創(chuàng)建了一個名為SystemCounter的計數(shù)器,那么在AUTOSAR OS中可以通過省略末尾的_CounterID來使用簡短的宏形式訪問相關(guān)的計數(shù)器屬性:
OSMAXALLOWEDVALUE_SystemCounter ? OSMAXALLOWEDVALUE
OSTICKSPERBASE_SystemCounter ? OSTICKSPERBASE
OSMINCYCLE_SystemCounter ? OSMINCYCLE
RTA-OS為SystemCounter生成兩種形式的宏,User可以使用任何一種版本。SystemCounter還提供了一個額外的宏來獲取計數(shù)器滴答的持續(xù)時間(以納秒為單位),稱為OSTICKDURATION。
集成指導(dǎo):生成一個有意義的OSTICKDURATION宏需要配置計數(shù)器屬性“Seconds Per Tick”。
6.4 讀取計數(shù)器值Reading Counter Values
應(yīng)用程序需要能夠在運行時讀取計數(shù)器的當(dāng)前值。例如,User可能想知道錯誤計數(shù)器記錄了多少錯誤,按鈕被按了多少次,或者經(jīng)過了多少時間。
計數(shù)器的當(dāng)前值可以在運行時通過調(diào)用GetCounterValue() API來讀取,如例6.8所示。
TickType HowMany; GetCounterValue(ButtonPresses,&HowMany);
Example 8.8: Using GetCounterValue()
當(dāng)使用GetCounterValue()時,應(yīng)該意識到:
?計數(shù)器從MAXALLOWEDVALUE到零,因此計算需要補償。Counters wrap around from MAXALLOWEDVALUE to zero, so the calculation needs to compensate for the wrap
?搶占可以在調(diào)用返回時發(fā)生,這意味著當(dāng)您恢復(fù)時,' Now '的值將是舊的
?當(dāng)使用硬件計數(shù)器時,當(dāng)調(diào)用返回時,計數(shù)器驅(qū)動程序仍將遞增。即使沒有發(fā)生搶 占,立即執(zhí)行的計算也將基于舊數(shù)據(jù)
如果需要執(zhí)行一個簡單的計算來計算自上次讀取值以來計數(shù)器經(jīng)過了多少次計時,那么可以通過使用GetElapsedCounterValue() API調(diào)用來避免這種潛在的競爭條件。該調(diào)用將先前讀取的計數(shù)器值作為輸入,并計算已經(jīng)過的刻度,包括對計數(shù)器包裝的補償。計算發(fā)生在操作系統(tǒng)級別(即禁用中斷),因此不會受到搶占效應(yīng)的影響。
示例6.9顯示了如何使用此特性來度量任務(wù)的端到端(響應(yīng))時間。
#includeTickType Start; ISR(CaptureTrigger){ /* Dismiss interrupt */ GetCounterValue(TimeCounter,&Start); ... ActivateTask(GenerateResponse); } TASK(GenerateResponse){ TickType Finish; CalculateValue(); WriteToDevice(); GetElapsedCounterValue(TimeCounter,&Start,&Finish); ... TerminateTask(); }
Example 6.9: Using GetElapsedCounterValue()
如果計數(shù)器正在計算時間刻度(如例6.9),那么這在AUTOSAR OS中被稱為“自由運行計時器free running timer”。這種類型的計數(shù)器沒有什么特別之處——它與任何其他類型的計數(shù)器相同——唯一的區(qū)別是計數(shù)器是由計時器滴答源驅(qū)動的。
自由運行計時器功能的預(yù)期用途是在運行時測量短、高準確度的持續(xù)時間。如果需要這樣做,那么可能需要使用硬件計數(shù)器來獲得所需的計數(shù)器分辨率。
6.5 Tick數(shù)轉(zhuǎn)換為時間Tick to Time Conversions
通常將計數(shù)器用作操作系統(tǒng)的時基參考。對于編寫的大多數(shù)應(yīng)用程序,事件的相對定時將是由系統(tǒng)需求決定的實時值。很可能會根據(jù)實時值、納秒、毫秒等來考慮系統(tǒng)配置,而不是使用更抽象的tick(滴答)概念。
如果計數(shù)器配置參數(shù)“秒每滴答”已經(jīng)配置,那么RTA操作系統(tǒng)生成宏供使用,以在滴答和實時單位之間轉(zhuǎn)換。
可移植性注意事項:AUTOSAR OS聲明Tick到時間的轉(zhuǎn)換僅適用于硬件計數(shù)器。但是,該特性通常對軟件和硬件計數(shù)器都有用,并且AUTOSAR XML配置語言支持對這兩種類型的計數(shù)器進行配置。
在RTA-OS中,這種異常通過為軟件和硬件計數(shù)器提供刻度到時間的轉(zhuǎn)換來解決。但是,應(yīng)該注意,其他AUTOSAR OS實現(xiàn)不一定支持為軟件計數(shù)器提供這些宏。
提供了以下Tick轉(zhuǎn)換為時間的宏:
? OS_TICKS2NS_CounterID(ticks) converts ticks to nanoseconds
? OS_TICKS2US_CounterID(ticks) converts ticks to microseconds
? OS_TICKS2MS_CounterID(ticks) converts ticks to milliseconds
? OS_TICKS2SEC_CounterID(ticks) converts ticks to seconds
這些宏返回的值是PhysicalTimeType,而不是TickType,可能會使用這些宏的API調(diào)用使這些值,因此需要將它們轉(zhuǎn)換為適當(dāng)?shù)念愋汀?/p>
例6.10展示了如何在應(yīng)用程序代碼中使用這些宏來使用靜態(tài)定義的“timeout”值來模擬超時。
#define TIMEOUT_MS 100 /* Set a timeout to be 100ms */ TickType TimeoutInTicks; TimeoutInTicks = (TickType)((PhysicalTimeType)TIMEOUT_MS/OS_TICKS2MS_TimeCounter(1)); SetRelAlarm(TimeoutAlarm, TimeoutInTicks, 0);
Example 6.10: Programming an alarm with time rather than ticks (1)
RTA-OS將盡可能使用整數(shù)乘法或除法生成這些宏。然而,對于某些滴答率,有必要在計算中使用浮點數(shù),以保持準確性。當(dāng)這些宏被傳遞給編譯時已知的固定值時,編譯器通常會自己執(zhí)行計算并嵌入整型結(jié)果。如果傳遞的值是一個變量,那么編譯器將不得不在運行時生成使用浮點計算的代碼。如果這在應(yīng)用程序中可能是一個問題,應(yīng)該檢查文件Os_Cfg.h以檢查宏的代碼。
除了這些宏之外,RTA-OS還生成一個名為otickduration_
#define TIMEOUT_NS 100000000 /* Set a timeout to be 100ms */ TickType TimeoutInTicks; TimeoutInTicks = (TickType)(TIMEOUT_NS/OSTICKDURATION_TimeCounter); SetRelAlarm(TimeoutAlarm, TimeoutInTicks, 0);
Example 6.11: Programming an alarm with time rather than ticks (2)
可移植性注意事項:OSTICKDURATION_
6.6 小結(jié)
?計數(shù)器用于注冊一些tick源的計數(shù)。
?計數(shù)器可以是軟件計數(shù)器也可以是硬件計數(shù)器。User需要為配置的計數(shù)器類型提供私有驅(qū)動程序。
審核編輯:劉清
-
計數(shù)器
+關(guān)注
關(guān)注
32文章
2248瀏覽量
94184 -
定時器
+關(guān)注
關(guān)注
23文章
3228瀏覽量
114161 -
AUTOSAR
+關(guān)注
關(guān)注
10文章
345瀏覽量
21417 -
ISR
+關(guān)注
關(guān)注
0文章
38瀏覽量
14379
原文標題:符合AUTOSAR標準的RTAOS--Counters詳解
文章出處:【微信號:汽車電子嵌入式,微信公眾號:汽車電子嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論