targets/plc_debug.c
changeset 605 2250ed42e306
parent 582 bb5d0367bf32
child 611 b665a9001451
equal deleted inserted replaced
604:5b1c92060fc2 605:2250ed42e306
    53       *varp = NULL;
    53       *varp = NULL;
    54       return UNKNOWN_ENUM;
    54       return UNKNOWN_ENUM;
    55     }
    55     }
    56 }
    56 }
    57 
    57 
    58 #define __BufferDebugDataIterator_case_t(TYPENAME) \
    58 #define __Unpack_case_t(TYPENAME) \
    59         case TYPENAME##_ENUM :\
    59         case TYPENAME##_ENUM :\
    60             *flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\
    60             *flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\
    61             *ptrvalue = &((__IEC_##TYPENAME##_t *)varp)->value;\
    61             forced_value_p = *real_value_p = &((__IEC_##TYPENAME##_t *)varp)->value;\
    62             break;
    62             break;
    63 
    63 
    64 #define __BufferDebugDataIterator_case_p(TYPENAME)\
    64 #define __Unpack_case_p(TYPENAME)\
       
    65         case TYPENAME##_O_ENUM :\
       
    66             *flags = __IEC_OUTPUT_FLAG;\
    65         case TYPENAME##_P_ENUM :\
    67         case TYPENAME##_P_ENUM :\
    66         case TYPENAME##_O_ENUM :\
    68             *flags |= ((__IEC_##TYPENAME##_p *)varp)->flags;\
    67             *flags = ((__IEC_##TYPENAME##_p *)varp)->flags;\
    69             *real_value_p = ((__IEC_##TYPENAME##_p *)varp)->value;\
    68             if (*flags & __IEC_FORCE_FLAG)\
    70             forced_value_p = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\
    69                *ptrvalue = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\
    71             break;
    70             else\
    72 
    71                *ptrvalue = ((__IEC_##TYPENAME##_p *)varp)->value;\
    73 void* UnpackVar(void* varp, __IEC_types_enum vartype, void **real_value_p, char *flags)
    72             break;
    74 {
    73 
    75     void *forced_value_p = NULL;
    74 void UnpackVar(void* varp, __IEC_types_enum vartype, void **ptrvalue, char *flags)
    76     *flags = 0;
    75 {
       
    76     /* find data to copy*/
    77     /* find data to copy*/
    77     switch(vartype){
    78     switch(vartype){
    78         ANY(__BufferDebugDataIterator_case_t)
    79         ANY(__Unpack_case_t)
    79         ANY(__BufferDebugDataIterator_case_p)
    80         ANY(__Unpack_case_p)
    80     default:
    81     default:
    81         break;
    82         break;
    82     }
    83     }
       
    84     if (*flags & __IEC_FORCE_FLAG)
       
    85         return forced_value_p;
       
    86     return *real_value_p;
    83 }
    87 }
    84 
    88 
    85 void Remind(unsigned int offset, unsigned int count, void * p);
    89 void Remind(unsigned int offset, unsigned int count, void * p);
    86 
    90 
    87 void RemindIterator(void* varp, __IEC_types_enum vartype)
    91 void RemindIterator(void* varp, __IEC_types_enum vartype)
    88 {
    92 {
    89     void *ptrvalue = NULL;
    93     void *real_value_p = NULL;
    90     char flags = 0;
    94     char flags = 0;
    91     UnpackVar(varp, vartype, &ptrvalue, &flags);
    95     UnpackVar(varp, vartype, &real_value_p, &flags);
    92 
    96 
    93     if(flags & __IEC_RETAIN_FLAG){
    97     if(flags & __IEC_RETAIN_FLAG){
    94         USINT size = __get_type_enum_size(vartype);
    98         USINT size = __get_type_enum_size(vartype);
    95         /* compute next cursor positon*/
    99         /* compute next cursor positon*/
    96         unsigned int next_retain_offset = retain_offset + size;
   100         unsigned int next_retain_offset = retain_offset + size;
    97         /* if buffer not full */
   101         /* if buffer not full */
    98         Remind(retain_offset, size, ptrvalue);
   102         Remind(retain_offset, size, real_value_p);
    99         /* increment cursor according size*/
   103         /* increment cursor according size*/
   100         retain_offset = next_retain_offset;
   104         retain_offset = next_retain_offset;
   101     }
   105     }
   102 }
   106 }
   103 
   107 
   127 
   131 
   128 void __retrieve_debug(void)
   132 void __retrieve_debug(void)
   129 {
   133 {
   130 }
   134 }
   131 
   135 
   132 void DoDebug(void *ptrvalue, char flags, USINT size)
       
   133 {
       
   134     /* compute next cursor positon*/
       
   135     char* next_cursor = buffer_cursor + size;
       
   136     /* if buffer not full */
       
   137     if(next_cursor <= debug_buffer + BUFFER_SIZE)
       
   138     {
       
   139         /* copy data to the buffer */
       
   140         memcpy(buffer_cursor, ptrvalue, size);
       
   141         /* increment cursor according size*/
       
   142         buffer_cursor = next_cursor;
       
   143     }else{
       
   144         /*TODO : signal overflow*/
       
   145     }
       
   146 }
       
   147 
   136 
   148 void Retain(unsigned int offset, unsigned int count, void * p);
   137 void Retain(unsigned int offset, unsigned int count, void * p);
   149 void DoRetain(void *ptrvalue, char flags, USINT size){
   138 
   150     /* compute next cursor positon*/
   139 inline void BufferIterator(void* varp, __IEC_types_enum vartype, int do_debug)
   151     unsigned int next_retain_offset = retain_offset + size;
   140 {
   152     /* if buffer not full */
   141     void *real_value_p = NULL;
   153     Retain(retain_offset, size, ptrvalue);
   142     void *visible_value_p = NULL;
   154     /* increment cursor according size*/
       
   155     retain_offset = next_retain_offset;
       
   156 }
       
   157 
       
   158 void BufferDebugDataIterator(void* varp, __IEC_types_enum vartype)
       
   159 {
       
   160     void *ptrvalue = NULL;
       
   161     char flags = 0;
   143     char flags = 0;
   162     UnpackVar(varp, vartype, &ptrvalue, &flags);
   144 
   163     /* For optimization purpose we do retain and debug in the same pass */
   145     visible_value_p = UnpackVar(varp, vartype, &real_value_p, &flags);
   164     if(flags & (__IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
   146 
       
   147     if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){
   165         USINT size = __get_type_enum_size(vartype);
   148         USINT size = __get_type_enum_size(vartype);
   166         if(flags & __IEC_DEBUG_FLAG){
   149         if(flags & __IEC_DEBUG_FLAG){
   167             DoDebug(ptrvalue, flags, size);
   150             /* copy visible variable to buffer */;
       
   151             if(do_debug){
       
   152                 /* compute next cursor positon.
       
   153                    No need to check overflow, as BUFFER_SIZE
       
   154                    is computed large enough */
       
   155                 char* next_cursor = buffer_cursor + size;
       
   156                 /* copy data to the buffer */
       
   157                 memcpy(buffer_cursor, visible_value_p, size);
       
   158                 /* increment cursor according size*/
       
   159                 buffer_cursor = next_cursor;
       
   160             }
       
   161             /* re-force real value of outputs (M and Q)*/
       
   162             if(flags & (__IEC_FORCE_FLAG | __IEC_OUTPUT_FLAG)){
       
   163                 memcpy(real_value_p, visible_value_p, size);
       
   164             }
   168         }
   165         }
   169         if(flags & __IEC_RETAIN_FLAG){
   166         if(flags & __IEC_RETAIN_FLAG){
   170             DoRetain(ptrvalue, flags, size);
   167             /* compute next cursor positon*/
       
   168             unsigned int next_retain_offset = retain_offset + size;
       
   169             /* if buffer not full */
       
   170             Retain(retain_offset, size, real_value_p);
       
   171             /* increment cursor according size*/
       
   172             retain_offset = next_retain_offset;
   171         }
   173         }
   172     }
   174     }
   173 }
   175 }
   174 
   176 
   175 void RetainIterator(void* varp, __IEC_types_enum vartype)
   177 void DebugIterator(void* varp, __IEC_types_enum vartype){
   176 {
   178     BufferIterator(varp, vartype, 1);
   177     void *ptrvalue = NULL;
   179 }
   178     char flags = 0;
   180 
   179     UnpackVar(varp, vartype, &ptrvalue, &flags);
   181 void RetainIterator(void* varp, __IEC_types_enum vartype){
   180 
   182     BufferIterator(varp, vartype, 0);
   181     if(flags & __IEC_RETAIN_FLAG){
       
   182         USINT size = __get_type_enum_size(vartype);
       
   183         DoRetain(ptrvalue, flags, size);
       
   184     }
       
   185 }
   183 }
   186 
   184 
   187 extern int TryEnterDebugSection(void);
   185 extern int TryEnterDebugSection(void);
   188 extern long AtomicCompareExchange(long*, long, long);
   186 extern long AtomicCompareExchange(long*, long, long);
   189 extern void LeaveDebugSection(void);
   187 extern void LeaveDebugSection(void);
   206         if(latest_state == BUFFER_FREE)
   204         if(latest_state == BUFFER_FREE)
   207         {
   205         {
   208             /* Reset buffer cursor */
   206             /* Reset buffer cursor */
   209             buffer_cursor = debug_buffer;
   207             buffer_cursor = debug_buffer;
   210             /* Iterate over all variables to fill debug buffer */
   208             /* Iterate over all variables to fill debug buffer */
   211             __for_each_variable_do(BufferDebugDataIterator);
   209             __for_each_variable_do(DebugIterator);
   212             
   210             
   213             /* Leave debug section,
   211             /* Leave debug section,
   214              * Trigger asynchronous transmission 
   212              * Trigger asynchronous transmission 
   215              * (returns immediately) */
   213              * (returns immediately) */
   216             InitiateDebugTransfer(); /* size */
   214             InitiateDebugTransfer(); /* size */