targets/plc_debug.c
branchRuntimeLists
changeset 3394 9ea29ac18837
parent 2710 aaa1dc426213
child 3395 93ad018fb602
equal deleted inserted replaced
3393:a65bcbb6af20 3394:9ea29ac18837
    24 /*for memcpy*/
    24 /*for memcpy*/
    25 #include <string.h>
    25 #include <string.h>
    26 #include <stdio.h>
    26 #include <stdio.h>
    27 
    27 
    28 #ifndef TARGET_ONLINE_DEBUG_DISABLE
    28 #ifndef TARGET_ONLINE_DEBUG_DISABLE
    29 #define BUFFER_SIZE %(buffer_size)d
    29 #define TRACE_BUFFER_SIZE 4096
       
    30 #define TRACE_LIST_SIZE 1024
    30 
    31 
    31 /* Atomically accessed variable for buffer state */
    32 /* Atomically accessed variable for buffer state */
    32 #define BUFFER_FREE 0
    33 #define BUFFER_FREE 0
    33 #define BUFFER_BUSY 1
    34 #define BUFFER_BUSY 1
    34 static long buffer_state = BUFFER_FREE;
    35 static long trace_buffer_state = BUFFER_FREE;
    35 
    36 
    36 /* The buffer itself */
    37 typedef unsigned int dbgvardsc_index_t;
    37 char debug_buffer[BUFFER_SIZE];
    38 typedef unsigned short trace_buf_offset_t;
       
    39 
       
    40 typedef struct trace_item_s {
       
    41     dbgvardsc_index_t dbgvardsc_index;
       
    42 } trace_item_t;
       
    43 
       
    44 trace_item_t trace_list[TRACE_LIST_SIZE];
       
    45 char trace_buffer[TRACE_BUFFER_SIZE];
    38 
    46 
    39 /* Buffer's cursor*/
    47 /* Buffer's cursor*/
    40 static char* buffer_cursor = debug_buffer;
    48 static trace_item_t *trace_list_collect_cursor = trace_list;
       
    49 static trace_item_t *trace_list_addvar_cursor = trace_list;
       
    50 static const trace_item_t *trace_list_end = 
       
    51     &trace_list[TRACE_LIST_SIZE-1];
       
    52 static char *trace_buffer_cursor = trace_buffer;
       
    53 static const char *trace_buffer_end = trace_buffer + TRACE_BUFFER_SIZE;
    41 #endif
    54 #endif
    42 
    55 
    43 static unsigned int retain_offset = 0;
    56 static unsigned int retain_offset = 0;
    44 /***
    57 /***
    45  * Declare programs 
    58  * Declare programs 
    99 
   112 
   100 void __init_debug(void)
   113 void __init_debug(void)
   101 {
   114 {
   102     /* init local static vars */
   115     /* init local static vars */
   103 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   116 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   104     buffer_cursor = debug_buffer;
   117     trace_buffer_cursor = trace_buffer;
   105     buffer_state = BUFFER_FREE;
   118     trace_list_addvar_cursor = trace_list;
       
   119     trace_list_collect_cursor = trace_list;
       
   120     trace_buffer_state = BUFFER_FREE;
   106 #endif
   121 #endif
   107 
   122 
   108     retain_offset = 0;
   123     retain_offset = 0;
   109     InitRetain();
   124     InitRetain();
   110     /* Iterate over all variables to fill debug buffer */
   125     /* Iterate over all variables to fill debug buffer */
   123 extern unsigned long __tick;
   138 extern unsigned long __tick;
   124 
   139 
   125 void __cleanup_debug(void)
   140 void __cleanup_debug(void)
   126 {
   141 {
   127 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   142 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   128     buffer_cursor = debug_buffer;
   143     trace_buffer_cursor = trace_buffer;
   129     InitiateDebugTransfer();
   144     InitiateDebugTransfer();
   130 #endif    
   145 #endif    
   131 
   146 
   132     CleanupRetain();
   147     CleanupRetain();
   133 }
   148 }
   145     void *visible_value_p = NULL;
   160     void *visible_value_p = NULL;
   146     char flags = 0;
   161     char flags = 0;
   147 
   162 
   148     visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
   163     visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
   149 
   164 
   150     if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
   165     if(flags & __IEC_RETAIN_FLAG ||
       
   166        ((flags & __IEC_FORCE_FLAG) && (flags & __IEC_OUTPUT_FLAG))){
   151         USINT size = __get_type_enum_size(dsc->type);
   167         USINT size = __get_type_enum_size(dsc->type);
   152 
   168 
   153 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   169 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   154         if(flags & __IEC_DEBUG_FLAG){
   170         if((flags & __IEC_FORCE_FLAG) && (flags & __IEC_OUTPUT_FLAG)){
   155             /* copy visible variable to buffer */;
   171             if(__Is_a_string(dsc)){
   156             if(do_debug){
   172                 /* optimization for strings */
   157                 /* compute next cursor positon.
   173                 size = ((STRING*)visible_value_p)->len + 1;
   158                    No need to check overflow, as BUFFER_SIZE
       
   159                    is computed large enough */
       
   160                 if(__Is_a_string(dsc)){
       
   161                     /* optimization for strings */
       
   162                     size = ((STRING*)visible_value_p)->len + 1;
       
   163                 }
       
   164                 char* next_cursor = buffer_cursor + size;
       
   165                 /* copy data to the buffer */
       
   166                 memcpy(buffer_cursor, visible_value_p, size);
       
   167                 /* increment cursor according size*/
       
   168                 buffer_cursor = next_cursor;
       
   169             }
   174             }
   170             /* re-force real value of outputs (M and Q)*/
   175             /* re-force real value of outputs (M and Q)*/
   171             if((flags & __IEC_FORCE_FLAG) && (flags & __IEC_OUTPUT_FLAG)){
   176             memcpy(real_value_p, visible_value_p, size);
   172                 memcpy(real_value_p, visible_value_p, size);
       
   173             }
       
   174         }
   177         }
   175 #endif
   178 #endif
   176 
   179 
   177         if(flags & __IEC_RETAIN_FLAG){
   180         if(flags & __IEC_RETAIN_FLAG){
   178             /* compute next cursor positon*/
   181             /* compute next cursor positon*/
   234 #ifndef TARGET_ONLINE_DEBUG_DISABLE 
   237 #ifndef TARGET_ONLINE_DEBUG_DISABLE 
   235     /* Check there is no running debugger re-configuration */
   238     /* Check there is no running debugger re-configuration */
   236     if(TryEnterDebugSection()){
   239     if(TryEnterDebugSection()){
   237         /* Lock buffer */
   240         /* Lock buffer */
   238         long latest_state = AtomicCompareExchange(
   241         long latest_state = AtomicCompareExchange(
   239             &buffer_state,
   242             &trace_buffer_state,
   240             BUFFER_FREE,
   243             BUFFER_FREE,
   241             BUFFER_BUSY);
   244             BUFFER_BUSY);
   242             
   245             
   243         /* If buffer was free */
   246         /* If buffer was free */
   244         if(latest_state == BUFFER_FREE)
   247         if(latest_state == BUFFER_FREE)
   245         {
   248         {
   246             /* Reset buffer cursor */
   249             /* Reset buffer cursor */
   247             buffer_cursor = debug_buffer;
   250             trace_buffer_cursor = trace_buffer;
       
   251             /* Reset trace list cursor */
       
   252             trace_list_collect_cursor = trace_list;
   248             /* Iterate over all variables to fill debug buffer */
   253             /* Iterate over all variables to fill debug buffer */
   249             __for_each_variable_do(DebugIterator);
   254             __for_each_variable_do(DebugIterator);
       
   255             while(trace_list_collect_cursor < trace_list_addvar_cursor){
       
   256                 void *real_value_p = NULL;
       
   257                 void *visible_value_p = NULL;
       
   258                 char flags = 0;
       
   259                 USINT size;
       
   260                 char* next_cursor;
       
   261 
       
   262                 dbgvardsc_t *dsc = &dbgvardsc[
       
   263                     trace_list_collect_cursor->dbgvardsc_index];
       
   264 
       
   265                 visible_value_p = UnpackVar(dsc, &real_value_p, &flags);
       
   266 
       
   267                 /* copy visible variable to buffer */;
       
   268                 if(__Is_a_string(dsc)){
       
   269                     /* optimization for strings */
       
   270                     /* assume NULL terminated strings */
       
   271                     size = ((STRING*)visible_value_p)->len + 1;
       
   272                 }else{
       
   273                     size = __get_type_enum_size(dsc->type);
       
   274                 }
       
   275 
       
   276                 /* compute next cursor positon.*/
       
   277                 next_cursor = trace_buffer_cursor + size;
       
   278                 /* check for buffer overflow */
       
   279                 if(next_cursor < trace_buffer_end)
       
   280                     /* copy data to the buffer */
       
   281                     memcpy(trace_buffer_cursor, visible_value_p, size);
       
   282                 else
       
   283                     /* stop looping in case of overflow */
       
   284                     break;
       
   285                 /* increment cursor according size*/
       
   286                 trace_buffer_cursor = next_cursor;
       
   287                 trace_list_collect_cursor++;
       
   288             }
   250             
   289             
   251             /* Leave debug section,
   290             /* Leave debug section,
   252              * Trigger asynchronous transmission 
   291              * Trigger asynchronous transmission 
   253              * (returns immediately) */
   292              * (returns immediately) */
   254             InitiateDebugTransfer(); /* size */
   293             InitiateDebugTransfer(); /* size */
   255         }else{
       
   256             /* when not debugging, do only retain */
       
   257             __for_each_variable_do(RetainIterator);
       
   258         }
   294         }
   259         LeaveDebugSection();
   295         LeaveDebugSection();
   260     }else
   296     }
   261 #endif
   297 #endif
   262     {
   298     /* when not debugging, do only retain */
   263         /* when not debugging, do only retain */
   299     __for_each_variable_do(RetainIterator);
   264         __for_each_variable_do(RetainIterator);
       
   265     }
       
   266     ValidateRetainBuffer();
   300     ValidateRetainBuffer();
   267 }
   301 }
   268 
   302 
   269 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   303 #ifndef TARGET_ONLINE_DEBUG_DISABLE
   270 #define __RegisterDebugVariable_case_t(TYPENAME) \
   304 #define __RegisterDebugVariable_case_t(TYPENAME) \
   271         case TYPENAME##_ENUM :\
   305         case TYPENAME##_ENUM :\
   272             ((__IEC_##TYPENAME##_t *)varp)->flags |= flags;\
   306             ((__IEC_##TYPENAME##_t *)varp)->flags |= __IEC_FORCE_FLAG;\
   273             if(force)\
   307             ((__IEC_##TYPENAME##_t *)varp)->value = *((TYPENAME *)force);\
   274              ((__IEC_##TYPENAME##_t *)varp)->value = *((TYPENAME *)force);\
       
   275             break;
   308             break;
   276 #define __RegisterDebugVariable_case_p(TYPENAME)\
   309 #define __RegisterDebugVariable_case_p(TYPENAME)\
   277         case TYPENAME##_P_ENUM :\
   310         case TYPENAME##_P_ENUM :\
   278             ((__IEC_##TYPENAME##_p *)varp)->flags |= flags;\
   311             ((__IEC_##TYPENAME##_p *)varp)->flags |= __IEC_FORCE_FLAG;\
   279             if(force)\
   312             ((__IEC_##TYPENAME##_p *)varp)->fvalue = *((TYPENAME *)force);\
   280              ((__IEC_##TYPENAME##_p *)varp)->fvalue = *((TYPENAME *)force);\
       
   281             break;\
   313             break;\
   282         case TYPENAME##_O_ENUM :\
   314         case TYPENAME##_O_ENUM :\
   283             ((__IEC_##TYPENAME##_p *)varp)->flags |= flags;\
   315             ((__IEC_##TYPENAME##_p *)varp)->flags |= __IEC_FORCE_FLAG;\
   284             if(force){\
   316             ((__IEC_##TYPENAME##_p *)varp)->fvalue = *((TYPENAME *)force);\
   285              ((__IEC_##TYPENAME##_p *)varp)->fvalue = *((TYPENAME *)force);\
   317             *(((__IEC_##TYPENAME##_p *)varp)->value) = *((TYPENAME *)force);\
   286              *(((__IEC_##TYPENAME##_p *)varp)->value) = *((TYPENAME *)force);\
       
   287             }\
       
   288             break;
   318             break;
   289 void RegisterDebugVariable(unsigned int idx, void* force)
   319 void RegisterDebugVariable(dbgvardsc_index_t idx, void* force)
   290 {
   320 {
   291     if(idx  < sizeof(dbgvardsc)/sizeof(dbgvardsc_t)){
   321     if(idx < sizeof(dbgvardsc)/sizeof(dbgvardsc_t)){
   292         unsigned char flags = force ?
   322         /* add to trace_list, inc tracelist_addvar_cursor*/
   293             __IEC_DEBUG_FLAG | __IEC_FORCE_FLAG :
   323         if(trace_list_addvar_cursor <= trace_list_end){
   294             __IEC_DEBUG_FLAG;
   324             trace_list_addvar_cursor->dbgvardsc_index = idx;
   295         dbgvardsc_t *dsc = &dbgvardsc[idx];
   325             trace_list_addvar_cursor++;
   296         void *varp = dsc->ptr;
   326         }
   297         switch(dsc->type){
   327         if(force){
   298             __ANY(__RegisterDebugVariable_case_t)
   328             dbgvardsc_t *dsc = &dbgvardsc[idx];
   299             __ANY(__RegisterDebugVariable_case_p)
   329             void *varp = dsc->ptr;
   300         default:
   330             switch(dsc->type){
   301             break;
   331                 __ANY(__RegisterDebugVariable_case_t)
       
   332                 __ANY(__RegisterDebugVariable_case_p)
       
   333             default:
       
   334                 break;
       
   335             }
   302         }
   336         }
   303     }
   337     }
   304 }
   338 }
   305 
   339 
   306 #define __ResetDebugVariablesIterator_case_t(TYPENAME) \
   340 #define __ResetDebugVariablesIterator_case_t(TYPENAME) \
   307         case TYPENAME##_ENUM :\
   341         case TYPENAME##_ENUM :\
   308             ((__IEC_##TYPENAME##_t *)varp)->flags &= ~(__IEC_DEBUG_FLAG|__IEC_FORCE_FLAG);\
   342             ((__IEC_##TYPENAME##_t *)varp)->flags &= ~(__IEC_FORCE_FLAG);\
   309             break;
   343             break;
   310 
   344 
   311 #define __ResetDebugVariablesIterator_case_p(TYPENAME)\
   345 #define __ResetDebugVariablesIterator_case_p(TYPENAME)\
   312         case TYPENAME##_P_ENUM :\
   346         case TYPENAME##_P_ENUM :\
   313         case TYPENAME##_O_ENUM :\
   347         case TYPENAME##_O_ENUM :\
   314             ((__IEC_##TYPENAME##_p *)varp)->flags &= ~(__IEC_DEBUG_FLAG|__IEC_FORCE_FLAG);\
   348             ((__IEC_##TYPENAME##_p *)varp)->flags &= ~(__IEC_FORCE_FLAG);\
   315             break;
   349             break;
   316 
   350 
   317 void ResetDebugVariablesIterator(dbgvardsc_t *dsc)
   351 void ResetDebugVariablesIterator(dbgvardsc_t *dsc)
   318 {
   352 {
   319     /* force debug flag to 0*/
   353     /* force debug flag to 0*/
   326     }
   360     }
   327 }
   361 }
   328 
   362 
   329 void ResetDebugVariables(void)
   363 void ResetDebugVariables(void)
   330 {
   364 {
       
   365     trace_list_addvar_cursor = trace_list;
   331     __for_each_variable_do(ResetDebugVariablesIterator);
   366     __for_each_variable_do(ResetDebugVariablesIterator);
   332 }
   367 }
   333 
   368 
   334 void FreeDebugData(void)
   369 void FreeDebugData(void)
   335 {
   370 {
   336     /* atomically mark buffer as free */
   371     /* atomically mark buffer as free */
   337     AtomicCompareExchange(
   372     AtomicCompareExchange(
   338         &buffer_state,
   373         &trace_buffer_state,
   339         BUFFER_BUSY,
   374         BUFFER_BUSY,
   340         BUFFER_FREE);
   375         BUFFER_FREE);
   341 }
   376 }
   342 int WaitDebugData(unsigned long *tick);
   377 int WaitDebugData(unsigned long *tick);
   343 /* Wait until debug data ready and return pointer to it */
   378 /* Wait until debug data ready and return pointer to it */
   344 int GetDebugData(unsigned long *tick, unsigned long *size, void **buffer){
   379 int GetDebugData(unsigned long *tick, unsigned long *size, void **buffer){
   345     int wait_error = WaitDebugData(tick);
   380     int wait_error = WaitDebugData(tick);
   346     if(!wait_error){
   381     if(!wait_error){
   347         *size = buffer_cursor - debug_buffer;
   382         *size = trace_buffer_cursor - trace_buffer;
   348         *buffer = debug_buffer;
   383         *buffer = trace_buffer;
   349     }
   384     }
   350     return wait_error;
   385     return wait_error;
   351 }
   386 }
   352 #endif
   387 #endif
   353 #endif
   388 #endif