--- a/plugger.py Wed Dec 02 13:07:57 2009 +0100
+++ b/plugger.py Wed Dec 02 20:22:28 2009 +0100
@@ -1303,7 +1303,7 @@
# Fill in IEC<->C translation dicts
IEC_path=attrs["IEC_path"]
- self._IECPathToIdx[IEC_path]=Idx
+ self._IECPathToIdx[IEC_path]=(Idx, attrs["type"]) self.logger.write_error(_("Cannot open/parse VARIABLES.csv!\n"))
self.logger.write_error(traceback.format_exc())
@@ -1331,10 +1331,15 @@
len(self._VariablesList),
"variables_pointer_type_table_count":
len(self._VariablesList),
- "variables_pointer_type_table_initializer":"\n".join([
- {"PT":" variable_table[%(num)s].ptrvalue = (void*)(%(C_path)s);\n",
- "VAR":" variable_table[%(num)s].ptrvalue = (void*)(&%(C_path)s);\n"}[v["vartype"]]%v +
- " variable_table[%(num)s].type = %(type)s_ENUM;\n"%v
+ "for_each_variable_do_code":"\n".join([ + {"PT":" (*fp)((void*)&%(C_path)s,%(type)s_P_ENUM);\n", + "VAR":" (*fp)((void*)&%(C_path)s,%(type)s_ENUM);\n"}[v["vartype"]]%v + for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypes ]), + "find_variable_case_code":"\n".join([ + " varp = (void*)&%(C_path)s;\n"%v+ + {"PT":" return %(type)s_P_ENUM;\n", + "VAR":" return %(type)s_ENUM;\n"}[v["vartype"]]%v for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypes ])}
@@ -1596,16 +1601,17 @@
IECPathsToPop.append(IECPath)
elif IECPath != "__tick__":
- Idx = self._IECPathToIdx.get(IECPath,None)
+ Idx, IEC_Type = self._IECPathToIdx.get(IECPath,(None,None))
- self.TracedIECPath.append(IECPath)
+ Idxs.append((Idx, IEC_Type, IECPath)) self.logger.write_warning(_("Debug : Unknown variable %s\n")%IECPath)
for IECPathToPop in IECPathsToPop:
self.IECdebug_datas.pop(IECPathToPop)
- self._connector.SetTraceVariablesList(Idxs)
+ self.TracedIECPath = zip(Idxs)[2] + self._connector.SetTraceVariablesList(zip(zip(Idxs)[0:1])) self.IECdebug_lock.release()
#for IEC_path, IECdebug_data in self.IECdebug_datas.iteritems():
@@ -1629,7 +1635,7 @@
to a WeakKeyDictionary linking
weakly referenced callables to optionnal args
- if IECPath != "__tick__" and self._IECPathToIdx.get(IECPath, None) is None:
+ if IECPath != "__tick__" and not self._IECPathToIdx.has_key(IECPath): self.IECdebug_lock.acquire()
--- a/runtime/PLCObject.py Wed Dec 02 13:07:57 2009 +0100
+++ b/runtime/PLCObject.py Wed Dec 02 20:22:28 2009 +0100
@@ -131,15 +131,12 @@
self._RegisterDebugVariable.restype = None
self._RegisterDebugVariable.argtypes = [ctypes.c_int]
- self._IterDebugData = self.PLClibraryHandle.IterDebugData
- self._IterDebugData.restype = ctypes.c_void_p
- self._IterDebugData.argtypes = [ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_char_p)]
self._FreeDebugData = self.PLClibraryHandle.FreeDebugData
self._FreeDebugData.restype = None
- self._WaitDebugData = self.PLClibraryHandle.WaitDebugData
- self._WaitDebugData.restype = ctypes.c_int
+ self._GetDebugData = self.PLClibraryHandle.GetDebugData + self._GetDebugData.restype = ctypes.c_int + self._GetDebugData.argtypes = [ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_uint32), ctypes.POINTER(ctypes.c_void_p)] self._suspendDebug = self.PLClibraryHandle.suspendDebug
self._suspendDebug.restype = None
@@ -165,7 +162,7 @@
self._RegisterDebugVariable = lambda x:None
self._IterDebugData = lambda x,y:None
self._FreeDebugData = lambda:None
- self._WaitDebugData = lambda:-1
+ self._GetDebugData = lambda:-1 self._suspendDebug = lambda:None
self._resumeDebug = lambda:None
self._PythonIterator = lambda:""
@@ -339,7 +336,7 @@
# keep a copy of requested idx
self._ResetDebugVariables()
+ for idx,iectype in idxs: self._RegisterDebugVariable(idx)
@@ -378,21 +375,21 @@
if self.PLCStatus == "Started":
self.PLClibraryLock.acquire()
- #PLCprint("Debug tick : %d"%tick)
- if self._WaitDebugData(ctypes.byref(tick)) != 0:
- typename = ctypes.c_char_p()
- for given_idx in self._Idxs:
- buffer=self._IterDebugData(ctypes.byref(idx), ctypes.byref(typename))
- c_type,unpack_func = self.TypeTranslator.get(typename.value, (None,None))
- if c_type is not None and given_idx == idx.value:
- res.append(unpack_func(ctypes.cast(buffer,
+ tick = ctypes.c_uint32() + size = ctypes.c_uint32() + buffer = ctypes.c_void_p() + if self._GetDebugData(ctypes.byref(tick),ctypes.byref(size),ctypes.byref(buffer)) == 0 : + for idx, iectype in self._Idxs: + cursor = ctypes.c_void_p(buffer.value + offset) + c_type,unpack_func = self.TypeTranslator.get(iectype, (None,None)) + if c_type is not None and offset < size: + res.append(unpack_func(ctypes.cast(cursor, ctypes.POINTER(c_type)).contents))
+ offset += ctypes.sizeof(c_type) - PLCprint("Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value))
+ PLCprint("Debug error !") self.PLClibraryLock.release()
return self.PLCStatus, tick, res
--- a/targets/plc_debug.c Wed Dec 02 13:07:57 2009 +0100
+++ b/targets/plc_debug.c Wed Dec 02 20:22:28 2009 +0100
@@ -30,11 +30,6 @@
static char* buffer_cursor = debug_buffer;
@@ -45,15 +40,23 @@
%(extern_variables_declarations)s
-static int subscription_table[MAX_SUBSCRIBTION];
-static int* latest_subscription = subscription_table;
-static int* subscription_cursor = subscription_table;
+typedef void(*__for_each_variable_do_fp)(void*, __IEC_types_enum); +__for_each_variable_do(__for_each_variable_do_fp fp) +%(for_each_variable_do_code)s -struct_plcvar variable_table[%(variables_pointer_type_table_count)d];
+__IEC_types_enum __find_variable(unsigned int varindex, void ** varp) +%(find_variable_case_code)s -%(variables_pointer_type_table_initializer)s
buffer_state = BUFFER_FREE;
@@ -71,6 +74,44 @@
extern void InitiateDebugTransfer(void);
extern unsigned long __tick;
+#define __BufferDebugDataIterator_case_t(TYPENAME) \ + case TYPENAME##_ENUM :\ + flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\ + ptrvalue = &((__IEC_##TYPENAME##_t *)varp)->value; +#define __BufferDebugDataIterator_case_p(TYPENAME)\ + case TYPENAME##_P_ENUM :\ + flags = ((__IEC_##TYPENAME##_p *)varp)->flags;\ + ptrvalue = ((__IEC_##TYPENAME##_p *)varp)->value; +void BufferDebugDataIterator(void* varp, __IEC_types_enum vartype) + ANY(__BufferDebugDataIterator_case_t) + ANY(__BufferDebugDataIterator_case_p) + if(flags && __IEC_DEBUG_FLAG){ + USINT size = __get_type_enum_size(vartype); + /* compute next cursor positon*/ + char* next_cursor = buffer_cursor + size; + /* if buffer not full */ + if(next_cursor <= debug_buffer + BUFFER_SIZE) + /* copy data to the buffer */ + memcpy(buffer_cursor, ptrvalue, size); + /* increment cursor according size*/ + buffer_cursor = next_cursor; + /*TODO : signal overflow*/ void __publish_debug(void)
/* Check there is no running debugger re-configuration */
@@ -84,38 +125,10 @@
if(latest_state == BUFFER_FREE)
/* Reset buffer cursor */
buffer_cursor = debug_buffer;
- /* iterate over subscriptions */
- for(subscription=subscription_table;
- subscription < latest_subscription;
- /* get variable descriptor */
- struct_plcvar* my_var = &variable_table[*subscription];
- USINT size = __get_type_enum_size(my_var->type);
- /* compute next cursor positon*/
- next_cursor = buffer_cursor + size;
- /* if buffer not full */
- if(next_cursor <= debug_buffer + BUFFER_SIZE)
- /* copy data to the buffer */
- memcpy(buffer_cursor, my_var->ptrvalue, size);
- /* increment cursor according size*/
- buffer_cursor = next_cursor;
- /*TODO : signal overflow*/
- /* Reset buffer cursor again (for IterDebugData)*/
- buffer_cursor = debug_buffer;
- subscription_cursor = subscription_table;
+ /* Iterate over all variables to fill debug buffer */ + __for_each_variable_do(BufferDebugDataIterator); * Trigger asynchronous transmission
@@ -126,21 +139,41 @@
+#define __RegisterDebugVariable_case_t(TYPENAME) \ + case TYPENAME##_ENUM :\ + ((__IEC_##TYPENAME##_t *)varp)->flags |= __IEC_DEBUG_FLAG; +#define __RegisterDebugVariable_case_p(TYPENAME)\ + case TYPENAME##_P_ENUM :\ + ((__IEC_##TYPENAME##_p *)varp)->flags |= __IEC_DEBUG_FLAG; void RegisterDebugVariable(int idx)
- /*If subscription table not full */
- if(latest_subscription - subscription_table < MAX_SUBSCRIBTION)
- *(latest_subscription++) = idx;
- /* TODO pre-calc buffer size and signal overflow*/
- /*TODO : signal subscription overflow*/
+ switch(__find_variable(idx, varp)){ + ANY(__RegisterDebugVariable_case_t) + ANY(__RegisterDebugVariable_case_p) +#define __ResetDebugVariablesIterator_case_t(TYPENAME) \ + case TYPENAME##_ENUM :\ + ((__IEC_##TYPENAME##_t *)varp)->flags &= ~__IEC_DEBUG_FLAG; +#define __ResetDebugVariablesIterator_case_p(TYPENAME)\ + case TYPENAME##_P_ENUM :\ + ((__IEC_##TYPENAME##_p *)varp)->flags &= ~__IEC_DEBUG_FLAG;\ +void ResetDebugVariablesIterator(void* varp, __IEC_types_enum vartype) + /* force debug flag to 0*/ + ANY(__ResetDebugVariablesIterator_case_t) + ANY(__ResetDebugVariablesIterator_case_p) void ResetDebugVariables(void)
- latest_subscription = subscription_table;
+ __for_each_variable_do(ResetDebugVariablesIterator); @@ -153,29 +186,11 @@
-void* IterDebugData(int* idx, const char **type_name)
- if(subscription_cursor < latest_subscription){
- char* old_cursor = buffer_cursor;
- *idx = *subscription_cursor;
- my_var = &variable_table[*(subscription_cursor++)];
- *type_name = __get_type_enum_name(my_var->type);
- size = __get_type_enum_size(my_var->type);
- /* compute next cursor position*/
- buffer_cursor = buffer_cursor + size;
- if(old_cursor < debug_buffer + BUFFER_SIZE)
- //printf("%%d > %%d\n", old_cursor - debug_buffer, BUFFER_SIZE);
+/* Wait until debug data ready and return pointer to it */ +int GetDebugData(unsigned long *tick, unsigned long *size, void **buffer){ + int res = WaitDebugData(tick); + *size = buffer_cursor - debug_buffer;