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 /** ThreadX Component */
17 /** */
18 /** Trace */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define TX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "tx_api.h"
29 #include "tx_trace.h"
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _tx_trace_object_register PORTABLE C */
37 /* 6.1.12 */
38 /* AUTHOR */
39 /* */
40 /* William E. Lamie, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function registers a ThreadX system object in the trace */
45 /* registry area. This provides a mapping between the object pointers */
46 /* stored in each trace event to the actual ThreadX objects. */
47 /* */
48 /* INPUT */
49 /* */
50 /* object_type Type of system object */
51 /* object_ptr Address of system object */
52 /* object_name Name of system object */
53 /* parameter_1 Supplemental parameter 1 */
54 /* parameter_2 Supplemental parameter 2 */
55 /* */
56 /* OUTPUT */
57 /* */
58 /* None */
59 /* */
60 /* CALLS */
61 /* */
62 /* None */
63 /* */
64 /* CALLED BY */
65 /* */
66 /* Application Code */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 William E. Lamie Initial Version 6.0 */
73 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* 07-29-2022 Scott Larson Modified comment(s), */
76 /* check for null name, */
77 /* resulting in version 6.1.12 */
78 /* */
79 /**************************************************************************/
_tx_trace_object_register(UCHAR object_type,VOID * object_ptr,CHAR * object_name,ULONG parameter_1,ULONG parameter_2)80 VOID _tx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2)
81 {
82
83 #ifdef TX_ENABLE_EVENT_TRACE
84
85 UINT i, entries;
86 UINT found, loop_break;
87 TX_THREAD *thread_ptr;
88 UCHAR *work_ptr;
89 TX_TRACE_OBJECT_ENTRY *entry_ptr;
90
91
92 /* Determine if the registry area is setup. */
93 if (_tx_trace_registry_start_ptr != TX_NULL)
94 {
95
96 /* Trace buffer is enabled, proceed. */
97
98 /* Pickup the total entries. */
99 entries = _tx_trace_total_registry_entries;
100
101 /* Determine if there are available entries in the registry. */
102 if (_tx_trace_available_registry_entries != ((ULONG) 0))
103 {
104
105 /* There are more available entries, proceed. */
106
107 /* Initialize found to the max entries... indicating no space was found. */
108 found = entries;
109 loop_break = TX_FALSE;
110
111 /* Loop to find available entry. */
112 i = _tx_trace_registry_search_start;
113 do
114 {
115
116 /* Setup the registry entry pointer. */
117 work_ptr = TX_OBJECT_TO_UCHAR_POINTER_CONVERT(_tx_trace_registry_start_ptr);
118 work_ptr = TX_UCHAR_POINTER_ADD(work_ptr, ((sizeof(TX_TRACE_OBJECT_ENTRY))*i));
119 entry_ptr = TX_UCHAR_TO_OBJECT_POINTER_CONVERT(work_ptr);
120
121 /* Determine if this is the first pass building the registry. A NULL object value indicates this part
122 of the registry has never been used. */
123 if (entry_ptr -> tx_trace_object_entry_thread_pointer == (ULONG) 0)
124 {
125
126 /* Set found to this index and break out of the loop. */
127 found = i;
128 loop_break = TX_TRUE;
129 }
130
131 /* Determine if this entry matches the object pointer... we must reuse old entries left in the
132 registry. */
133 if (entry_ptr -> tx_trace_object_entry_thread_pointer == TX_POINTER_TO_ULONG_CONVERT(object_ptr))
134 {
135
136 /* Set found to this index and break out of the loop. */
137 found = i;
138 loop_break = TX_TRUE;
139 }
140
141 /* Determine if we should break out of the loop. */
142 if (loop_break == TX_TRUE)
143 {
144
145 /* Yes, break out of the loop. */
146 break;
147 }
148
149 /* Is this entry available? */
150 if (entry_ptr -> tx_trace_object_entry_available == TX_TRUE)
151 {
152
153 /* Yes, determine if we have not already found an empty slot. */
154 if (found == entries)
155 {
156 found = i;
157 }
158 else
159 {
160
161 /* Setup a pointer to the found entry. */
162 work_ptr = TX_OBJECT_TO_UCHAR_POINTER_CONVERT(_tx_trace_registry_start_ptr);
163 work_ptr = TX_UCHAR_POINTER_ADD(work_ptr, ((sizeof(TX_TRACE_OBJECT_ENTRY))*found));
164 entry_ptr = TX_UCHAR_TO_OBJECT_POINTER_CONVERT(work_ptr);
165
166 if (entry_ptr -> tx_trace_object_entry_type != ((UCHAR) 0))
167 {
168 found = i;
169 }
170 }
171 }
172
173 /* Move to the next entry. */
174 i++;
175
176 /* Determine if we have wrapped the list. */
177 if (i >= entries)
178 {
179
180 /* Yes, wrap to the beginning of the list. */
181 i = ((ULONG) 0);
182 }
183
184 } while (i != _tx_trace_registry_search_start);
185
186 /* Now determine if an empty or reuse entry has been found. */
187 if (found < entries)
188 {
189
190 /* Decrement the number of available entries. */
191 _tx_trace_available_registry_entries--;
192
193 /* Adjust the search index to the next entry. */
194 if ((found + ((ULONG) 1)) < entries)
195 {
196
197 /* Start searching from the next index. */
198 _tx_trace_registry_search_start = found + ((ULONG) 1);
199 }
200 else
201 {
202
203 /* Reset the search to the beginning of the list. */
204 _tx_trace_registry_search_start = ((ULONG) 0);
205 }
206
207 /* Yes, an entry has been found... */
208
209 /* Build a pointer to the found entry. */
210 work_ptr = TX_OBJECT_TO_UCHAR_POINTER_CONVERT(_tx_trace_registry_start_ptr);
211 work_ptr = TX_UCHAR_POINTER_ADD(work_ptr, ((sizeof(TX_TRACE_OBJECT_ENTRY))*found));
212 entry_ptr = TX_UCHAR_TO_OBJECT_POINTER_CONVERT(work_ptr);
213
214 /* Populate the found entry! */
215 entry_ptr -> tx_trace_object_entry_available = ((UCHAR) TX_FALSE);
216 entry_ptr -> tx_trace_object_entry_type = object_type;
217 entry_ptr -> tx_trace_object_entry_thread_pointer = TX_POINTER_TO_ULONG_CONVERT(object_ptr);
218 entry_ptr -> tx_trace_object_entry_param_1 = parameter_1;
219 entry_ptr -> tx_trace_object_entry_param_2 = parameter_2;
220
221 /* Loop to copy the object name string... */
222 for (i = ((ULONG) 0); i < (((ULONG) TX_TRACE_OBJECT_REGISTRY_NAME)-((ULONG) 1)); i++)
223 {
224
225 /* Setup work pointer to the object name character. */
226 work_ptr = TX_CHAR_TO_UCHAR_POINTER_CONVERT(object_name);
227 work_ptr = TX_UCHAR_POINTER_ADD(work_ptr, i);
228
229 /* Determine if object_name (work_ptr) is null. */
230 if (work_ptr == TX_NULL)
231 {
232 break;
233 }
234
235 /* Copy a character of the name. */
236 entry_ptr -> tx_trace_object_entry_name[i] = (UCHAR) *work_ptr;
237
238 /* Determine if we are at the end. */
239 if (*work_ptr == ((UCHAR) 0))
240 {
241 break;
242 }
243 }
244
245 /* Null terminate the object string. */
246 entry_ptr -> tx_trace_object_entry_name[i] = (UCHAR) 0;
247
248 /* Determine if a thread object type is present. */
249 if (object_type == TX_TRACE_OBJECT_TYPE_THREAD)
250 {
251
252 /* Yes, a thread object is present. */
253
254 /* Setup a pointer to the thread. */
255 thread_ptr = TX_VOID_TO_THREAD_POINTER_CONVERT(object_ptr);
256
257 /* Store the thread's priority in the reserved bits. */
258 entry_ptr -> tx_trace_object_entry_reserved1 = ((UCHAR) 0x80) | ((UCHAR) (thread_ptr -> tx_thread_priority >> ((UCHAR) 8)));
259 entry_ptr -> tx_trace_object_entry_reserved2 = (UCHAR) (thread_ptr -> tx_thread_priority & ((UCHAR) 0xFF));
260 }
261 else
262 {
263
264 /* For all other objects, set the reserved bytes to 0. */
265 entry_ptr -> tx_trace_object_entry_reserved1 = ((UCHAR) 0);
266 entry_ptr -> tx_trace_object_entry_reserved2 = ((UCHAR) 0);
267 }
268 }
269 }
270 }
271 #else
272
273 TX_INTERRUPT_SAVE_AREA
274
275
276 /* Access input arguments just for the sake of lint, MISRA, etc. */
277 if (object_type != ((UCHAR) 0))
278 {
279
280 if (object_ptr != TX_NULL)
281 {
282
283 if (object_name != TX_NULL)
284 {
285
286 if (parameter_1 != ((ULONG) 0))
287 {
288
289 if (parameter_2 != ((ULONG) 0))
290 {
291
292 /* NOP code. */
293 TX_DISABLE
294 TX_RESTORE
295 }
296 }
297 }
298 }
299 }
300 #endif
301 }
302
303