targets/plc_python.c
changeset 281 3f0fc8de99b0
parent 280 f2ef79f3dba0
child 286 a2a8a52b0d4f
equal deleted inserted replaced
280:f2ef79f3dba0 281:3f0fc8de99b0
    19 #include <string.h>
    19 #include <string.h>
    20 
    20 
    21 /* The fifo (fixed size, as number of FB is fixed) */
    21 /* The fifo (fixed size, as number of FB is fixed) */
    22 static PYTHON_EVAL* EvalFBs[%(python_eval_fb_count)d];
    22 static PYTHON_EVAL* EvalFBs[%(python_eval_fb_count)d];
    23 /* Producer and consumer cursors */
    23 /* Producer and consumer cursors */
    24 static long Current_PLC_EvalFB;
    24 static int Current_PLC_EvalFB;
    25 static long Current_Python_EvalFB;
    25 static int Current_Python_EvalFB;
    26 
    26 
    27 /* A global IEC-Python gateway state, for use inside python_eval FBs*/
    27 /* A global IEC-Python gateway state, for use inside python_eval FBs*/
    28 static int PythonState;
    28 static int PythonState;
    29 #define PYTHON_LOCKED_BY_PYTHON 0
    29 #define PYTHON_LOCKED_BY_PYTHON 0
    30 #define PYTHON_LOCKED_BY_PLC 1
    30 #define PYTHON_LOCKED_BY_PLC 1
    83  * Called by the PLC, each time a python_eval 
    83  * Called by the PLC, each time a python_eval 
    84  * FB instance is executed
    84  * FB instance is executed
    85  */
    85  */
    86 void __PythonEvalFB(PYTHON_EVAL* data__)
    86 void __PythonEvalFB(PYTHON_EVAL* data__)
    87 {
    87 {
       
    88 	/* detect rising edge on TRIG */
       
    89 	if(data__->TRIG && !data__->TRIGM1 && data__->TRIGGED == 0){
       
    90 		/* mark as trigged */
       
    91 		data__->TRIGGED = 1;
       
    92 		/* make a safe copy of the code */
       
    93 		data__->PREBUFFER = data__->CODE;
       
    94 	}
       
    95 	/* retain value for next detection */
       
    96 	data__->TRIGM1 = data__->TRIG;
       
    97 
    88 	/* python thread is not in ? */
    98 	/* python thread is not in ? */
    89 	if( PythonState & PYTHON_LOCKED_BY_PLC){
    99 	if( PythonState & PYTHON_LOCKED_BY_PLC){
    90 		/* Rising edge on TRIG */
   100 		/* got the order to act */
    91 		if(data__->TRIG && !data__->TRIGM1 &&
   101 		if(data__->TRIGGED == 1 &&
    92 		   /* and not already being processed */ 
   102 		   /* and not already being processed */ 
    93 		   data__->STATE == PYTHON_FB_FREE) 
   103 		   data__->STATE == PYTHON_FB_FREE) 
    94 		{
   104 		{
    95 			/* Get a new line */
       
    96 			Current_PLC_EvalFB = (Current_PLC_EvalFB + 1) %% %(python_eval_fb_count)d;
       
    97 			/* Enter the block in the fifo
   105 			/* Enter the block in the fifo
    98 			/* Don't have to check if fifo cell is free
   106 			/* Don't have to check if fifo cell is free
    99 			 * as fifo size == FB count, and a FB cannot 
   107 			 * as fifo size == FB count, and a FB cannot 
   100 			 * be requested twice */
   108 			 * be requested twice */
   101 			EvalFBs[Current_PLC_EvalFB] = data__;
   109 			EvalFBs[Current_PLC_EvalFB] = data__;
   102 			/* copy CODE in variable into BUFFER local*/
   110 			/* copy into BUFFER local*/
   103 			data__->BUFFER = data__->CODE;
   111 			data__->BUFFER = data__->PREBUFFER;
   104 			/* Set ACK pin to low so that we can set a rising edge on result */
   112 			/* Set ACK pin to low so that we can set a rising edge on result */
   105 			data__->ACK = 0;
   113 			data__->ACK = 0;
   106 			/* Mark FB busy */
   114 			/* Mark FB busy */
   107 			data__->STATE = PYTHON_FB_REQUESTED;
   115 			data__->STATE = PYTHON_FB_REQUESTED;
   108 			/* Have to wakeup python thread in case he was asleep */
   116 			/* Have to wakeup python thread in case he was asleep */
   109 			PythonState |= PYTHON_MUSTWAKEUP;
   117 			PythonState |= PYTHON_MUSTWAKEUP;
   110 			//printf("__PythonEvalFB push %%*s\n",data__->BUFFER.len, data__->BUFFER.body);
   118 			//printf("__PythonEvalFB push %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);
       
   119 			/* Get a new line */
       
   120 			Current_PLC_EvalFB = (Current_PLC_EvalFB + 1) %% %(python_eval_fb_count)d;
   111 		}else if(data__->STATE == PYTHON_FB_ANSWERED){
   121 		}else if(data__->STATE == PYTHON_FB_ANSWERED){
       
   122 			/* Copy buffer content into result*/
   112 			data__->RESULT = data__->BUFFER;
   123 			data__->RESULT = data__->BUFFER;
       
   124 			/* signal result presece to PLC*/
   113 			data__->ACK = 1;
   125 			data__->ACK = 1;
       
   126 			/* Mark as free */
   114 			data__->STATE = PYTHON_FB_FREE;
   127 			data__->STATE = PYTHON_FB_FREE;
   115 			//printf("__PythonEvalFB pop %%*s\n",data__->BUFFER.len, data__->BUFFER.body);
   128 			/* mark as not trigged */
       
   129 			data__->TRIGGED = 0;
       
   130 			//printf("__PythonEvalFB pop %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);
   116 		}
   131 		}
   117 		/* retain value for trig
       
   118 		 * do this only when PYTHON_LOCKED_BY_PLC
       
   119 		 * to avoid missed rising edge due to asynchronism */
       
   120 		data__->TRIGM1 = data__->TRIG;
       
   121 	}
   132 	}
   122 }
   133 }
   123 
   134 
   124 char* PythonIterator(char* result)
   135 char* PythonIterator(char* result)
   125 {
   136 {
   151 		EvalFBs[Current_Python_EvalFB] = NULL;
   162 		EvalFBs[Current_Python_EvalFB] = NULL;
   152 		/* Mark block as answered */
   163 		/* Mark block as answered */
   153 		data__->STATE = PYTHON_FB_ANSWERED;
   164 		data__->STATE = PYTHON_FB_ANSWERED;
   154 		/* Get a new line */
   165 		/* Get a new line */
   155 		Current_Python_EvalFB = (Current_Python_EvalFB + 1) %% %(python_eval_fb_count)d;
   166 		Current_Python_EvalFB = (Current_Python_EvalFB + 1) %% %(python_eval_fb_count)d;
       
   167 		//printf("PythonIterator ++ Current_Python_EvalFB %%d\n", Current_Python_EvalFB);
   156 	}
   168 	}
   157 	/* while next slot is empty */
   169 	/* while next slot is empty */
   158 	while(((data__ = EvalFBs[Current_Python_EvalFB]) == NULL) || 
   170 	while(((data__ = EvalFBs[Current_Python_EvalFB]) == NULL) || 
   159 	 	  /* or doesn't contain command */ 
   171 	 	  /* or doesn't contain command */ 
   160 	      data__->STATE != PYTHON_FB_REQUESTED)
   172 	      data__->STATE != PYTHON_FB_REQUESTED)