targets/plc_debug.c
changeset 450 18583d13f0fa
parent 423 4d7ac355701d
child 452 2d0718a05cc7
equal deleted inserted replaced
449:9d5036e86c3d 450:18583d13f0fa
    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 
    33 typedef struct{
       
    34     void* ptrvalue;
       
    35     __IEC_types_enum type;
       
    36 }struct_plcvar;
       
    37 
       
    38 /***
    33 /***
    39  * Declare programs 
    34  * Declare programs 
    40  **/
    35  **/
    41 %(programs_declarations)s
    36 %(programs_declarations)s
    42 
    37 
    43 /***
    38 /***
    44  * Declare global variables from resources and conf 
    39  * Declare global variables from resources and conf 
    45  **/
    40  **/
    46 %(extern_variables_declarations)s
    41 %(extern_variables_declarations)s
    47 
    42 
    48 static int subscription_table[MAX_SUBSCRIBTION];
    43 typedef void(*__for_each_variable_do_fp)(void*, __IEC_types_enum);
    49 static int* latest_subscription = subscription_table;
    44 __for_each_variable_do(__for_each_variable_do_fp fp)
    50 static int* subscription_cursor = subscription_table;
    45 {
       
    46 %(for_each_variable_do_code)s
       
    47 }
    51 
    48 
    52 struct_plcvar variable_table[%(variables_pointer_type_table_count)d];
    49 __IEC_types_enum __find_variable(unsigned int varindex, void ** varp)
       
    50 {
       
    51     switch(varindex){
       
    52 %(find_variable_case_code)s
       
    53     }
       
    54     *varp = NULL;
       
    55     return UNKNOWN_ENUM;
       
    56 }
    53 
    57 
    54 void __init_debug(void)
    58 void __init_debug(void)
    55 {
    59 {
    56 %(variables_pointer_type_table_initializer)s
       
    57     buffer_state = BUFFER_FREE;
    60     buffer_state = BUFFER_FREE;
    58 }
    61 }
    59 
    62 
    60 void __cleanup_debug(void)
    63 void __cleanup_debug(void)
    61 {
    64 {
    69 extern void LeaveDebugSection(void);
    72 extern void LeaveDebugSection(void);
    70 extern long AtomicCompareExchange(long*, long, long);
    73 extern long AtomicCompareExchange(long*, long, long);
    71 extern void InitiateDebugTransfer(void);
    74 extern void InitiateDebugTransfer(void);
    72 
    75 
    73 extern unsigned long __tick;
    76 extern unsigned long __tick;
       
    77 
       
    78 #define __BufferDebugDataIterator_case_t(TYPENAME) \
       
    79         case TYPENAME##_ENUM :\
       
    80             flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\
       
    81             ptrvalue = &((__IEC_##TYPENAME##_t *)varp)->value;
       
    82 
       
    83 #define __BufferDebugDataIterator_case_p(TYPENAME)\
       
    84         case TYPENAME##_P_ENUM :\
       
    85             flags = ((__IEC_##TYPENAME##_p *)varp)->flags;\
       
    86             ptrvalue = ((__IEC_##TYPENAME##_p *)varp)->value;
       
    87 
       
    88 void BufferDebugDataIterator(void* varp, __IEC_types_enum vartype)
       
    89 {
       
    90     void *ptrvalue = NULL;
       
    91     char flags = 0;
       
    92     /* find data to copy*/
       
    93     switch(vartype){
       
    94         ANY(__BufferDebugDataIterator_case_t)
       
    95         ANY(__BufferDebugDataIterator_case_p)
       
    96     }
       
    97     if(flags && __IEC_DEBUG_FLAG){
       
    98         USINT size = __get_type_enum_size(vartype);
       
    99         /* compute next cursor positon*/
       
   100         char* next_cursor = buffer_cursor + size;
       
   101         /* if buffer not full */
       
   102         if(next_cursor <= debug_buffer + BUFFER_SIZE)
       
   103         {
       
   104             /* copy data to the buffer */
       
   105             memcpy(buffer_cursor, ptrvalue, size);
       
   106             /* increment cursor according size*/
       
   107             buffer_cursor = next_cursor;
       
   108         }else{
       
   109             /*TODO : signal overflow*/
       
   110         }
       
   111     }
       
   112 }
       
   113 
       
   114 
    74 void __publish_debug(void)
   115 void __publish_debug(void)
    75 {
   116 {
    76     /* Check there is no running debugger re-configuration */
   117     /* Check there is no running debugger re-configuration */
    77     if(TryEnterDebugSection()){
   118     if(TryEnterDebugSection()){
    78         /* Lock buffer */
   119         /* Lock buffer */
    82             BUFFER_BUSY);
   123             BUFFER_BUSY);
    83             
   124             
    84         /* If buffer was free */
   125         /* If buffer was free */
    85         if(latest_state == BUFFER_FREE)
   126         if(latest_state == BUFFER_FREE)
    86         {
   127         {
    87             int* subscription;
       
    88             
       
    89             /* Reset buffer cursor */
   128             /* Reset buffer cursor */
    90             buffer_cursor = debug_buffer;
   129             buffer_cursor = debug_buffer;
    91             
   130             /* Iterate over all variables to fill debug buffer */
    92             /* iterate over subscriptions */
   131             __for_each_variable_do(BufferDebugDataIterator);
    93             for(subscription=subscription_table;
       
    94                 subscription < latest_subscription;
       
    95                 subscription++)
       
    96             {
       
    97                 /* get variable descriptor */
       
    98                 struct_plcvar* my_var = &variable_table[*subscription];
       
    99                 char* next_cursor;
       
   100                 /* get variable size*/
       
   101                 USINT size = __get_type_enum_size(my_var->type);
       
   102                 /* compute next cursor positon*/
       
   103                 next_cursor = buffer_cursor + size;
       
   104                 /* if buffer not full */
       
   105                 if(next_cursor <= debug_buffer + BUFFER_SIZE)
       
   106                 {
       
   107                     /* copy data to the buffer */
       
   108                     memcpy(buffer_cursor, my_var->ptrvalue, size);
       
   109                     /* increment cursor according size*/
       
   110                     buffer_cursor = next_cursor;
       
   111                 }else{
       
   112                     /*TODO : signal overflow*/
       
   113                 }
       
   114             }
       
   115     
       
   116             /* Reset buffer cursor again (for IterDebugData)*/
       
   117             buffer_cursor = debug_buffer;
       
   118             subscription_cursor = subscription_table;
       
   119             
   132             
   120             /* Leave debug section,
   133             /* Leave debug section,
   121              * Trigger asynchronous transmission 
   134              * Trigger asynchronous transmission 
   122              * (returns immediately) */
   135              * (returns immediately) */
   123             InitiateDebugTransfer(); /* size */
   136             InitiateDebugTransfer(); /* size */
   124         }
   137         }
   125         LeaveDebugSection();
   138         LeaveDebugSection();
   126     }
   139     }
   127 }
   140 }
   128 
   141 
       
   142 #define __RegisterDebugVariable_case_t(TYPENAME) \
       
   143         case TYPENAME##_ENUM :\
       
   144             ((__IEC_##TYPENAME##_t *)varp)->flags |= __IEC_DEBUG_FLAG;
       
   145 #define __RegisterDebugVariable_case_p(TYPENAME)\
       
   146         case TYPENAME##_P_ENUM :\
       
   147             ((__IEC_##TYPENAME##_p *)varp)->flags |= __IEC_DEBUG_FLAG;
   129 void RegisterDebugVariable(int idx)
   148 void RegisterDebugVariable(int idx)
   130 {
   149 {
   131     /*If subscription table not full */
   150     void *varp;
   132     if(latest_subscription - subscription_table < MAX_SUBSCRIBTION)
   151     switch(__find_variable(idx, varp)){
   133     {
   152         ANY(__RegisterDebugVariable_case_t)
   134         *(latest_subscription++) = idx;
   153         ANY(__RegisterDebugVariable_case_p)
   135         /* TODO pre-calc buffer size and signal overflow*/
   154     }
   136     }else{
   155 }
   137         /*TODO : signal subscription overflow*/
   156 
       
   157 #define __ResetDebugVariablesIterator_case_t(TYPENAME) \
       
   158         case TYPENAME##_ENUM :\
       
   159             ((__IEC_##TYPENAME##_t *)varp)->flags &= ~__IEC_DEBUG_FLAG;
       
   160 
       
   161 #define __ResetDebugVariablesIterator_case_p(TYPENAME)\
       
   162         case TYPENAME##_P_ENUM :\
       
   163             ((__IEC_##TYPENAME##_p *)varp)->flags &= ~__IEC_DEBUG_FLAG;\
       
   164 
       
   165 void ResetDebugVariablesIterator(void* varp, __IEC_types_enum vartype)
       
   166 {
       
   167     /* force debug flag to 0*/
       
   168     switch(vartype){
       
   169         ANY(__ResetDebugVariablesIterator_case_t)
       
   170         ANY(__ResetDebugVariablesIterator_case_p)
   138     }
   171     }
   139 }
   172 }
   140 
   173 
   141 void ResetDebugVariables(void)
   174 void ResetDebugVariables(void)
   142 {
   175 {
   143     latest_subscription = subscription_table;
   176     __for_each_variable_do(ResetDebugVariablesIterator);
   144 }
   177 }
   145 
   178 
   146 void FreeDebugData(void)
   179 void FreeDebugData(void)
   147 {
   180 {
   148     /* atomically mark buffer as free */
   181     /* atomically mark buffer as free */
   151         &buffer_state,
   184         &buffer_state,
   152         BUFFER_BUSY,
   185         BUFFER_BUSY,
   153         BUFFER_FREE);
   186         BUFFER_FREE);
   154 }
   187 }
   155 
   188 
   156 void* IterDebugData(int* idx, const char **type_name)
   189 /* Wait until debug data ready and return pointer to it */
   157 {
   190 int GetDebugData(unsigned long *tick, unsigned long *size, void **buffer){
   158 	struct_plcvar* my_var;
   191     int res = WaitDebugData(tick);
   159 	USINT size;
   192     *size = buffer_cursor - debug_buffer;
   160     if(subscription_cursor < latest_subscription){
   193     *buffer = NULL;
   161         char* old_cursor = buffer_cursor;
   194     return res;
   162         *idx = *subscription_cursor;
       
   163         my_var = &variable_table[*(subscription_cursor++)];
       
   164         *type_name = __get_type_enum_name(my_var->type);
       
   165         /* get variable size*/
       
   166         size = __get_type_enum_size(my_var->type);
       
   167         /* compute next cursor position*/
       
   168         buffer_cursor = buffer_cursor + size;
       
   169         if(old_cursor < debug_buffer + BUFFER_SIZE)
       
   170         {
       
   171             return old_cursor;
       
   172         }else{
       
   173             //printf("%%d > %%d\n", old_cursor - debug_buffer, BUFFER_SIZE);
       
   174             return NULL;
       
   175         } 
       
   176     }
       
   177     *idx = -1;
       
   178     *type_name = NULL;
       
   179     return NULL;
       
   180 }
   195 }
   181 
   196