--- 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"]
Idx=int(attrs["num"])
- self._IECPathToIdx[IEC_path]=Idx
+ self._IECPathToIdx[IEC_path]=(Idx, attrs["type"])
except Exception,e:
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([
+ " case %(num)s:\n"%v+
+ " 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 ])}
return debug_code
@@ -1596,16 +1601,17 @@
IECPathsToPop.append(IECPath)
elif IECPath != "__tick__":
# Convert
- Idx = self._IECPathToIdx.get(IECPath,None)
+ Idx, IEC_Type = self._IECPathToIdx.get(IECPath,(None,None))
if Idx is not None:
- Idxs.append(Idx)
- self.TracedIECPath.append(IECPath)
+ Idxs.append((Idx, IEC_Type, IECPath))
else:
self.logger.write_warning(_("Debug : Unknown variable %s\n")%IECPath)
for IECPathToPop in IECPathsToPop:
self.IECdebug_datas.pop(IECPathToPop)
- self._connector.SetTraceVariablesList(Idxs)
+ Idxs.sort()
+ 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):
return None
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._Idxs = idxs[:]
self._ResetDebugVariables()
- for idx in idxs:
+ for idx,iectype in idxs:
self._RegisterDebugVariable(idx)
self._resumeDebug()
@@ -378,21 +375,21 @@
"""
if self.PLCStatus == "Started":
self.PLClibraryLock.acquire()
- tick = ctypes.c_int()
- #PLCprint("Debug tick : %d"%tick)
- if self._WaitDebugData(ctypes.byref(tick)) != 0:
- idx = ctypes.c_int()
- typename = ctypes.c_char_p()
- res = []
- 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 :
+ offset = 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)
else:
- PLCprint("Debug error idx : %d, expected_idx %d, type : %s"%(idx.value, given_idx,typename.value))
- res.append(None)
+ PLCprint("Debug error !")
+ break
self._FreeDebugData()
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 @@
/* Buffer's cursor*/
static char* buffer_cursor = debug_buffer;
-typedef struct{
- void* ptrvalue;
- __IEC_types_enum type;
-}struct_plcvar;
-
/***
* Declare programs
**/
@@ -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)
+{
+ switch(varindex){
+%(find_variable_case_code)s
+ }
+ *varp = NULL;
+ return UNKNOWN_ENUM;
+}
void __init_debug(void)
{
-%(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)
+{
+ void *ptrvalue = NULL;
+ char flags = 0;
+ /* find data to copy*/
+ switch(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;
+ }else{
+ /*TODO : signal overflow*/
+ }
+ }
+}
+
+
void __publish_debug(void)
{
/* Check there is no running debugger re-configuration */
@@ -84,38 +125,10 @@
/* If buffer was free */
if(latest_state == BUFFER_FREE)
{
- int* subscription;
-
/* Reset buffer cursor */
buffer_cursor = debug_buffer;
-
- /* iterate over subscriptions */
- for(subscription=subscription_table;
- subscription < latest_subscription;
- subscription++)
- {
- /* get variable descriptor */
- struct_plcvar* my_var = &variable_table[*subscription];
- char* next_cursor;
- /* get variable size*/
- 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;
- }else{
- /*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);
/* Leave debug section,
* 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*/
- }else{
- /*TODO : signal subscription overflow*/
+ void *varp;
+ 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*/
+ switch(vartype){
+ ANY(__ResetDebugVariablesIterator_case_t)
+ ANY(__ResetDebugVariablesIterator_case_p)
}
}
void ResetDebugVariables(void)
{
- latest_subscription = subscription_table;
+ __for_each_variable_do(ResetDebugVariablesIterator);
}
void FreeDebugData(void)
@@ -153,29 +186,11 @@
BUFFER_FREE);
}
-void* IterDebugData(int* idx, const char **type_name)
-{
- struct_plcvar* my_var;
- USINT size;
- 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);
- /* get variable size*/
- size = __get_type_enum_size(my_var->type);
- /* compute next cursor position*/
- buffer_cursor = buffer_cursor + size;
- if(old_cursor < debug_buffer + BUFFER_SIZE)
- {
- return old_cursor;
- }else{
- //printf("%%d > %%d\n", old_cursor - debug_buffer, BUFFER_SIZE);
- return NULL;
- }
- }
- *idx = -1;
- *type_name = NULL;
- return NULL;
+/* 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;
+ *buffer = NULL;
+ return res;
}