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 :\ |
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 :\ |