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