# HG changeset patch # User Edouard Tisserant # Date 1422555094 -3600 # Node ID 8872223a675b41d0c5abc52c0e41e7f6c4f8802d # Parent df59be5afb08541cb93a6f15ef620003db2195d2 Optimized plc_debug.c generated code. Should produce smaller code size. Added statically initialized array for PLC tracable variable description. diff -r df59be5afb08 -r 8872223a675b ProjectController.py --- a/ProjectController.py Sun Jan 18 20:38:34 2015 +0100 +++ b/ProjectController.py Thu Jan 29 19:11:34 2015 +0100 @@ -732,6 +732,7 @@ """ self._ProgramList = None self._VariablesList = None + self._DbgVariablesList = None self._IECPathToIdx = {} self._Ticktime = 0 self.TracedIECPath = [] @@ -750,6 +751,7 @@ VariablesListAttributeName = ["num", "vartype", "IEC_path", "C_path", "type"] self._ProgramList = [] self._VariablesList = [] + self._DbgVariablesList = [] self._IECPathToIdx = {} # Separate sections @@ -774,6 +776,7 @@ # second section contains all variables config_FBs = {} + Idx = 0 for line in ListGroup[1]: # Split and Maps each field to dictionnary entries attrs = dict(zip(VariablesListAttributeName,line.strip().split(';'))) @@ -790,12 +793,17 @@ attrs["C_path"] = '__'.join(parts) if attrs["vartype"] == "FB": config_FBs[tuple(parts)] = attrs["C_path"] - # Push this dictionnary into result. + if attrs["vartype"] != "FB": + # Push this dictionnary into result. + self._DbgVariablesList.append(attrs) + # Fill in IEC<->C translation dicts + IEC_path=attrs["IEC_path"] + self._IECPathToIdx[IEC_path]=(Idx, attrs["type"]) + # Ignores numbers given in CSV file + # Idx=int(attrs["num"]) + # Count variables only, ignore FBs + Idx+=1 self._VariablesList.append(attrs) - # Fill in IEC<->C translation dicts - IEC_path=attrs["IEC_path"] - Idx=int(attrs["num"]) - self._IECPathToIdx[IEC_path]=(Idx, attrs["type"]) # third section contains ticktime if len(ListGroup) > 2: @@ -816,8 +824,21 @@ self.GetIECProgramsAndVariables() # prepare debug code + variable_decl_array = [] + bofs = 0 + for v in self._DbgVariablesList : + sz = DebugTypesSize.get(v["type"], 0) + variable_decl_array += [ + "{&(%(C_path)s), "%v+ + {"EXT":"%(type)s_P_ENUM", + "IN":"%(type)s_P_ENUM", + "MEM":"%(type)s_O_ENUM", + "OUT":"%(type)s_O_ENUM", + "VAR":"%(type)s_ENUM"}[v["vartype"]]%v + + "}"] + bofs += sz debug_code = targets.GetCode("plc_debug.c") % { - "buffer_size": reduce(lambda x, y: x + y, [DebugTypesSize.get(v["type"], 0) for v in self._VariablesList], 0), + "buffer_size":bofs, "programs_declarations": "\n".join(["extern %(type)s %(C_path)s;"%p for p in self._ProgramList]), "extern_variables_declarations":"\n".join([ @@ -828,22 +849,8 @@ "VAR":"extern __IEC_%(type)s_t %(C_path)s;", "FB":"extern %(type)s %(C_path)s;"}[v["vartype"]]%v for v in self._VariablesList if v["C_path"].find('.')<0]), - "for_each_variable_do_code":"\n".join([ - {"EXT":" (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n", - "IN":" (*fp)((void*)&(%(C_path)s),%(type)s_P_ENUM);\n", - "MEM":" (*fp)((void*)&(%(C_path)s),%(type)s_O_ENUM);\n", - "OUT":" (*fp)((void*)&(%(C_path)s),%(type)s_O_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 DebugTypesSize ]), - "find_variable_case_code":"\n".join([ - " case %(num)s:\n"%v+ - " *varp = (void*)&(%(C_path)s);\n"%v+ - {"EXT":" return %(type)s_P_ENUM;\n", - "IN":" return %(type)s_P_ENUM;\n", - "MEM":" return %(type)s_O_ENUM;\n", - "OUT":" return %(type)s_O_ENUM;\n", - "VAR":" return %(type)s_ENUM;\n"}[v["vartype"]]%v - for v in self._VariablesList if v["vartype"] != "FB" and v["type"] in DebugTypesSize ])} + "variable_decl_array": ",\n".join(variable_decl_array) + } return debug_code @@ -1307,7 +1314,7 @@ self.IECdebug_datas.pop(IECPath) else: IECdebug_data[4] = reduce( - lambda x, y: x|y, + lambda x, y: x|y, IECdebug_data[0].itervalues(), False) self.IECdebug_lock.release() diff -r df59be5afb08 -r 8872223a675b targets/plc_debug.c --- a/targets/plc_debug.c Sun Jan 18 20:38:34 2015 +0100 +++ b/targets/plc_debug.c Thu Jan 29 19:11:34 2015 +0100 @@ -39,19 +39,23 @@ **/ %(extern_variables_declarations)s -typedef void(*__for_each_variable_do_fp)(void*, __IEC_types_enum); +typedef const struct { + void *ptr; + __IEC_types_enum type; +} dbgvardsc_t; + +static dbgvardsc_t dbgvardsc[] = { +%(variable_decl_array)s +}; + +typedef void(*__for_each_variable_do_fp)(dbgvardsc_t*); void __for_each_variable_do(__for_each_variable_do_fp fp) { -%(for_each_variable_do_code)s -} - -__IEC_types_enum __find_variable(unsigned int varindex, void ** varp) -{ - switch(varindex){ -%(find_variable_case_code)s - default: - *varp = NULL; - return UNKNOWN_ENUM; + int i; + for(i = 0; i < sizeof(dbgvardsc)/sizeof(dbgvardsc_t); i++){ + dbgvardsc_t *dsc = &dbgvardsc[i]; + if(dsc->type != UNKNOWN_ENUM) + (*fp)(dsc); } } @@ -70,12 +74,13 @@ forced_value_p = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\ break; -void* UnpackVar(void* varp, __IEC_types_enum vartype, void **real_value_p, char *flags) -{ +void* UnpackVar(dbgvardsc_t *dsc, void **real_value_p, char *flags) +{ + void *varp = dsc->ptr; void *forced_value_p = NULL; *flags = 0; /* find data to copy*/ - switch(vartype){ + switch(dsc->type){ __ANY(__Unpack_case_t) __ANY(__Unpack_case_p) default: @@ -88,14 +93,14 @@ void Remind(unsigned int offset, unsigned int count, void * p); -void RemindIterator(void* varp, __IEC_types_enum vartype) +void RemindIterator(dbgvardsc_t *dsc) { void *real_value_p = NULL; char flags = 0; - UnpackVar(varp, vartype, &real_value_p, &flags); + UnpackVar(dsc, &real_value_p, &flags); if(flags & __IEC_RETAIN_FLAG){ - USINT size = __get_type_enum_size(vartype); + USINT size = __get_type_enum_size(dsc->type); /* compute next cursor positon*/ unsigned int next_retain_offset = retain_offset + size; /* if buffer not full */ @@ -136,23 +141,23 @@ void Retain(unsigned int offset, unsigned int count, void * p); -inline void BufferIterator(void* varp, __IEC_types_enum vartype, int do_debug) +inline void BufferIterator(dbgvardsc_t *dsc, int do_debug) { void *real_value_p = NULL; void *visible_value_p = NULL; char flags = 0; - visible_value_p = UnpackVar(varp, vartype, &real_value_p, &flags); + visible_value_p = UnpackVar(dsc, &real_value_p, &flags); if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){ - USINT size = __get_type_enum_size(vartype); + USINT size = __get_type_enum_size(dsc->type); if(flags & __IEC_DEBUG_FLAG){ /* copy visible variable to buffer */; if(do_debug){ /* compute next cursor positon. No need to check overflow, as BUFFER_SIZE is computed large enough */ - if(vartype == STRING_ENUM){ + if(dsc->type == STRING_ENUM){ /* optimization for strings */ size = ((STRING*)visible_value_p)->len + 1; } @@ -178,12 +183,12 @@ } } -void DebugIterator(void* varp, __IEC_types_enum vartype){ - BufferIterator(varp, vartype, 1); -} - -void RetainIterator(void* varp, __IEC_types_enum vartype){ - BufferIterator(varp, vartype, 0); +void DebugIterator(dbgvardsc_t *dsc){ + BufferIterator(dsc, 1); +} + +void RetainIterator(dbgvardsc_t *dsc){ + BufferIterator(dsc, 0); } extern void PLC_GetTime(IEC_TIME*); @@ -251,13 +256,18 @@ break; void RegisterDebugVariable(int idx, void* force) { - void *varp = NULL; - unsigned char flags = force ? __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG : __IEC_DEBUG_FLAG; - switch(__find_variable(idx, &varp)){ - __ANY(__RegisterDebugVariable_case_t) - __ANY(__RegisterDebugVariable_case_p) - default: - break; + if(idx < sizeof(dbgvardsc)/sizeof(dbgvardsc_t)){ + unsigned char flags = force ? + __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG : + __IEC_DEBUG_FLAG; + dbgvardsc_t *dsc = &dbgvardsc[idx]; + void *varp = dsc->ptr; + switch(dsc->type){ + __ANY(__RegisterDebugVariable_case_t) + __ANY(__RegisterDebugVariable_case_p) + default: + break; + } } } @@ -272,10 +282,11 @@ ((__IEC_##TYPENAME##_p *)varp)->flags &= ~(__IEC_DEBUG_FLAG|__IEC_FORCE_FLAG);\ break; -void ResetDebugVariablesIterator(void* varp, __IEC_types_enum vartype) +void ResetDebugVariablesIterator(dbgvardsc_t *dsc) { /* force debug flag to 0*/ - switch(vartype){ + void *varp = dsc->ptr; + switch(dsc->type){ __ANY(__ResetDebugVariablesIterator_case_t) __ANY(__ResetDebugVariablesIterator_case_p) default: