summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortjung2012-05-09 15:10:03 (EDT)
committertjung2012-05-09 15:10:03 (EDT)
commitf8004b2a167e12b6f70485a3d9b70297cb93e8ea (patch)
tree001d90a41a61c62f228585aa2f92f194c446f9a6
parentd6bc3384470d55f4aba0d5c5df659f5ac3c464c5 (diff)
downloadorg.eclipse.etrice-f8004b2a167e12b6f70485a3d9b70297cb93e8ea.zip
org.eclipse.etrice-f8004b2a167e12b6f70485a3d9b70297cb93e8ea.tar.gz
org.eclipse.etrice-f8004b2a167e12b6f70485a3d9b70297cb93e8ea.tar.bz2
TimingService for C
-rw-r--r--tests/org.eclipse.etrice.generator.c.tests/model/TimingServiceC.room284
1 files changed, 284 insertions, 0 deletions
diff --git a/tests/org.eclipse.etrice.generator.c.tests/model/TimingServiceC.room b/tests/org.eclipse.etrice.generator.c.tests/model/TimingServiceC.room
new file mode 100644
index 0000000..4e88e9a
--- /dev/null
+++ b/tests/org.eclipse.etrice.generator.c.tests/model/TimingServiceC.room
@@ -0,0 +1,284 @@
+RoomModel room.basic.service.timingC {
+
+ import room.basic.types.c.* from "CTypes.room"
+
+ async ActorClass ATimingService {
+ Interface {
+ SPP timer: PTimer
+ }
+ Structure {
+ usercode1 {
+ "
+ #include \"platform/etTimer.h\"
+ #define ET_NB_OF_TCBS 10
+ typedef struct etTCB etTimerControlBlock;
+ struct etTCB {
+ etTargetTime_t expTime;
+ etTargetTime_t pTime;
+ int32 portIdx;
+ etTimerControlBlock* next;
+ };
+ "
+ }
+ usercode2 {
+ "//uc2"
+ }
+ usercode3{
+ "//etTimerControlBlock tcbs[ET_NB_OF_TCBS];"
+ }
+ ServiceImplementation of timer
+ Attribute tcbs[10]:tcb
+ Attribute usedTcbsRoot : tcb ref
+ Attribute freeTcbsRoot : tcb ref
+ }
+ Behavior {
+ Operation getTcb():tcb ref{"
+ etTimerControlBlock* temp = freeTcbsRoot;
+
+ if(freeTcbsRoot!=0) {
+ freeTcbsRoot=freeTcbsRoot->next;
+ temp->next=0;
+ }
+ return temp;
+ "}
+ Operation returnTcb(block:tcb ref){"
+ block->next=freeTcbsRoot;
+ freeTcbsRoot=block;
+ "}
+ Operation removeTcbFromUsedList(idx:int32){"
+ 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;
+ }
+ }
+ "}
+ Operation putTcbToUsedList(block:tcb ref){"
+ 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(temp2==usedTcbsRoot){
+ usedTcbsRoot=block;
+ }else{
+ temp2->next=block;
+ }
+ return;
+ }
+ }else{
+ // end of list reached
+ block->next=0;
+ temp2->next=block;
+ return;
+ }
+ }
+ "}
+ Operation isTimeGreater(t1:targetTime ref, t2 :targetTime ref):boolean{"
+ if (t1->sec > t2->sec) return TRUE;
+ if (t1->sec < t2->sec) return FALSE;
+ if (t1->nSec > t2->nSec) return TRUE;
+ return FALSE;
+ "}
+
+ Operation addTime(t1:targetTime ref, t2:targetTime ref){"
+ t1->sec += t2->sec;
+ t1->nSec += t2->nSec;
+ while(t1->nSec >= 1000000000L){
+ t1->sec++;
+ t1->nSec-=1000000000L;
+ }
+ "}
+
+ Operation printList(){"
+ etTimerControlBlock* temp=usedTcbsRoot;
+ printf(\"list: \");
+ while (temp!=0){
+ printf(\"(%d,%d),\",temp->expTime.sec,temp->expTime.nSec);
+ temp=temp->next;
+ }
+ printf(\"\\n\");
+ "}
+ StateMachine {
+ Transition tr0: initial -> Operational {
+ action {
+ "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++){"
+ "\ttcbs[i].next=&tcbs[i+1];"
+ "\t}"
+ }
+ }
+ Transition tr1: Operational -> Operational {
+ triggers {
+ <startTimeout: timer>
+ }
+ action {
+ "etTimerControlBlock* timer = getTcb();"
+ "etTargetTime_t t;"
+ "if (timer!= 0){"
+ "\tt.sec=time/1000;"
+ "\tt.nSec=(time%1000)*1000000L;"
+ "\ttimer->pTime.sec = 0;"
+ "\ttimer->pTime.nSec = 0;"
+ "\ttimer->portIdx=((etReplSubPort*)ifitem)->index;"
+ "\tgetTimeFromTarget(&(timer->expTime));"
+ "\taddTime(&(timer->expTime),&t);"
+ "\tputTcbToUsedList(timer);"
+ "\t}"
+ }
+ }
+ Transition tr3: Operational -> Operational {
+ triggers {
+ <startTimer: timer>
+ }
+ action {
+ "etTimerControlBlock* timer = getTcb();"
+ "etTargetTime_t t;"
+ "if (timer!= 0){"
+ "\tt.sec=time/1000;"
+ "\tt.nSec=(time%1000)*1000000L;"
+ "\ttimer->pTime = t;"
+ "\ttimer->portIdx=((etReplSubPort*)ifitem)->index;"
+ "\tgetTimeFromTarget(&(timer->expTime));"
+ "\taddTime(&(timer->expTime),&t);"
+ "\tputTcbToUsedList(timer);"
+ "\t}"
+ }
+ }
+ Transition tr4: Operational -> Operational {
+ triggers {
+ <kill: timer>
+ }
+ action {
+ "removeTcbFromUsedList(((etReplSubPort*)ifitem)->index);"
+ }
+ }
+ State Operational {
+ entry {
+ "// prepare"
+ } do {
+ "// maintain timers"
+ "etTimerControlBlock* temp;"
+ "etTargetTime_t t;"
+ ""
+ "getTimeFromTarget(&t);"
+ "while (usedTcbsRoot !=0 ){"
+ "\tif (isTimeGreater(&t,&(usedTcbsRoot->expTime))){"
+ "\t\ttimer[self->usedTcbsRoot->portIdx].timeout();"
+ "\t\ttemp=usedTcbsRoot;"
+ "\t\tusedTcbsRoot=usedTcbsRoot->next;"
+ "\t\tif((temp->pTime.sec==0)&&(temp->pTime.nSec==0)){"
+ "\t\t\t// single shot timer"
+ "\t\t\treturnTcb(temp);"
+ "\t\t}else{"
+ "\t\t\t// periodic timer"
+ "\t\t\taddTime(&temp->expTime,&temp->pTime);"
+ "\t\t\tputTcbToUsedList(temp);"
+ "\t\t\t}"
+ "\t\t}else{"
+ "\t\t\tbreak;"
+ "\t\t\t}"
+ "\t}"
+ }
+ }
+ }
+ }
+ }
+
+
+ ProtocolClass PTimer {
+ usercode1 {"
+ #define ET_TIMER_RUNNING 0x01
+ #define ET_TIMER_PERIODIC 0x02
+ "
+ }
+ usercode2 {
+ "//uc2 "
+ }
+ incoming {
+ Message startTimer(time: uint32)
+ Message startTimeout(time: uint32)
+ Message kill()
+ }
+ outgoing {
+ Message timeout()
+ }
+ conjugate PortClass
+ {
+ handle incoming startTimer{
+ "if (((PTimerConjPort_var*)(self->varData))->status==0){
+ ((PTimerConjPort_var*)(self->varData))->status=ET_TIMER_RUNNING | ET_TIMER_PERIODIC;
+ etPort_sendMessage(self, PTimer_IN_startTimer, sizeof(int32), &data);
+ }
+ "
+ }
+ handle incoming startTimeout{
+ "if (((PTimerConjPort_var*)(self->varData))->status==0){
+ ((PTimerConjPort_var*)(self->varData))->status = ET_TIMER_RUNNING;
+ etPort_sendMessage(self, PTimer_IN_startTimeout, sizeof(int32), &data);
+ }
+ "
+ }
+ handle outgoing timeout{
+ "//TODO: clear active bit in case of single shot timer
+ if (((PTimerConjPort_var*)(self->varData))->status!=0){
+ if (((PTimerConjPort_var*)(self->varData))->status==ET_TIMER_RUNNING){
+ // single shot timer
+ ((PTimerConjPort_var*)(self->varData))->status=0;
+ }
+ // msg to fsm
+ (*receiveMessageFunc)(actor, self, msg);
+ }
+ "
+ }
+ handle incoming kill {
+ "
+ if (((PTimerConjPort_var*)(self->varData))->status!=0){
+ ((PTimerConjPort_var*)(self->varData))->status=0;
+ etPort_sendMessage(self, PTimer_IN_kill, 0,NULL);
+ }
+ "
+ }
+ Attribute status:int8="0"
+ }
+ }
+ ExternalType tcb -> etTimerControlBlock
+ ExternalType targetTime -> etTargetTime_t
+}
+
+ \ No newline at end of file