📄 calc_rt.c
字号:
State = StateElement; } else { UpdateRung->Element[x-2][y].DynamicInput = StateOnLeft(x-2,y,UpdateRung); State = StateElement && UpdateRung->Element[x-2][y].DynamicInput; } UpdateRung->Element[x][y].DynamicOutput = State; return State;}/* Element : Operate (3 Horizontal Blocks) */static char CalcTypeOutputOperate(int x,int y,StrRung * UpdateRung){ char State; State = StateOnLeft(x-2,y,UpdateRung); if (State) MakeCalc(ArithmExpr[UpdateRung->Element[x][y].VarNum].Expr,FALSE /* verify mode */); UpdateRung->Element[x][y].DynamicInput = State; UpdateRung->Element[x][y].DynamicState = State; return State;}static int RefreshRung(StrRung * Rung, int * JumpTo, int * CallTo){ int x,y; int JumpToRung = -1; int SectionToCall = -1; for (x=0;x<RUNG_WIDTH;x++) { for(y=0;y<RUNG_HEIGHT;y++) { switch(Rung->Element[x][y].Type) { /* MLD,16/5/2001,V0.2.8 , fixed for drawing */ case ELE_FREE: case ELE_UNUSABLE: if (StateOnLeft(x,y,Rung)) Rung->Element[x][y].DynamicInput = 1; else Rung->Element[x][y].DynamicInput = 0; break; /* End fix */ case ELE_INPUT: CalcTypeInput(x,y,Rung,FALSE,FALSE); break; case ELE_INPUT_NOT: CalcTypeInput(x,y,Rung,TRUE,FALSE); break; case ELE_RISING_INPUT: CalcTypeInput(x,y,Rung,FALSE,TRUE); break; case ELE_FALLING_INPUT: CalcTypeInput(x,y,Rung,TRUE,TRUE); break; case ELE_CONNECTION: CalcTypeConnection(x,y,Rung); break; case ELE_TIMER: CalcTypeTimer(x,y,Rung); break; case ELE_MONOSTABLE: CalcTypeMonostable(x,y,Rung); break; case ELE_COMPAR: CalcTypeCompar(x,y,Rung); break; case ELE_OUTPUT: CalcTypeOutput(x,y,Rung,FALSE); break; case ELE_OUTPUT_NOT: CalcTypeOutput(x,y,Rung,TRUE); break; case ELE_OUTPUT_SET: CalcTypeOutputSetReset(x,y,Rung,FALSE); break; case ELE_OUTPUT_RESET: CalcTypeOutputSetReset(x,y,Rung,TRUE); break; case ELE_OUTPUT_JUMP: JumpToRung = CalcTypeOutputJump(x,y,Rung); // TODO : abort the refresh of the rung immediately... break; case ELE_OUTPUT_CALL: SectionToCall = CalcTypeOutputCall(x,y,Rung); break; case ELE_OUTPUT_OPERATE: CalcTypeOutputOperate(x,y,Rung); break; } } } *JumpTo = JumpToRung; *CallTo = SectionToCall; // TODO : tell if the rung isn't finished : if found Call, immediately abort // and return here to finish the end, after the sub-routine has been called... return TRUE;}// we refresh all the rungs of one section.// we can (J)ump to another rung in the same section.// we can (C)all a sub-routine (a section) and at the end of it, returns to the// next rung.// All the sections 'main' are refreshed in the order defined.// TODO : if we have a mad Jump (infinite loop) we must make something !#define SR_STACK 25void RefreshAllRungs(long NsSinceLastScan){ int NumRung; int Goto; int SectionForCallSR; int Done; int ScanMainSection; int CurrentSection; StrSection * pSection; int SubRoutinesStack[ SR_STACK ]; int RungsStack[ SR_STACK ]; int SubRoutineDepth = 0; long long int StartTime = rtapi_get_time(); InfosGene->NsSinceLastScan += NsSinceLastScan; InfosGene->TimeSinceLastScan = InfosGene->NsSinceLastScan / 1000000; InfosGene->NsSinceLastScan = InfosGene->NsSinceLastScan % 1000000; for ( ScanMainSection=0; ScanMainSection<NBR_SECTIONS; ScanMainSection++ ) { CurrentSection = ScanMainSection; pSection = &SectionArray[ CurrentSection ]; // current section defined and is a main-section (not a sub-routine) // and in Ladder language ? if ( pSection->Used && pSection->SubRoutineNumber==-1 && pSection->Language==SECTION_IN_LADDER ) { Done = FALSE; NumRung = pSection->FirstRung; do { RefreshRung(&RungArray[NumRung], &Goto, &SectionForCallSR); if ( SectionForCallSR!=-1 ) { if ( SectionArray[ SectionForCallSR ].Used && SectionArray[ SectionForCallSR ].SubRoutineNumber>=0 ) { if ( SubRoutineDepth<SR_STACK-1 ) { // saving current section context SubRoutineDepth++; SubRoutinesStack[ SubRoutineDepth ] = CurrentSection; if ( NumRung!=pSection->LastRung ) { RungsStack[ SubRoutineDepth ] = RungArray[NumRung].NextRung; } else { // at the end of the sub-routine, this section is already finished RungsStack[ SubRoutineDepth ] = -1; } // now starting the sub-routine section... CurrentSection = SectionForCallSR; pSection = &SectionArray[ CurrentSection ]; NumRung = pSection->FirstRung; } else { rtapi_print_msg(RTAPI_MSG_INFO, "Refresh rungs aborted - too much sub-routine calls in series !?"); } } else { rtapi_print_msg(RTAPI_MSG_INFO, "Refresh rungs aborted - call to a sub-routine undefined or programmed as main !!!"); } } else if ( Goto!=-1 ) { if (!RungArray[Goto].Used) { Done = TRUE; rtapi_print_msg(RTAPI_MSG_INFO, "Refresh rungs aborted - jump to an undefined rung found in rung No%d...\n",Goto); } NumRung = Goto; } else { if (NumRung == pSection->LastRung) { // if this section is a sub-routine, we make a return... if ( pSection->SubRoutineNumber>=0 ) { int ReturnFound = FALSE; do { if ( SubRoutineDepth>0 ) { // previous section already finished ? if ( RungsStack[ SubRoutineDepth ]!=-1 ) { CurrentSection = SubRoutinesStack[ SubRoutineDepth ]; pSection = &SectionArray[ CurrentSection ]; NumRung = RungsStack[ SubRoutineDepth ]; ReturnFound = TRUE; } else { // the previous main section was already finished... if ( SectionArray[ SubRoutinesStack[ SubRoutineDepth ] ].SubRoutineNumber==0 ) { Done = TRUE; ReturnFound = TRUE; } } SubRoutineDepth--; } else { rtapi_print_msg(RTAPI_MSG_INFO, "Refresh rungs aborted - return of sub-routine without call before !?"); } } while( !ReturnFound ); } else { // last rung found for a main section Done = TRUE; } } else NumRung = RungArray[NumRung].NextRung; } } while(!Done); }#ifdef SEQUENTIAL_SUPPORT // current section defined and is in sequential language if ( pSection->Used && pSection->Language==SECTION_IN_SEQUENTIAL ) { RefreshSequentialPage( pSection->SequentialPage ); }#endif }// for( ) InfosGene->DurationOfLastScan = rtapi_get_time() - StartTime;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -