diff options
Diffstat (limited to 'runtime/org.eclipse.etrice.modellib.cpp/src-gen/room/basic/service/timing/ATimingService.cpp')
-rw-r--r-- | runtime/org.eclipse.etrice.modellib.cpp/src-gen/room/basic/service/timing/ATimingService.cpp | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/runtime/org.eclipse.etrice.modellib.cpp/src-gen/room/basic/service/timing/ATimingService.cpp b/runtime/org.eclipse.etrice.modellib.cpp/src-gen/room/basic/service/timing/ATimingService.cpp new file mode 100644 index 000000000..8639764df --- /dev/null +++ b/runtime/org.eclipse.etrice.modellib.cpp/src-gen/room/basic/service/timing/ATimingService.cpp @@ -0,0 +1,399 @@ +/** + * @author generated by eTrice + * + * Source File of ActorClass ATimingService + * + */ + +#include "ATimingService.h" + +#include "common/messaging/RTObject.h" +#include "common/messaging/RTServices.h" +#include "common/debugging/DebuggingService.h" +#include "common/debugging/MSCFunctionObject.h" + +using namespace etRuntime; + + +/*--------------------- begin user code ---------------------*/ +// uc3 +/*--------------------- end user code ---------------------*/ + +ATimingService::ATimingService(etRuntime::IRTObject* parent, const String& name) + : ActorClassBase(parent, name) + , timer(this, "timer", IFITEM_timer) + , tcbs() + , usedTcbsRoot(0) + , freeTcbsRoot(0) +{ + MSCFunctionObject mscFunctionObject(getInstancePathName(), "Constructor"); + + for (int i = 0; i < s_numberOfStates; i++) { + history[i] = NO_STATE; + } + setClassName("ATimingService"); + + // sub actors + + /* user defined constructor body */ + memset(tcbs.getData(), sizeof(tcbs), 0); +} + +void ATimingService::initialize() { + MSCFunctionObject mscFunctionObject(getInstancePathName(), "initialize()"); + + ActorClassBase::initialize(); + + + // wiring + + // activate polling for data-driven communication + RTServices::getInstance().getMsgSvcCtrl().getMsgSvc(getThread())->addPollingMessageReceiver(*this); +} + +void ATimingService::setProbesActive(bool recursive, bool active) { + DebuggingService::getInstance().addPortInstance(m_RTSystemPort); + for(int i = 0; i < timer.getNInterfaceItems(); i++) + DebuggingService::getInstance().addPortInstance(*(timer.getInterfaceItem(i))); +} + +void ATimingService::destroy(){ + MSCFunctionObject mscFunctionObject(getInstancePathName(), "destroy()"); + + /* user defined destructor body */ + DebuggingService::getInstance().addMessageActorDestroy(*this); + RTServices::getInstance().getMsgSvcCtrl().getMsgSvc(getThread())->removePollingMessageReceiver(*this); + ActorClassBase::destroy(); +} + +/*--------------------- operations ---------------------*/ + etTimerControlBlock* ATimingService::getTcb() { + etTimerControlBlock* temp = freeTcbsRoot; + + if (freeTcbsRoot != 0) { + freeTcbsRoot = freeTcbsRoot->next; + temp->next = 0; + } + return temp; +} + void ATimingService::returnTcb(etTimerControlBlock* block) { + block->next = freeTcbsRoot; + freeTcbsRoot = block; +} + void ATimingService::removeTcbFromUsedList(int32 idx) { + etTimerControlBlock* temp = usedTcbsRoot; + etTimerControlBlock* temp2 = usedTcbsRoot; + + if (temp == 0) + return; + + if (usedTcbsRoot->portIdx == idx) { + /* element found, the first one */ + usedTcbsRoot = usedTcbsRoot->next; + returnTcb(temp); + return; + } + + temp = temp->next; + while (temp != 0) { + if (temp->portIdx == idx) { + temp2->next = temp->next; + returnTcb(temp); + return; + } else { + /* try next */ + temp2 = temp; + temp = temp->next; + } + } +} + void ATimingService::putTcbToUsedList(etTimerControlBlock* block) { + etTimerControlBlock* temp = usedTcbsRoot; + etTimerControlBlock* temp2 = usedTcbsRoot; + + if (temp == 0) { + /* list empty put new block to root */ + block->next = 0; + usedTcbsRoot = block; + return; + } + + while (1) { + if (temp != 0) { + if (isTimeGreater(&block->expTime, &temp->expTime)) { + /* try next position */ + temp2 = temp; + temp = temp->next; + } else { + /* right position found */ + block->next = temp; + if (temp == usedTcbsRoot) { + usedTcbsRoot = block; + } else { + temp2->next = block; + } + return; + } + } else { + /* end of list reached */ + block->next = 0; + temp2->next = block; + return; + } + } +} + bool ATimingService::isTimeGreater(etTime* t1, etTime* t2) { + if (t1->sec > t2->sec) + return ET_TRUE; + if (t1->sec < t2->sec) + return ET_FALSE; + if (t1->nSec > t2->nSec) + return ET_TRUE; + return ET_FALSE; +} + void ATimingService::addTime(etTime* t1, etTime* t2) { + t1->sec += t2->sec; + t1->nSec += t2->nSec; + while (t1->nSec >= 1000000000L) { + t1->sec++; + t1->nSec -= 1000000000L; + } +} + +// state names +const String ATimingService::s_stateStrings[] = { + "<no state>", + "<top>", + "Operational" +}; +const int ATimingService::s_numberOfStates = 3; + +void ATimingService::setState(int new_state) { + DebuggingService::getInstance().addActorState(*this, s_stateStrings[new_state].c_str()); + m_state = new_state; +} + +/* Entry and Exit Codes */ +void ATimingService::entry_Operational() { + // prepare +} + void ATimingService::do_Operational() { + // maintain timers + etTimerControlBlock* temp; + etTime t; + + getTimeFromTarget(&t); + while (usedTcbsRoot != 0) { + if (isTimeGreater(&t, &(usedTcbsRoot->expTime))) { + timer.get(usedTcbsRoot->portIdx).timeout(); + temp = usedTcbsRoot; + usedTcbsRoot = usedTcbsRoot->next; + if ((temp->pTime.sec == 0) && (temp->pTime.nSec == 0)) { + // single shot timer + returnTcb(temp); + } else { + // periodic timer + addTime(&temp->expTime, &temp->pTime); + putTcbToUsedList(temp); + } + } else { + break; + } + } +} + +/* Action Codes */ +void ATimingService::action_TRANS_INITIAL_TO__Operational() { + int i; + usedTcbsRoot = 0; + freeTcbsRoot = &tcbs[0]; + tcbs[ET_NB_OF_TCBS - 1].next = 0; + for (i = 0; i < ET_NB_OF_TCBS - 1; i++) { + tcbs[i].next = &tcbs[i + 1]; + } +} +void ATimingService::action_TRANS_tr1_FROM_Operational_TO_Operational_BY_startTimeouttimer_tr1(const InterfaceItemBase* ifitem, uint32 time) { + etTimerControlBlock* timer = getTcb(); + etTime t; + if (timer != 0) { + t.sec = time / 1000; + t.nSec = (time % 1000) * 1000000L; + timer->pTime.sec = 0; + timer->pTime.nSec = 0; + timer->portIdx = ifitem->getIdx(); + getTimeFromTarget(&(timer->expTime)); + addTime(&(timer->expTime), &t); + putTcbToUsedList(timer); + } +} +void ATimingService::action_TRANS_tr3_FROM_Operational_TO_Operational_BY_startTimertimer_tr3(const InterfaceItemBase* ifitem, uint32 time) { + etTimerControlBlock* timer = getTcb(); + etTime t; + if (timer != 0) { + t.sec = time / 1000; + t.nSec = (time % 1000) * 1000000L; + timer->pTime = t; + timer->portIdx = ifitem->getIdx(); + getTimeFromTarget(&(timer->expTime)); + addTime(&(timer->expTime), &t); + putTcbToUsedList(timer); + } +} +void ATimingService::action_TRANS_tr4_FROM_Operational_TO_Operational_BY_killtimer_tr4(const InterfaceItemBase* ifitem) { + removeTcbFromUsedList(ifitem->getIdx()); +} + +/* State Switch Methods */ +/** + * calls exit codes while exiting from the current state to one of its + * parent states while remembering the history + * @param current__et - the current state + * @param to - the final parent state + */ +void ATimingService::exitTo(etInt16 current__et, etInt16 to) { + while (current__et!=to) { + switch (current__et) { + case STATE_Operational: + this->history[STATE_TOP] = STATE_Operational; + current__et = STATE_TOP; + break; + default: + /* should not occur */ + break; + } + } +} + +/** + * calls action, entry and exit codes along a transition chain. The generic data are cast to typed data + * matching the trigger of this chain. The ID of the final state is returned + * @param chain__et - the chain ID + * @param generic_data__et - the generic data pointer + * @return the +/- ID of the final state either with a positive sign, that indicates to execute the state's entry code, or a negative sign vice versa + */ +etInt16 ATimingService::executeTransitionChain(int chain__et, const InterfaceItemBase* ifitem, void* generic_data__et) { + switch (chain__et) { + case ATimingService::CHAIN_TRANS_INITIAL_TO__Operational: + { + action_TRANS_INITIAL_TO__Operational(); + return STATE_Operational; + } + case ATimingService::CHAIN_TRANS_tr1_FROM_Operational_TO_Operational_BY_startTimeouttimer_tr1: + { + uint32 time = *(static_cast<uint32*>(generic_data__et)); + action_TRANS_tr1_FROM_Operational_TO_Operational_BY_startTimeouttimer_tr1(ifitem, time); + return STATE_Operational; + } + case ATimingService::CHAIN_TRANS_tr3_FROM_Operational_TO_Operational_BY_startTimertimer_tr3: + { + uint32 time = *(static_cast<uint32*>(generic_data__et)); + action_TRANS_tr3_FROM_Operational_TO_Operational_BY_startTimertimer_tr3(ifitem, time); + return STATE_Operational; + } + case ATimingService::CHAIN_TRANS_tr4_FROM_Operational_TO_Operational_BY_killtimer_tr4: + { + action_TRANS_tr4_FROM_Operational_TO_Operational_BY_killtimer_tr4(ifitem); + return STATE_Operational; + } + default: + /* should not occur */ + break; + } + return NO_STATE; +} + +/** + * calls entry codes while entering a state's history. The ID of the final leaf state is returned + * @param state__et - the state which is entered + * @return - the ID of the final leaf state + */ +etInt16 ATimingService::enterHistory(etInt16 state__et) { + etBool skip_entry__et = false; + if (state__et >= STATE_MAX) { + state__et = (state__et - STATE_MAX); + skip_entry__et = true; + } + while (true) { + switch (state__et) { + case STATE_Operational: + if (!(skip_entry__et)) entry_Operational(); + /* in leaf state: return state id */ + return STATE_Operational; + case STATE_TOP: + state__et = this->history[STATE_TOP]; + break; + default: + /* should not occur */ + break; + } + skip_entry__et = false; + } + /* return NO_STATE; // required by CDT but detected as unreachable by JDT because of while (true) */ +} + +void ATimingService::executeInitTransition() { + int chain__et = ATimingService::CHAIN_TRANS_INITIAL_TO__Operational; + etInt16 next__et = ATimingService::executeTransitionChain(chain__et, 0, 0); + next__et = ATimingService::enterHistory(next__et); + setState(next__et); +} + +/* receiveEvent contains the main implementation of the FSM */ +void ATimingService::receiveEventInternal(InterfaceItemBase* ifitem, int localId, int evt, void* generic_data__et) { + int trigger__et = (ifitem==0)? POLLING : localId + EVT_SHIFT*evt; + int chain__et = NOT_CAUGHT; + etInt16 catching_state__et = NO_STATE; + + if (!handleSystemEvent(ifitem, evt, generic_data__et)) { + switch (getState()) { + case STATE_Operational: + switch(trigger__et) { + case POLLING: + do_Operational(); + break; + case TRIG_timer__startTimeout: + { + chain__et = ATimingService::CHAIN_TRANS_tr1_FROM_Operational_TO_Operational_BY_startTimeouttimer_tr1; + catching_state__et = STATE_TOP; + } + break; + case TRIG_timer__startTimer: + { + chain__et = ATimingService::CHAIN_TRANS_tr3_FROM_Operational_TO_Operational_BY_startTimertimer_tr3; + catching_state__et = STATE_TOP; + } + break; + case TRIG_timer__kill: + { + chain__et = ATimingService::CHAIN_TRANS_tr4_FROM_Operational_TO_Operational_BY_killtimer_tr4; + catching_state__et = STATE_TOP; + } + break; + default: + /* should not occur */ + break; + } + break; + default: + /* should not occur */ + break; + } + } + if (chain__et != NOT_CAUGHT) { + ATimingService::exitTo(getState(), catching_state__et); + { + etInt16 next__et = ATimingService::executeTransitionChain(chain__et, ifitem, generic_data__et); + next__et = ATimingService::enterHistory(next__et); + setState(next__et); + } + } +} +void ATimingService::receiveEvent(InterfaceItemBase* ifitem, int evt, void* generic_data__et) { + int localId = (ifitem==0)? 0 : ifitem->getLocalId(); + ATimingService::receiveEventInternal(ifitem, localId, evt, generic_data__et); +} +void ATimingService::receive(const Message* msg) { + receiveEvent(0, -1, 0); +} + + |