targets/plc_debug.c
changeset 1475 de4ee16f7c6c
parent 1459 c9065fb5de0a
child 1479 8f41aa88aa46
equal deleted inserted replaced
1474:28e9d479aa65 1475:de4ee16f7c6c
    37 /***
    37 /***
    38  * Declare global variables from resources and conf 
    38  * Declare global variables from resources and conf 
    39  **/
    39  **/
    40 %(extern_variables_declarations)s
    40 %(extern_variables_declarations)s
    41 
    41 
    42 typedef void(*__for_each_variable_do_fp)(void*, __IEC_types_enum);
    42 typedef const struct {
       
    43     void *ptr;
       
    44     __IEC_types_enum type;
       
    45 } dbgvardsc_t;
       
    46 
       
    47 static dbgvardsc_t dbgvardsc[] = {
       
    48 %(variable_decl_array)s
       
    49 };
       
    50 
       
    51 typedef void(*__for_each_variable_do_fp)(dbgvardsc_t*);
    43 void __for_each_variable_do(__for_each_variable_do_fp fp)
    52 void __for_each_variable_do(__for_each_variable_do_fp fp)
    44 {
    53 {
    45 %(for_each_variable_do_code)s
    54     int i;
    46 }
    55     for(i = 0; i < sizeof(dbgvardsc)/sizeof(dbgvardsc_t); i++){
    47 
    56         dbgvardsc_t *dsc = &dbgvardsc[i];
    48 __IEC_types_enum __find_variable(unsigned int varindex, void ** varp)
    57         if(dsc->type != UNKNOWN_ENUM) 
    49 {
    58             (*fp)(dsc);
    50     switch(varindex){
       
    51 %(find_variable_case_code)s
       
    52      default:
       
    53       *varp = NULL;
       
    54       return UNKNOWN_ENUM;
       
    55     }
    59     }
    56 }
    60 }
    57 
    61 
    58 #define __Unpack_case_t(TYPENAME) \
    62 #define __Unpack_case_t(TYPENAME) \
    59         case TYPENAME##_ENUM :\
    63         case TYPENAME##_ENUM :\
    68             *flags |= ((__IEC_##TYPENAME##_p *)varp)->flags;\
    72             *flags |= ((__IEC_##TYPENAME##_p *)varp)->flags;\
    69             *real_value_p = ((__IEC_##TYPENAME##_p *)varp)->value;\
    73             *real_value_p = ((__IEC_##TYPENAME##_p *)varp)->value;\
    70             forced_value_p = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\
    74             forced_value_p = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\
    71             break;
    75             break;
    72 
    76 
    73 void* UnpackVar(void* varp, __IEC_types_enum vartype, void **real_value_p, char *flags)
    77 void* UnpackVar(dbgvardsc_t *dsc, void **real_value_p, char *flags)
    74 {
    78 {
       
    79     void *varp = dsc->ptr;
    75     void *forced_value_p = NULL;
    80     void *forced_value_p = NULL;
    76     *flags = 0;
    81     *flags = 0;
    77     /* find data to copy*/
    82     /* find data to copy*/
    78     switch(vartype){
    83     switch(dsc->type){
    79         __ANY(__Unpack_case_t)
    84         __ANY(__Unpack_case_t)
    80         __ANY(__Unpack_case_p)
    85         __ANY(__Unpack_case_p)
    81     default:
    86     default:
    82         break;
    87         break;
    83     }
    88     }
    86     return *real_value_p;
    91     return *real_value_p;
    87 }
    92 }
    88 
    93 
    89 void Remind(unsigned int offset, unsigned int count, void * p);
    94 void Remind(unsigned int offset, unsigned int count, void * p);
    90 
    95 
    91 void RemindIterator(void* varp, __IEC_types_enum vartype)
    96 void RemindIterator(dbgvardsc_t *dsc)
    92 {
    97 {
    93     void *real_value_p = NULL;
    98     void *real_value_p = NULL;
    94     char flags = 0;
    99     char flags = 0;
    95     UnpackVar(varp, vartype, &real_value_p, &flags);
   100     UnpackVar(dsc, &real_value_p, &flags);
    96 
   101 
    97     if(flags & __IEC_RETAIN_FLAG){
   102     if(flags & __IEC_RETAIN_FLAG){
    98         USINT size = __get_type_enum_size(vartype);
   103         USINT size = __get_type_enum_size(dsc->type);
    99         /* compute next cursor positon*/
   104         /* compute next cursor positon*/
   100         unsigned int next_retain_offset = retain_offset + size;
   105         unsigned int next_retain_offset = retain_offset + size;
   101         /* if buffer not full */
   106         /* if buffer not full */
   102         Remind(retain_offset, size, real_value_p);
   107         Remind(retain_offset, size, real_value_p);
   103         /* increment cursor according size*/
   108         /* increment cursor according size*/
   104         retain_offset = next_retain_offset;
   109         retain_offset = next_retain_offset;
   105     }
   110     }
   106 }
   111 }
   107 
   112 
   108 extern int CheckRetainBuffer(void);
   113 extern int CheckRetainBuffer(void);
       
   114 extern void InitRetain(void);
   109 
   115 
   110 void __init_debug(void)
   116 void __init_debug(void)
   111 {
   117 {
   112     /* init local static vars */
   118     /* init local static vars */
   113     buffer_cursor = debug_buffer;
   119     buffer_cursor = debug_buffer;
   114     retain_offset = 0;
   120     retain_offset = 0;
   115     buffer_state = BUFFER_FREE;
   121     buffer_state = BUFFER_FREE;
       
   122     InitRetain();
   116     /* Iterate over all variables to fill debug buffer */
   123     /* Iterate over all variables to fill debug buffer */
   117     if(CheckRetainBuffer())
   124     if(CheckRetainBuffer()){
   118     	__for_each_variable_do(RemindIterator);
   125     	__for_each_variable_do(RemindIterator);
       
   126     }else{
       
   127     	char mstr[] = "RETAIN memory invalid - defaults used";
       
   128         LogMessage(LOG_WARNING, mstr, sizeof(mstr));
       
   129     }
   119     retain_offset = 0;
   130     retain_offset = 0;
   120 }
   131 }
   121 
   132 
   122 extern void InitiateDebugTransfer(void);
   133 extern void InitiateDebugTransfer(void);
       
   134 extern void CleanupRetain(void);
   123 
   135 
   124 extern unsigned long __tick;
   136 extern unsigned long __tick;
   125 
   137 
   126 void __cleanup_debug(void)
   138 void __cleanup_debug(void)
   127 {
   139 {
   128     buffer_cursor = debug_buffer;
   140     buffer_cursor = debug_buffer;
   129     InitiateDebugTransfer();
   141     InitiateDebugTransfer();
       
   142     CleanupRetain();
   130 }
   143 }
   131 
   144 
   132 void __retrieve_debug(void)
   145 void __retrieve_debug(void)
   133 {
   146 {
   134 }
   147 }
   135 
   148 
   136 
   149 
   137 void Retain(unsigned int offset, unsigned int count, void * p);
   150 void Retain(unsigned int offset, unsigned int count, void * p);
   138 
   151 
   139 inline void BufferIterator(void* varp, __IEC_types_enum vartype, int do_debug)
   152 inline void BufferIterator(dbgvardsc_t *dsc, int do_debug)
   140 {
   153 {
   141     void *real_value_p = NULL;
   154     void *real_value_p = NULL;
   142     void *visible_value_p = NULL;
   155     void *visible_value_p = NULL;
   143     char flags = 0;
   156     char flags = 0;
   144 
   157 
   145     visible_value_p = UnpackVar(varp, vartype, &real_value_p, &flags);
   158     visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
   146 
   159 
   147     if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
   160     if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
   148         USINT size = __get_type_enum_size(vartype);
   161         USINT size = __get_type_enum_size(dsc->type);
   149         if(flags & __IEC_DEBUG_FLAG){
   162         if(flags & __IEC_DEBUG_FLAG){
   150             /* copy visible variable to buffer */;
   163             /* copy visible variable to buffer */;
   151             if(do_debug){
   164             if(do_debug){
   152                 /* compute next cursor positon.
   165                 /* compute next cursor positon.
   153                    No need to check overflow, as BUFFER_SIZE
   166                    No need to check overflow, as BUFFER_SIZE
   154                    is computed large enough */
   167                    is computed large enough */
   155                 if(vartype == STRING_ENUM){
   168                 if(dsc->type == STRING_ENUM){
   156                     /* optimization for strings */
   169                     /* optimization for strings */
   157                     size = ((STRING*)visible_value_p)->len + 1;
   170                     size = ((STRING*)visible_value_p)->len + 1;
   158                 }
   171                 }
   159                 char* next_cursor = buffer_cursor + size;
   172                 char* next_cursor = buffer_cursor + size;
   160                 /* copy data to the buffer */
   173                 /* copy data to the buffer */
   176             retain_offset = next_retain_offset;
   189             retain_offset = next_retain_offset;
   177         }
   190         }
   178     }
   191     }
   179 }
   192 }
   180 
   193 
   181 void DebugIterator(void* varp, __IEC_types_enum vartype){
   194 void DebugIterator(dbgvardsc_t *dsc){
   182     BufferIterator(varp, vartype, 1);
   195     BufferIterator(dsc, 1);
   183 }
   196 }
   184 
   197 
   185 void RetainIterator(void* varp, __IEC_types_enum vartype){
   198 void RetainIterator(dbgvardsc_t *dsc){
   186     BufferIterator(varp, vartype, 0);
   199     BufferIterator(dsc, 0);
   187 }
   200 }
   188 
   201 
   189 extern void PLC_GetTime(IEC_TIME*);
   202 extern void PLC_GetTime(IEC_TIME*);
   190 extern int TryEnterDebugSection(void);
   203 extern int TryEnterDebugSection(void);
   191 extern long AtomicCompareExchange(long*, long, long);
   204 extern long AtomicCompareExchange(long*, long, long);
   249              *(((__IEC_##TYPENAME##_p *)varp)->value) = *((TYPENAME *)force);\
   262              *(((__IEC_##TYPENAME##_p *)varp)->value) = *((TYPENAME *)force);\
   250             }\
   263             }\
   251             break;
   264             break;
   252 void RegisterDebugVariable(int idx, void* force)
   265 void RegisterDebugVariable(int idx, void* force)
   253 {
   266 {
   254     void *varp = NULL;
   267     if(idx  < sizeof(dbgvardsc)/sizeof(dbgvardsc_t)){
   255     unsigned char flags = force ? __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG : __IEC_DEBUG_FLAG;
   268         unsigned char flags = force ?
   256     switch(__find_variable(idx, &varp)){
   269             __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG :
   257         __ANY(__RegisterDebugVariable_case_t)
   270             __IEC_DEBUG_FLAG;
   258         __ANY(__RegisterDebugVariable_case_p)
   271         dbgvardsc_t *dsc = &dbgvardsc[idx];
   259     default:
   272         void *varp = dsc->ptr;
   260         break;
   273         switch(dsc->type){
       
   274             __ANY(__RegisterDebugVariable_case_t)
       
   275             __ANY(__RegisterDebugVariable_case_p)
       
   276         default:
       
   277             break;
       
   278         }
   261     }
   279     }
   262 }
   280 }
   263 
   281 
   264 #define __ResetDebugVariablesIterator_case_t(TYPENAME) \
   282 #define __ResetDebugVariablesIterator_case_t(TYPENAME) \
   265         case TYPENAME##_ENUM :\
   283         case TYPENAME##_ENUM :\
   270         case TYPENAME##_P_ENUM :\
   288         case TYPENAME##_P_ENUM :\
   271         case TYPENAME##_O_ENUM :\
   289         case TYPENAME##_O_ENUM :\
   272             ((__IEC_##TYPENAME##_p *)varp)->flags &= ~(__IEC_DEBUG_FLAG|__IEC_FORCE_FLAG);\
   290             ((__IEC_##TYPENAME##_p *)varp)->flags &= ~(__IEC_DEBUG_FLAG|__IEC_FORCE_FLAG);\
   273             break;
   291             break;
   274 
   292 
   275 void ResetDebugVariablesIterator(void* varp, __IEC_types_enum vartype)
   293 void ResetDebugVariablesIterator(dbgvardsc_t *dsc)
   276 {
   294 {
   277     /* force debug flag to 0*/
   295     /* force debug flag to 0*/
   278     switch(vartype){
   296     void *varp = dsc->ptr;
       
   297     switch(dsc->type){
   279         __ANY(__ResetDebugVariablesIterator_case_t)
   298         __ANY(__ResetDebugVariablesIterator_case_t)
   280         __ANY(__ResetDebugVariablesIterator_case_p)
   299         __ANY(__ResetDebugVariablesIterator_case_p)
   281     default:
   300     default:
   282         break;
   301         break;
   283     }
   302     }