1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** USBX Component */
17 /** */
18 /** Utility */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 /* Include necessary system files. */
24
25 #define UX_SOURCE_CODE
26
27 #include "ux_api.h"
28
29
30 #ifdef UX_ENABLE_DEBUG_LOG
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _ux_utility_debug_log PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Chaoqiong Xiao, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function logs a debug msg in a circular queue. The queue */
45 /* must be initialized during the init of USBX. */
46 /* */
47 /* */
48 /* INPUT */
49 /* */
50 /* debug_location C string to locate the debug, */
51 /* for example source file name. */
52 /* debug_message C string of message */
53 /* debug_code Debug code */
54 /* debug_parameter_1 First parameter */
55 /* debug_parameter_2 Second parameter */
56 /* */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* None */
61 /* */
62 /* CALLS */
63 /* */
64 /* _ux_utility_string_length_check Check C string and return */
65 /* its length if null-terminated */
66 /* _tx_time_get Return system clock time */
67 /* */
68 /* CALLED BY */
69 /* */
70 /* Application */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 05-19-2020 Chaoqiong Xiao Initial Version 6.0 */
77 /* 09-30-2020 Chaoqiong Xiao Modified comment(s), */
78 /* verified memset and memcpy */
79 /* cases, used UX prefix to */
80 /* refer to TX symbols instead */
81 /* of using them directly, */
82 /* resulting in version 6.1 */
83 /* */
84 /**************************************************************************/
_ux_utility_debug_log(UCHAR * debug_location,UCHAR * debug_message,ULONG debug_code,ULONG debug_parameter_1,ULONG debug_parameter_2)85 VOID _ux_utility_debug_log(UCHAR *debug_location, UCHAR *debug_message, ULONG debug_code,
86 ULONG debug_parameter_1, ULONG debug_parameter_2)
87 {
88
89 UINT debug_location_string_length;
90 UINT debug_message_string_length;
91 ULONG total_debug_message_length;
92 ULONG parameter_length;
93 ULONG parameter_shift;
94 UCHAR parameter_hexa;
95 ULONG local_parameter_value;
96 ULONG current_time;
97 UX_INTERRUPT_SAVE_AREA
98
99 /* Is USBX system completely initialized ? */
100 if (_ux_system -> ux_system_debug_log_size == 0)
101
102 /* Not yet. */
103 return;
104
105 /* Entering critical area. Disable interrupts. */
106 UX_DISABLE
107
108 /* Store the debug value as the last debug value recorded. */
109 _ux_system -> ux_system_debug_code = debug_code;
110
111 /* Increment the debug value code count. */
112 _ux_system -> ux_system_debug_count++;
113
114 /* Calculate the string length. */
115 debug_location_string_length = UX_DEBUG_LOG_SIZE;
116 _ux_utility_string_length_check(source, &debug_location_string_length, UX_DEBUG_LOG_SIZE);
117 debug_message_string_length = UX_DEBUG_LOG_SIZE;
118 _ux_utility_string_length_check(source, &debug_message_string_length, UX_DEBUG_LOG_SIZE);
119
120 /* Calculate the length of the entire message string. 1 fixed string, then 1 hexa
121 decimal, then 2 strings then 2 hexa decimal numbers in the format 0x00000000
122 separated by commas and . at the end, zero terminated. */
123 total_debug_message_length = debug_location_string_length + debug_message_string_length + 10 + 10 + 10 + 10 + 5;
124
125 /* Can we accommodate this debug value message at the current location ? */
126 if (total_debug_message_length >= _ux_system -> ux_system_debug_log_size)
127 return;
128 if (_ux_system -> ux_system_debug_log_head + total_debug_message_length >
129 ux_system -> ux_system_debug_log_buffer + _ux_system -> ux_system_debug_log_size)
130 {
131
132 /* The debug value log to insert goes beyond the end of the log buffer, rewind to the beginning. */
133 _ux_system -> ux_system_debug_log_head = _ux_system -> ux_system_debug_log_buffer;
134 }
135
136 /* Copy the time strings and parameters in the log buffer. */
137 _ux_utility_memory_copy(_ux_system -> ux_system_debug_log_head, "At time : ", 10); /* Use case of memcpy is verified. */
138 _ux_system -> ux_system_debug_log_head += 10;
139
140 /* Get the time value from TX. */
141 current_time = _tx_time_get();
142
143 /* Reset the value of the length.*/
144 parameter_length = 0;
145
146 /* Init the shift value. */
147 parameter_shift = 32 - 4;
148
149 /* We parse the hexa value parameter and build the hexa value one byte at a type. */
150 while(parameter_length < 8)
151 {
152
153 /* Shift the 4 bit value we are interested in. We keep the lowest nibble. */
154 local_parameter_value = (current_time >> parameter_shift) & 0x0f;
155
156 /* See if this value is from 0-9 or A to F. */
157 if (local_parameter_value <= 9)
158
159 /* We have a digit. */
160 parameter_hexa = (UCHAR) (local_parameter_value + '0');
161
162 else
163
164 /* We have 'A' to 'F' value. */
165 parameter_hexa = (UCHAR) (local_parameter_value - 10 + 'A');
166
167 /* Store the converted hexa value. */
168 *_ux_system -> ux_system_debug_log_head = parameter_hexa;
169
170 /* Next position. */
171 _ux_system -> ux_system_debug_log_head++;
172
173 /* Update length. */
174 parameter_length++;
175
176 /* Continue shifting by one nibble. */
177 parameter_shift = parameter_shift - 4;
178 }
179
180 /* Add the comma after the time. */
181 *_ux_system -> ux_system_debug_log_head = ',';
182 _ux_system -> ux_system_debug_log_head++;
183
184 /* Copy the strings and parameters in the log buffer. */
185 _ux_utility_memory_copy(_ux_system -> ux_system_debug_log_head, debug_location, debug_location_string_length); /* Use case of memcpy is verified. */
186 _ux_system -> ux_system_debug_log_head += debug_location_string_length;
187 *_ux_system -> ux_system_debug_log_head = ',';
188 _ux_system -> ux_system_debug_log_head++;
189 _ux_utility_memory_copy(_ux_system -> ux_system_debug_log_head, debug_message, debug_message_string_length); /* Use case of memcpy is verified. */
190 _ux_system -> ux_system_debug_log_head += debug_message_string_length;
191 *_ux_system -> ux_system_debug_log_head = ',';
192 _ux_system -> ux_system_debug_log_head++;
193
194 /* Create the hexa string for parameter 1. */
195 *_ux_system -> ux_system_debug_log_head = '0';
196 _ux_system -> ux_system_debug_log_head++;
197 *_ux_system -> ux_system_debug_log_head = 'x';
198 _ux_system -> ux_system_debug_log_head++;
199
200 /* Reset the value of the length.*/
201 parameter_length = 0;
202
203 /* Init the shift value. */
204 parameter_shift = 32 - 4;
205
206 /* We parse the hexa value parameter and build the hexa value one byte at a type. */
207 while(parameter_length < 8)
208 {
209
210 /* Shift the 4 bit value we are interested in. We keep the lowest nibble. */
211 local_parameter_value = (debug_parameter_1 >> parameter_shift) & 0x0f;
212
213 /* See if this value is from 0-9 or A to F. */
214 if (local_parameter_value <= 9)
215
216 /* We have a digit. */
217 parameter_hexa = (UCHAR) (local_parameter_value + '0');
218
219 else
220
221 /* We have 'A' to 'F' value. */
222 parameter_hexa = (UCHAR) (local_parameter_value - 10 + 'A');
223
224 /* Store the converted hexa value. */
225 *_ux_system -> ux_system_debug_log_head = parameter_hexa;
226
227 /* Next position. */
228 _ux_system -> ux_system_debug_log_head++;
229
230 /* Update length. */
231 parameter_length++;
232
233 /* Continue shifting by one nibble. */
234 parameter_shift = parameter_shift - 4;
235 }
236
237 /* Add the comma between the 2 hexa values. */
238 *_ux_system -> ux_system_debug_log_head = ',';
239 _ux_system -> ux_system_debug_log_head++;
240
241 /* Create the hexa string for parameter 2. */
242 *_ux_system -> ux_system_debug_log_head = '0';
243 _ux_system -> ux_system_debug_log_head++;
244 *_ux_system -> ux_system_debug_log_head = 'x';
245 _ux_system -> ux_system_debug_log_head++;
246
247 /* Reset the value of the length.*/
248 parameter_length = 0;
249
250 /* Init the shift value. */
251 parameter_shift = 32 - 4;
252
253 /* We parse the hexa value parameter and build the hexa value one byte at a type. */
254 while(parameter_length < 8)
255 {
256
257 /* Shift the 4 bit value we are interested in. We keep the lowest nibble. */
258 local_parameter_value = (debug_parameter_2 >> parameter_shift) & 0x0f;
259
260 /* See if this value is from 0-9 or A to F. */
261 if (local_parameter_value <= 9)
262
263 /* We have a digit. */
264 parameter_hexa = (UCHAR) (local_parameter_value + '0');
265
266 else
267
268 /* We have 'A' to 'F' value. */
269 parameter_hexa = (UCHAR) (local_parameter_value - 10 + 'A');
270
271 /* Store the converted hexa value. */
272 *_ux_system -> ux_system_debug_log_head = parameter_hexa;
273
274 /* Next position. */
275 _ux_system -> ux_system_debug_log_head++;
276
277 /* Update length. */
278 parameter_length++;
279
280 /* Continue shifting by one nibble. */
281 parameter_shift = parameter_shift - 4;
282 }
283
284 /* Add the termination dot at the end. */
285 *_ux_system -> ux_system_debug_log_head = '.';
286 _ux_system -> ux_system_debug_log_head++;
287
288 /* Add the CR/LF end of the string. */
289 *_ux_system -> ux_system_debug_log_head = 0x0d;
290 _ux_system -> ux_system_debug_log_head++;
291 *_ux_system -> ux_system_debug_log_head = 0x0a;
292 _ux_system -> ux_system_debug_log_head++;
293
294 /* Add the zero end of the string. */
295 *_ux_system -> ux_system_debug_log_head = 0x00;
296 _ux_system -> ux_system_debug_log_head++;
297
298 /* The log string is put into the log buffer. It can stay here until
299 a break into debugger by the developer or be passed to a callback registered
300 by the application. */
301 if (_ux_system -> ux_system_debug_callback_function != UX_NULL)
302 {
303
304 /* The callback function is defined, call it. */
305 _ux_system -> ux_system_debug_callback_function(_ux_system -> ux_system_debug_log_tail, debug_code);
306
307 /* Update the tail. */
308 _ux_system -> ux_system_debug_log_tail += total_debug_message_length;
309
310 }
311
312 /* Restore interrupts. */
313 UX_RESTORE
314
315 /* We are done here. No return codes. */
316 return;
317 }
318
319 #endif
320