targets/plc_debug.c
changeset 483 bc26c42d2eec
parent 477 f66a092b6e74
child 491 28afed8b1af5
equal deleted inserted replaced
482:7c83eb6a55bd 483:bc26c42d2eec
    27 /* The buffer itself */
    27 /* The buffer itself */
    28 char debug_buffer[BUFFER_SIZE];
    28 char debug_buffer[BUFFER_SIZE];
    29 
    29 
    30 /* Buffer's cursor*/
    30 /* Buffer's cursor*/
    31 static char* buffer_cursor = debug_buffer;
    31 static char* buffer_cursor = debug_buffer;
    32 
    32 static unsigned int retain_offset = 0;
    33 /***
    33 /***
    34  * Declare programs 
    34  * Declare programs 
    35  **/
    35  **/
    36 %(programs_declarations)s
    36 %(programs_declarations)s
    37 
    37 
    54       *varp = NULL;
    54       *varp = NULL;
    55       return UNKNOWN_ENUM;
    55       return UNKNOWN_ENUM;
    56     }
    56     }
    57 }
    57 }
    58 
    58 
    59 void __init_debug(void)
       
    60 {
       
    61     buffer_state = BUFFER_FREE;
       
    62 }
       
    63 
       
    64 void __cleanup_debug(void)
       
    65 {
       
    66 }
       
    67 
       
    68 void __retrieve_debug(void)
       
    69 {
       
    70 }
       
    71 
       
    72 extern int TryEnterDebugSection(void);
       
    73 extern void LeaveDebugSection(void);
       
    74 extern long AtomicCompareExchange(long*, long, long);
       
    75 extern void InitiateDebugTransfer(void);
       
    76 
       
    77 extern unsigned long __tick;
       
    78 
       
    79 #define __BufferDebugDataIterator_case_t(TYPENAME) \
    59 #define __BufferDebugDataIterator_case_t(TYPENAME) \
    80         case TYPENAME##_ENUM :\
    60         case TYPENAME##_ENUM :\
    81             flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\
    61             *flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\
    82             ptrvalue = &((__IEC_##TYPENAME##_t *)varp)->value;\
    62             *ptrvalue = &((__IEC_##TYPENAME##_t *)varp)->value;\
    83             break;
    63             break;
    84 
    64 
    85 #define __BufferDebugDataIterator_case_p(TYPENAME)\
    65 #define __BufferDebugDataIterator_case_p(TYPENAME)\
    86         case TYPENAME##_P_ENUM :\
    66         case TYPENAME##_P_ENUM :\
    87             flags = ((__IEC_##TYPENAME##_p *)varp)->flags;\
    67             *flags = ((__IEC_##TYPENAME##_p *)varp)->flags;\
    88             ptrvalue = ((__IEC_##TYPENAME##_p *)varp)->value;\
    68             *ptrvalue = ((__IEC_##TYPENAME##_p *)varp)->value;\
    89             break;
    69             break;
    90 
    70 
    91 void BufferDebugDataIterator(void* varp, __IEC_types_enum vartype)
    71 void UnpackVar(void* varp, __IEC_types_enum vartype, void **ptrvalue, char *flags)
    92 {
    72 {
    93     void *ptrvalue = NULL;
       
    94     char flags = 0;
       
    95     /* find data to copy*/
    73     /* find data to copy*/
    96     switch(vartype){
    74     switch(vartype){
    97         ANY(__BufferDebugDataIterator_case_t)
    75         ANY(__BufferDebugDataIterator_case_t)
    98         ANY(__BufferDebugDataIterator_case_p)
    76         ANY(__BufferDebugDataIterator_case_p)
    99     default:
    77     default:
   100         break;
    78         break;
   101     }
    79     }
   102     if(flags && __IEC_DEBUG_FLAG){
    80 }
       
    81 
       
    82 void Remind(unsigned int offset, unsigned int count, void * p);
       
    83 
       
    84 void RemindIterator(void* varp, __IEC_types_enum vartype)
       
    85 {
       
    86     void *ptrvalue = NULL;
       
    87     char flags = 0;
       
    88     UnpackVar(varp, vartype, &ptrvalue, &flags);
       
    89 
       
    90     if(flags && __IEC_RETAIN_FLAG){
   103         USINT size = __get_type_enum_size(vartype);
    91         USINT size = __get_type_enum_size(vartype);
   104         /* compute next cursor positon*/
    92         /* compute next cursor positon*/
   105         char* next_cursor = buffer_cursor + size;
    93         unsigned int next_retain_offset = retain_offset + size;
   106         /* if buffer not full */
    94         /* if buffer not full */
   107         if(next_cursor <= debug_buffer + BUFFER_SIZE)
    95         Remind(retain_offset, size, ptrvalue);
   108         {
    96         /* increment cursor according size*/
   109             /* copy data to the buffer */
    97         retain_offset = next_retain_offset;
   110             memcpy(buffer_cursor, ptrvalue, size);
    98     }
   111             /* increment cursor according size*/
    99 }
   112             buffer_cursor = next_cursor;
   100 
   113         }else{
   101 void __init_debug(void)
   114             /*TODO : signal overflow*/
   102 {
       
   103     /* init local static vars */
       
   104     buffer_cursor = debug_buffer;
       
   105     retain_offset = 0;
       
   106     buffer_state = BUFFER_FREE;
       
   107     /* Iterate over all variables to fill debug buffer */
       
   108     __for_each_variable_do(RemindIterator);
       
   109     retain_offset = 0;
       
   110 }
       
   111 
       
   112 extern void InitiateDebugTransfer(void);
       
   113 
       
   114 extern unsigned long __tick;
       
   115 
       
   116 void __cleanup_debug(void)
       
   117 {
       
   118     buffer_cursor = debug_buffer;
       
   119     InitiateDebugTransfer();
       
   120 }
       
   121 
       
   122 void __retrieve_debug(void)
       
   123 {
       
   124 }
       
   125 
       
   126 void DoDebug(void *ptrvalue, char flags, USINT size)
       
   127 {
       
   128     /* compute next cursor positon*/
       
   129     char* next_cursor = buffer_cursor + size;
       
   130     /* if buffer not full */
       
   131     if(next_cursor <= debug_buffer + BUFFER_SIZE)
       
   132     {
       
   133         /* copy data to the buffer */
       
   134         memcpy(buffer_cursor, ptrvalue, size);
       
   135         /* increment cursor according size*/
       
   136         buffer_cursor = next_cursor;
       
   137     }else{
       
   138         /*TODO : signal overflow*/
       
   139     }
       
   140 }
       
   141 
       
   142 void Retain(unsigned int offset, unsigned int count, void * p);
       
   143 void DoRetain(void *ptrvalue, char flags, USINT size){
       
   144     /* compute next cursor positon*/
       
   145     unsigned int next_retain_offset = retain_offset + size;
       
   146     /* if buffer not full */
       
   147     Retain(retain_offset, size, ptrvalue);
       
   148     /* increment cursor according size*/
       
   149     retain_offset = next_retain_offset;
       
   150 }
       
   151 
       
   152 void BufferDebugDataIterator(void* varp, __IEC_types_enum vartype)
       
   153 {
       
   154     void *ptrvalue = NULL;
       
   155     char flags = 0;
       
   156     UnpackVar(varp, vartype, &ptrvalue, &flags);
       
   157     /* For optimization purpose we do retain and debug in the same pass */
       
   158     if(flags & (__IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
       
   159         USINT size = __get_type_enum_size(vartype);
       
   160         if(flags & __IEC_DEBUG_FLAG){
       
   161             DoDebug(ptrvalue, flags, size);
   115         }
   162         }
   116     }
   163         if(flags & __IEC_RETAIN_FLAG){
   117 }
   164             DoRetain(ptrvalue, flags, size);
   118 
   165         }
       
   166     }
       
   167 }
       
   168 
       
   169 void RetainIterator(void* varp, __IEC_types_enum vartype)
       
   170 {
       
   171     void *ptrvalue = NULL;
       
   172     char flags = 0;
       
   173     UnpackVar(varp, vartype, &ptrvalue, &flags);
       
   174 
       
   175     if(flags & __IEC_RETAIN_FLAG){
       
   176         USINT size = __get_type_enum_size(vartype);
       
   177         DoRetain(ptrvalue, flags, size);
       
   178     }
       
   179 }
       
   180 
       
   181 extern int TryEnterDebugSection(void);
       
   182 extern long AtomicCompareExchange(long*, long, long);
       
   183 extern void LeaveDebugSection(void);
   119 
   184 
   120 void __publish_debug(void)
   185 void __publish_debug(void)
   121 {
   186 {
       
   187     retain_offset = 0;
   122     /* Check there is no running debugger re-configuration */
   188     /* Check there is no running debugger re-configuration */
   123     if(TryEnterDebugSection()){
   189     if(TryEnterDebugSection()){
   124         /* Lock buffer */
   190         /* Lock buffer */
   125         long latest_state = AtomicCompareExchange(
   191         long latest_state = AtomicCompareExchange(
   126             &buffer_state,
   192             &buffer_state,
   139              * Trigger asynchronous transmission 
   205              * Trigger asynchronous transmission 
   140              * (returns immediately) */
   206              * (returns immediately) */
   141             InitiateDebugTransfer(); /* size */
   207             InitiateDebugTransfer(); /* size */
   142         }
   208         }
   143         LeaveDebugSection();
   209         LeaveDebugSection();
       
   210     }else{
       
   211         /* when not debugging, do only retain */
       
   212         __for_each_variable_do(RetainIterator);
   144     }
   213     }
   145 }
   214 }
   146 
   215 
   147 #define __RegisterDebugVariable_case_t(TYPENAME) \
   216 #define __RegisterDebugVariable_case_t(TYPENAME) \
   148         case TYPENAME##_ENUM :\
   217         case TYPENAME##_ENUM :\