94 /* polling is equivalent to trig on value rather than on rising edge*/ |
94 /* polling is equivalent to trig on value rather than on rising edge*/ |
95 (poll && __GET_VAR(data__->TRIG) )) && |
95 (poll && __GET_VAR(data__->TRIG) )) && |
96 /* trig only if not already trigged */ |
96 /* trig only if not already trigged */ |
97 __GET_VAR(data__->TRIGGED) == 0){ |
97 __GET_VAR(data__->TRIGGED) == 0){ |
98 /* mark as trigged */ |
98 /* mark as trigged */ |
99 __SET_VAR(data__->, TRIGGED, 1); |
99 __SET_VAR(data__->, TRIGGED,, 1); |
100 /* make a safe copy of the code */ |
100 /* make a safe copy of the code */ |
101 __SET_VAR(data__->, PREBUFFER, __GET_VAR(data__->CODE)); |
101 __SET_VAR(data__->, PREBUFFER,, __GET_VAR(data__->CODE)); |
102 } |
102 } |
103 /* retain value for next rising edge detection */ |
103 /* retain value for next rising edge detection */ |
104 __SET_VAR(data__->, TRIGM1, __GET_VAR(data__->TRIG)); |
104 __SET_VAR(data__->, TRIGM1,, __GET_VAR(data__->TRIG)); |
105 |
105 |
106 /* python thread is not in ? */ |
106 /* python thread is not in ? */ |
107 if( PythonState & PYTHON_LOCKED_BY_PLC){ |
107 if( PythonState & PYTHON_LOCKED_BY_PLC){ |
108 /* if some answer are waiting, publish*/ |
108 /* if some answer are waiting, publish*/ |
109 if(__GET_VAR(data__->STATE) == PYTHON_FB_ANSWERED){ |
109 if(__GET_VAR(data__->STATE) == PYTHON_FB_ANSWERED){ |
110 /* Copy buffer content into result*/ |
110 /* Copy buffer content into result*/ |
111 __SET_VAR(data__->, RESULT, __GET_VAR(data__->BUFFER)); |
111 __SET_VAR(data__->, RESULT,, __GET_VAR(data__->BUFFER)); |
112 /* signal result presece to PLC*/ |
112 /* signal result presece to PLC*/ |
113 __SET_VAR(data__->, ACK, 1); |
113 __SET_VAR(data__->, ACK,, 1); |
114 /* Mark as free */ |
114 /* Mark as free */ |
115 __SET_VAR(data__->, STATE, PYTHON_FB_FREE); |
115 __SET_VAR(data__->, STATE,, PYTHON_FB_FREE); |
116 /* mark as not trigged */ |
116 /* mark as not trigged */ |
117 if(!poll) |
117 if(!poll) |
118 __SET_VAR(data__->, TRIGGED, 0); |
118 __SET_VAR(data__->, TRIGGED,, 0); |
119 /*printf("__PythonEvalFB pop %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/ |
119 /*printf("__PythonEvalFB pop %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/ |
120 }else if(poll){ |
120 }else if(poll){ |
121 /* when in polling, no answer == ack down */ |
121 /* when in polling, no answer == ack down */ |
122 __SET_VAR(data__->, ACK, 0); |
122 __SET_VAR(data__->, ACK,, 0); |
123 } |
123 } |
124 /* got the order to act ?*/ |
124 /* got the order to act ?*/ |
125 if(__GET_VAR(data__->TRIGGED) == 1 && |
125 if(__GET_VAR(data__->TRIGGED) == 1 && |
126 /* and not already being processed */ |
126 /* and not already being processed */ |
127 __GET_VAR(data__->STATE) == PYTHON_FB_FREE) |
127 __GET_VAR(data__->STATE) == PYTHON_FB_FREE) |
130 * Don't have to check if fifo cell is free |
130 * Don't have to check if fifo cell is free |
131 * as fifo size == FB count, and a FB cannot |
131 * as fifo size == FB count, and a FB cannot |
132 * be requested twice */ |
132 * be requested twice */ |
133 EvalFBs[Current_PLC_EvalFB] = data__; |
133 EvalFBs[Current_PLC_EvalFB] = data__; |
134 /* copy into BUFFER local*/ |
134 /* copy into BUFFER local*/ |
135 __SET_VAR(data__->, BUFFER, __GET_VAR(data__->PREBUFFER)); |
135 __SET_VAR(data__->, BUFFER,, __GET_VAR(data__->PREBUFFER)); |
136 /* Set ACK pin to low so that we can set a rising edge on result */ |
136 /* Set ACK pin to low so that we can set a rising edge on result */ |
137 if(!poll){ |
137 if(!poll){ |
138 /* when not polling, a new answer imply reseting ack*/ |
138 /* when not polling, a new answer imply reseting ack*/ |
139 __SET_VAR(data__->, ACK, 0); |
139 __SET_VAR(data__->, ACK,, 0); |
140 }else{ |
140 }else{ |
141 /* when in polling, acting reset trigger */ |
141 /* when in polling, acting reset trigger */ |
142 __SET_VAR(data__->, TRIGGED, 0); |
142 __SET_VAR(data__->, TRIGGED,, 0); |
143 } |
143 } |
144 /* Mark FB busy */ |
144 /* Mark FB busy */ |
145 __SET_VAR(data__->, STATE, PYTHON_FB_REQUESTED); |
145 __SET_VAR(data__->, STATE,, PYTHON_FB_REQUESTED); |
146 /* Have to wakeup python thread in case he was asleep */ |
146 /* Have to wakeup python thread in case he was asleep */ |
147 PythonState |= PYTHON_MUSTWAKEUP; |
147 PythonState |= PYTHON_MUSTWAKEUP; |
148 /*printf("__PythonEvalFB push %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/ |
148 /*printf("__PythonEvalFB push %%d - %%*s\n",Current_PLC_EvalFB, data__->BUFFER.len, data__->BUFFER.body);*/ |
149 /* Get a new line */ |
149 /* Get a new line */ |
150 Current_PLC_EvalFB = (Current_PLC_EvalFB + 1) %% %(python_eval_fb_count)d; |
150 Current_PLC_EvalFB = (Current_PLC_EvalFB + 1) %% %(python_eval_fb_count)d; |
166 if(data__ && /* may be null at first run */ |
166 if(data__ && /* may be null at first run */ |
167 __GET_VAR(data__->STATE) == PYTHON_FB_PROCESSING){ /* some answer awaited*/ |
167 __GET_VAR(data__->STATE) == PYTHON_FB_PROCESSING){ /* some answer awaited*/ |
168 /* If result not None */ |
168 /* If result not None */ |
169 if(result){ |
169 if(result){ |
170 /* Get results len */ |
170 /* Get results len */ |
171 __SET_VAR(data__->, BUFFER, strlen(result), .len); |
171 __SET_VAR(data__->, BUFFER, .len, strlen(result)); |
172 /* prevent results overrun */ |
172 /* prevent results overrun */ |
173 if(__GET_VAR(data__->BUFFER, .len) > STR_MAX_LEN) |
173 if(__GET_VAR(data__->BUFFER, .len) > STR_MAX_LEN) |
174 { |
174 { |
175 __SET_VAR(data__->, BUFFER, STR_MAX_LEN, .len ); |
175 __SET_VAR(data__->, BUFFER, .len, STR_MAX_LEN); |
176 /* TODO : signal error */ |
176 /* TODO : signal error */ |
177 } |
177 } |
178 /* Copy results to buffer */ |
178 /* Copy results to buffer */ |
179 strncpy((char*)__GET_VAR(data__->BUFFER, .body), result, __GET_VAR(data__->BUFFER,.len)); |
179 strncpy((char*)__GET_VAR(data__->BUFFER, .body), result, __GET_VAR(data__->BUFFER,.len)); |
180 }else{ |
180 }else{ |
181 __SET_VAR(data__->, BUFFER, 0, .len); |
181 __SET_VAR(data__->, BUFFER, .len, 0); |
182 } |
182 } |
183 /* remove block from fifo*/ |
183 /* remove block from fifo*/ |
184 EvalFBs[Current_Python_EvalFB] = NULL; |
184 EvalFBs[Current_Python_EvalFB] = NULL; |
185 /* Mark block as answered */ |
185 /* Mark block as answered */ |
186 __SET_VAR(data__->, STATE, PYTHON_FB_ANSWERED); |
186 __SET_VAR(data__->, STATE,, PYTHON_FB_ANSWERED); |
187 /* Get a new line */ |
187 /* Get a new line */ |
188 Current_Python_EvalFB = (Current_Python_EvalFB + 1) %% %(python_eval_fb_count)d; |
188 Current_Python_EvalFB = (Current_Python_EvalFB + 1) %% %(python_eval_fb_count)d; |
189 //printf("PythonIterator ++ Current_Python_EvalFB %%d\n", Current_Python_EvalFB); |
189 //printf("PythonIterator ++ Current_Python_EvalFB %%d\n", Current_Python_EvalFB); |
190 } |
190 } |
191 /* while next slot is empty */ |
191 /* while next slot is empty */ |
200 /*emergency exit*/ |
200 /*emergency exit*/ |
201 if(PythonState & PYTHON_FINISHED) return NULL; |
201 if(PythonState & PYTHON_FINISHED) return NULL; |
202 LockPython(); |
202 LockPython(); |
203 } |
203 } |
204 /* Mark block as processing */ |
204 /* Mark block as processing */ |
205 __SET_VAR(data__->, STATE, PYTHON_FB_PROCESSING); |
205 __SET_VAR(data__->, STATE,, PYTHON_FB_PROCESSING); |
206 //printf("PythonIterator\n"); |
206 //printf("PythonIterator\n"); |
207 /* make BUFFER a null terminated string */ |
207 /* make BUFFER a null terminated string */ |
208 __SET_VAR(data__->, BUFFER, 0, .body[__GET_VAR(data__->BUFFER, .len)]); |
208 __SET_VAR(data__->, BUFFER, .body[__GET_VAR(data__->BUFFER, .len)], 0); |
209 /* next command is BUFFER */ |
209 /* next command is BUFFER */ |
210 next_command = (char*)__GET_VAR(data__->BUFFER, .body); |
210 next_command = (char*)__GET_VAR(data__->BUFFER, .body); |
211 *id=data__; |
211 *id=data__; |
212 /* free python mutex */ |
212 /* free python mutex */ |
213 UnLockPython(); |
213 UnLockPython(); |