1.概述
在《RTA-OS系列介紹-Task》部分我們介紹了任務(wù)分為基礎(chǔ)任務(wù)與擴(kuò)展任務(wù),兩者的主要區(qū)別為,擴(kuò)展任務(wù)多了waiting狀態(tài),那Waiting狀態(tài)等待的是什么呢?其實(shí)就是我們今天要介紹的Events(事件),當(dāng)系統(tǒng)中的Task或ISR設(shè)置事件后,等待的任務(wù)將轉(zhuǎn)到Ready狀態(tài)。當(dāng)它成為最高優(yōu)先級(jí)就緒任務(wù)時(shí),RTA-OS將選擇運(yùn)行該Task。
在AUTOSAR操作系統(tǒng)中,事件用于向任務(wù)發(fā)送信號(hào)信息,主要用于為擴(kuò)展任務(wù)提供多個(gè)同步點(diǎn)。本文將對(duì)什么是事件,如何配置事件以及如何在運(yùn)行時(shí)使用它們。Events的使用場(chǎng)景大致如下圖所示。
2. Events配置
正常在應(yīng)用中可配置的Events的最大數(shù)量取決于硬件,而Events需要配置的內(nèi)容包括:名字、至少一個(gè)Task使用及Event mask。
設(shè)置事件時(shí),必須同時(shí)指定任務(wù)。因此,例如,如果為名為Task1的任務(wù)設(shè)置名為Event0的事件,則這對(duì)任務(wù)Task2的Event0沒(méi)有影響。
2.1 定義等待任務(wù)
在使用中,當(dāng)我們聲明某個(gè)Task需要等待一個(gè)Event時(shí),系統(tǒng)將默認(rèn)該任務(wù)為擴(kuò)展任務(wù),等待事件的擴(kuò)展任務(wù)通常會(huì)自動(dòng)啟動(dòng)(等待的時(shí)間滿足后),并且任務(wù)永遠(yuǎn)不會(huì)終止。當(dāng)任務(wù)開(kāi)始執(zhí)行時(shí),RTA-OS將清除它擁有的所有事件。
3. 如何使用Event
3.1 等待事件
任務(wù)的等待事件需要調(diào)用WaitEvent(EventMask) API,具體等待的EventMask需要關(guān)聯(lián)到提前聲明的內(nèi)容。
WaitEvent()將事件作為其唯一參數(shù)。執(zhí)行調(diào)用時(shí),有兩種可能:
1)事件暫未發(fā)生。這種情況下該Task會(huì)進(jìn)入等待狀態(tài),RTA-OS會(huì)運(yùn)行Ready狀態(tài)中優(yōu)先級(jí)最高的Task。
2)事件已經(jīng)發(fā)生。在這種情況下,任務(wù)將保持在運(yùn)行狀態(tài),并將在WaitEvent()調(diào)用之后的語(yǔ)句中繼續(xù)執(zhí)行。
3.1.1 等待單一事件
要等待單個(gè)事件,只需將事件掩碼名稱傳遞給API調(diào)用。下面示例顯示了任務(wù)如何使用等待事件。
#includeTASK(ExtendedTask){ ... WaitEvent(Event1);/*TaskenterswaitingstateinAPIcallif Event1hasnothappened*/ /*WhenEvent1isset,ExtendedTaskresumeshere*/ ... }
在AUTOSAR操作系統(tǒng)中,為處于掛起狀態(tài)的任務(wù)設(shè)置事件是非法的。實(shí)際上,這意味著等待事件的任務(wù)結(jié)構(gòu)通常是一個(gè)等待事件的有限循。
3.1.2 等待多個(gè)事件
因?yàn)锳UTOSAR OS事件只是一個(gè)位掩碼(Bit Mask),所以用戶可以通過(guò)按位設(shè)置一組位掩碼,同時(shí)等待多個(gè)事件。
當(dāng)任務(wù)等待多個(gè)事件時(shí),當(dāng)?shù)却娜魏我粋€(gè)事件發(fā)生時(shí),它將恢復(fù)。當(dāng)從等待多個(gè)事件恢復(fù)時(shí),將需要確定發(fā)生了哪些事件。
#includeTASK(ExtendedTask){ EventMaskTypeWhatHappened; while(true){ WaitEvent(Event1|Event2|Event3); GetEvent(Task1,&WhatHappened); if(WhatHappened&Event1){ /*TakeactiononEvent1*/ ... }elseif(WhatHappened&Event2){ /*TakeactiononEvent2*/ ... }elseif(WhatHappened&Event3){ /*TakeactiononEvent3*/ ... } } }
在AUTOSAR-OS中,提供了GetEvent()的API,我們可以通過(guò)該API獲知哪個(gè)事件已完成。
3.1.3 擴(kuò)展任務(wù)的死鎖
雖然AUTOSAR操作系統(tǒng)在關(guān)鍵部分的資源互斥中提供了免于死鎖的自由,但在構(gòu)建具有可能死鎖的事件的系統(tǒng)時(shí),仍不會(huì)受到保護(hù)。如果我們有相互設(shè)置和等待事件集的擴(kuò)展任務(wù),則兩個(gè)(或更多)任務(wù)可能正在等待僅由其他正在等待的任務(wù)設(shè)置的事件。當(dāng)然,即使存在死鎖擴(kuò)展任務(wù),系統(tǒng)中的基本任務(wù)也不可能死鎖。
下面的樣例展示了擴(kuò)展任務(wù)的死鎖:
#includeTASK(Task1) { while (1) { WaitEvent(Ev1); /* Never reach here - DEADLOCKED with Task2! */ SetEvent(Task2,Ev2); } } TASK(Task2) { while (1) { WaitEvent(Ev2); /* Never reach here - DEADLOCKED with Task1! */ SetEvent(Task1,Ev1); } }
OS配置不獲取哪些任務(wù)或ISR設(shè)置了事件,只獲取哪些任務(wù)可以等待事件。因此,RTA-OS不可能靜態(tài)地確定擴(kuò)展任務(wù)是否會(huì)死鎖。采用下面的設(shè)計(jì)方法可能會(huì)避免類似問(wèn)題:
?僅使用基本任務(wù);
?分析代碼,以表明在所有SetEvent()或WaitEvent()對(duì)的傳遞閉包上沒(méi)有循環(huán)等待事件。
3.2 設(shè)置事件
通過(guò)SetEvent() API 來(lái)設(shè)置事件。
SetEvent()調(diào)用有兩個(gè)參數(shù),一個(gè)任務(wù)和一個(gè)事件掩碼。對(duì)于指定的任務(wù),SetEvent()調(diào)用設(shè)置事件掩碼中指定的事件。該調(diào)用不會(huì)為共享事件的任何其他任務(wù)設(shè)置事件。
在調(diào)用SetEvent()時(shí),可以按位或多個(gè)事件掩碼來(lái)同時(shí)為任務(wù)設(shè)置多個(gè)事件。
無(wú)法為處于掛起狀態(tài)的任務(wù)設(shè)置事件。因此,在設(shè)置事件之前,必須確保任務(wù)未掛起。您可以使用GetTaskState()API調(diào)用來(lái)實(shí)現(xiàn)這一點(diǎn),但請(qǐng)注意,當(dāng)為優(yōu)先級(jí)高于調(diào)用方的任務(wù)調(diào)用此函數(shù)時(shí),可能存在競(jìng)爭(zhēng)條件。調(diào)用方可以在對(duì)API的調(diào)用和對(duì)結(jié)果的評(píng)估之間被搶占,并且被請(qǐng)求的任務(wù)的狀態(tài)在中間時(shí)間內(nèi)可能已經(jīng)改變。
當(dāng)擴(kuò)展任務(wù)正在等待的任何一個(gè)事件被設(shè)置時(shí),擴(kuò)展任務(wù)將從等待狀態(tài)移動(dòng)到就緒狀態(tài)。
如下任務(wù)顯示了任務(wù)如何設(shè)置事件:
#includeTASK(Task1) { TaskStateType TaskState; /* Set a single event */ SetEvent(Task2, Event1); /* Set multiple events */ SetEvent(Task3, Event1 | Event2 | Event3); ... /* Checking for the suspended state */ GetTaskState(Task2,&TaskState); if (TaskState != SUSPENDED) { SetEvent(Task2, Event1); } ... TerminateTask(); }
多個(gè)任務(wù)可以同時(shí)等待同一個(gè)事件,然而從上面例子可以看出,事件沒(méi)有廣播機(jī)制,換句話說(shuō),不能通過(guò)調(diào)用一個(gè)API告訴所有等待的任務(wù)該事件已經(jīng)發(fā)生。
此外,也可以通過(guò)Alarms及調(diào)度表來(lái)設(shè)置事件。
3.2.1通過(guò)Alarm設(shè)置事件
Alarm可用于定期激活不終止的擴(kuò)展任務(wù)。每次Alarm到期時(shí),都會(huì)設(shè)置該事件。等待事件的任務(wù)隨后準(zhǔn)備好運(yùn)行。
3.2.2 通過(guò)帶有到期點(diǎn)的調(diào)度表設(shè)置事件
調(diào)度表上的到期點(diǎn)可用于編程(a)非終止?fàn)顟B(tài)的擴(kuò)展任務(wù)的定期激活。每次處理到期點(diǎn)時(shí),都會(huì)設(shè)置事件。等待事件的任務(wù)隨后準(zhǔn)備好運(yùn)行。
3.3 清除Events
可以通過(guò)Task或者ISRs來(lái)設(shè)置Event,但是Event只能被其owner清除。
#includeTASK(ExtendedTask){ EventMaskType WhatHappened; ... while( WaitEvent(Event1|Event2|Event3)==E_OK ) { GetEvent(Task1, & WhatHappened); if(WhatHappened & Event1 ) { ClearEvent(Event1); /* Take action on Event1 */ ... } else if( WhatHappened & (Event2 | Event3 ) { ClearEvent(Event2 | Event3); /* Take action on Event2 or Event3*/ ... } } }
當(dāng)某個(gè)任務(wù)等待某個(gè)事件,該事件發(fā)生,在后面時(shí)序再次對(duì)同一個(gè)事件調(diào)用WaitEvent()時(shí),由于該事件仍處于Set狀態(tài),會(huì)立即返回。因此,在再次調(diào)用等待事件前需要將之前已發(fā)生事件清除。
清除事件時(shí)調(diào)用ClearEvent API,被清除后的狀態(tài)必須與事件掩碼關(guān)聯(lián)起來(lái)。
當(dāng)某個(gè)任務(wù)被掛起時(shí),其所擁有的Event將被自動(dòng)清除。
3.4 用基礎(chǔ)任務(wù)模擬擴(kuò)展任務(wù)
基礎(chǔ)任務(wù)只能在任務(wù)執(zhí)行的開(kāi)始或結(jié)束時(shí)同步。
如還有其他同步節(jié)點(diǎn)需要時(shí),可以通過(guò)event機(jī)制來(lái)實(shí)現(xiàn)。然而,擴(kuò)展任務(wù)較基礎(chǔ)任務(wù)占用資源更多,在資源限制的系統(tǒng)中,只能通過(guò)使用基礎(chǔ)任務(wù)來(lái)進(jìn)行 同步。
例如,如果任務(wù)構(gòu)建為狀態(tài)機(jī)(例如,使用C switch語(yǔ)句),則可以設(shè)置狀態(tài)變量,發(fā)出TerminateTask()調(diào)用并等待重新激活。如下樣例代碼顯示了如何實(shí)現(xiàn)這一點(diǎn)。
#include/* Create a "State" variable that remains in scope between task activations */ uint8 State; TASK(Task1) { switch (State) { case 0: /* Synchronization point 0. */ State = 1; break; case 1: /* Synchronization point 1. */ State = 2; break; case 2: /* Synchronization point 2. */ State = 0; break; } TerminateTask(); }
4.本文總結(jié)
Event是用于同步的實(shí)體,可用于擴(kuò)展任務(wù)的等待內(nèi)容;
同一個(gè)Event可被不同的Task引用;
Event不具有廣播機(jī)制,即無(wú)法將信息通知所有等待該Event中的任務(wù);
Tasks,ISRs及調(diào)度表都可以設(shè)置Events。
如果時(shí)效性在系統(tǒng)中很重要,則所有擴(kuò)展任務(wù)(任何等待事件的任務(wù))的優(yōu)先級(jí)必須低于基本任務(wù)。
審核編輯:湯梓紅
-
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
6862瀏覽量
123513 -
AUTOSAR
+關(guān)注
關(guān)注
10文章
363瀏覽量
21658 -
事件
+關(guān)注
關(guān)注
0文章
12瀏覽量
9948 -
ISR
+關(guān)注
關(guān)注
0文章
38瀏覽量
14454
原文標(biāo)題:RTA OS系列介紹03-Event
文章出處:【微信號(hào):汽車電子嵌入式,微信公眾號(hào):汽車電子嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論