1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.9.2
3 * Copyright 2023 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for strings.
9 */
10
11 #include <trcRecorder.h>
12
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
14
15 #include <trcTypes.h>
16
17 #ifndef TRC_SEND_NAME_ONLY_ON_DELETE
18 #define TRC_SEND_NAME_ONLY_ON_DELETE 0
19 #endif
20
21 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectRegisterInternal(uint32_t uiEventCode,void * const pvObject,const char * szName,TraceUnsignedBaseType_t uxStateCount,const TraceUnsignedBaseType_t uxStates[],TraceUnsignedBaseType_t uxOptions,TraceObjectHandle_t * pxObjectHandle)22 traceResult xTraceObjectRegisterInternal(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxStateCount, const TraceUnsignedBaseType_t uxStates[], TraceUnsignedBaseType_t uxOptions, TraceObjectHandle_t* pxObjectHandle)
23 {
24 TraceEntryHandle_t xEntryHandle;
25 TraceUnsignedBaseType_t i;
26 void *pvAddress;
27
28 TRACE_ALLOC_CRITICAL_SECTION();
29
30 /* This should never fail */
31 TRC_ASSERT(pxObjectHandle != (void*)0);
32
33 /* This should never fail */
34 TRC_ASSERT(uxStateCount <= (uint32_t)(TRC_ENTRY_TABLE_STATE_COUNT));
35
36 TRACE_ENTER_CRITICAL_SECTION();
37
38 if (pvObject != (void*)0)
39 {
40 /* An address was supplied */
41 if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
42 {
43 TRACE_EXIT_CRITICAL_SECTION();
44
45 return TRC_FAIL;
46 }
47
48 pvAddress = pvObject;
49 }
50 else
51 {
52 /* No address was supplied */
53 if (xTraceEntryCreate(&xEntryHandle) == TRC_FAIL)
54 {
55 TRACE_EXIT_CRITICAL_SECTION();
56
57 return TRC_FAIL;
58 }
59
60 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress(xEntryHandle, &pvAddress) == TRC_SUCCESS);
61 }
62
63 for (i = 0u; i < uxStateCount; i++)
64 {
65 /* This should never fail */
66 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetState(xEntryHandle, (uint32_t)i, uxStates[i]) == TRC_SUCCESS);
67 }
68
69 /* This should never fail */
70 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntrySetOptions(xEntryHandle, (uint32_t)uxOptions) == TRC_SUCCESS);
71
72 *pxObjectHandle = (TraceObjectHandle_t)xEntryHandle;
73
74 TRACE_EXIT_CRITICAL_SECTION();
75
76 if ((szName != (void*)0) && (szName[0] != (char)0)) /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
77 {
78 /* Not a null or empty string */
79 /* This will set the symbol and create an event for it */
80 /* This should never fail */
81 TRC_ASSERT_ALWAYS_EVALUATE(xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName) == TRC_SUCCESS);
82 }
83
84 switch (uxStateCount)
85 {
86 case 0:
87 xTraceEventCreate1(uiEventCode, (TraceUnsignedBaseType_t)pvAddress);
88 break;
89 case 1:
90 xTraceEventCreate2(uiEventCode, (TraceUnsignedBaseType_t)pvAddress, uxStates[0]);
91 break;
92 case 2:
93 xTraceEventCreate3(uiEventCode, (TraceUnsignedBaseType_t)pvAddress, uxStates[0], uxStates[1]);
94 break;
95 case 3:
96 xTraceEventCreate4(uiEventCode, (TraceUnsignedBaseType_t)pvAddress, uxStates[0], uxStates[1], uxStates[2]);
97 break;
98 default:
99 return TRC_FAIL;
100 break;
101 }
102
103 return TRC_SUCCESS;
104 }
105
106 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectRegister(uint32_t uiEventCode,void * const pvObject,const char * szName,TraceUnsignedBaseType_t uxState,TraceObjectHandle_t * pxObjectHandle)107 traceResult xTraceObjectRegister(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxState, TraceObjectHandle_t *pxObjectHandle)
108 {
109 return xTraceObjectRegisterInternal(uiEventCode, pvObject, szName, 1u, &uxState, 0u, pxObjectHandle);
110 }
111
112 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectRegister2(uint32_t uiEventCode,void * const pvObject,const char * szName,TraceUnsignedBaseType_t uxState1,TraceUnsignedBaseType_t uxState2,TraceObjectHandle_t * pxObjectHandle)113 traceResult xTraceObjectRegister2(uint32_t uiEventCode, void* const pvObject, const char* szName, TraceUnsignedBaseType_t uxState1, TraceUnsignedBaseType_t uxState2, TraceObjectHandle_t *pxObjectHandle)
114 {
115 TraceUnsignedBaseType_t auxStates[2] = { uxState1, uxState2 };
116 return xTraceObjectRegisterInternal(uiEventCode, pvObject, szName, 2u, auxStates, 0u, pxObjectHandle);
117 }
118
xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle,uint32_t uiEventCode,TraceUnsignedBaseType_t uxState)119 traceResult xTraceObjectUnregister(TraceObjectHandle_t xObjectHandle, uint32_t uiEventCode, TraceUnsignedBaseType_t uxState)
120 {
121 void* pvObject = (void*)0;
122 const char *szName = (void*)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
123 #if (TRC_SEND_NAME_ONLY_ON_DELETE == 1)
124 uint32_t uiLength;
125 uint32_t i;
126 #endif
127
128 /* If asserts are disabled this variable will not get used, this stops warnings. */
129 (void)szName;
130
131 /* This should never fail */
132 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS);
133
134 /* This should never fail */
135 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetSymbol((TraceEntryHandle_t)xObjectHandle, &szName) == TRC_SUCCESS);
136
137 #if (TRC_SEND_NAME_ONLY_ON_DELETE == 1)
138 /* Send name event because this is a delete */
139
140 for (i = 0u; (szName[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
141
142 uiLength = i;
143
144 /* Send the name event, if possible */
145 (void)xTraceEventCreateData1(PSF_EVENT_OBJ_NAME, (TraceUnsignedBaseType_t)pvObject, (TraceUnsignedBaseType_t*)szName, uiLength + 1); /* +1 for termination */
146 #endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 1) */
147
148 /* Send the delete event, if possible */
149 (void)xTraceEventCreate2(uiEventCode, (TraceUnsignedBaseType_t)(pvObject), uxState); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 !MISRAC2012-Rule-11.6 Suppress conversion from pointer to integer check*/
150
151 return xTraceEntryDelete(xObjectHandle);
152 }
153
154 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectSetName(TraceObjectHandle_t xObjectHandle,const char * szName)155 traceResult xTraceObjectSetName(TraceObjectHandle_t xObjectHandle, const char* szName)
156 {
157 void* pvObject = (void*)0;
158 uint32_t uiLength;
159 uint32_t i;
160
161 /* If asserts are disabled this variable will not get used, this stops warnings. */
162 (void)pvObject;
163
164 if (szName == (void*)0)
165 {
166 szName = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
167 }
168
169 /* This should never fail */
170 TRC_ASSERT_ALWAYS_EVALUATE(xTraceEntryGetAddress((TraceEntryHandle_t)xObjectHandle, &pvObject) == TRC_SUCCESS);
171
172 for (i = 0u; (szName[i] != (char)0) && (i < 128u); i++) {} /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/ /*cstat !MISRAC2004-17.4_b We need to access every character in the string*/
173
174 uiLength = i;
175
176 #if (TRC_SEND_NAME_ONLY_ON_DELETE == 0)
177 /* Attempt to send name event now since we don't do it on delete events */
178 (void)xTraceEventCreateData1(PSF_EVENT_OBJ_NAME, (TraceUnsignedBaseType_t)pvObject, (TraceUnsignedBaseType_t*)szName, uiLength + 1); /* +1 for termination */
179 #endif /* (TRC_SEND_NAME_ONLY_ON_DELETE == 0) */
180
181 return xTraceEntrySetSymbol((TraceEntryHandle_t)xObjectHandle, szName, uiLength);
182 }
183
184 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode,void * pvObject,const char * szName,TraceUnsignedBaseType_t uxState)185 traceResult xTraceObjectRegisterWithoutHandle(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState)
186 {
187 TraceObjectHandle_t xObjectHandle;
188
189 return xTraceObjectRegisterInternal(uiEventCode, pvObject, szName, 1u, &uxState, 0u, &xObjectHandle);
190 }
191
192 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectRegisterWithoutHandle2(uint32_t uiEventCode,void * pvObject,const char * szName,TraceUnsignedBaseType_t uxState1,TraceUnsignedBaseType_t uxState2)193 traceResult xTraceObjectRegisterWithoutHandle2(uint32_t uiEventCode, void* pvObject, const char* szName, TraceUnsignedBaseType_t uxState1, TraceUnsignedBaseType_t uxState2)
194 {
195 TraceObjectHandle_t xObjectHandle;
196 TraceUnsignedBaseType_t auxStates[2] = { uxState1, uxState2 };
197
198 return xTraceObjectRegisterInternal(uiEventCode, pvObject, szName, 2u, auxStates, 0u, &xObjectHandle);
199 }
200
xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode,void * pvObject,TraceUnsignedBaseType_t uxState)201 traceResult xTraceObjectUnregisterWithoutHandle(uint32_t uiEventCode, void* pvObject, TraceUnsignedBaseType_t uxState)
202 {
203 TraceEntryHandle_t xEntryHandle;
204 traceResult xResult;
205
206 TRACE_ALLOC_CRITICAL_SECTION();
207
208 TRACE_ENTER_CRITICAL_SECTION();
209
210 if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
211 {
212 TRACE_EXIT_CRITICAL_SECTION();
213
214 return TRC_FAIL;
215 }
216
217 xResult = xTraceObjectUnregister((TraceObjectHandle_t)xEntryHandle, uiEventCode, uxState);
218
219 TRACE_EXIT_CRITICAL_SECTION();
220
221 return xResult;
222 }
223
224 /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
xTraceObjectSetNameWithoutHandle(void * pvObject,const char * szName)225 traceResult xTraceObjectSetNameWithoutHandle(void* pvObject, const char* szName)
226 {
227 TraceEntryHandle_t xEntryHandle;
228 traceResult xResult;
229
230 TRACE_ALLOC_CRITICAL_SECTION();
231
232 TRACE_ENTER_CRITICAL_SECTION();
233
234 if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
235 {
236 /* No previous entry found. Create one. */
237 if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
238 {
239 TRACE_EXIT_CRITICAL_SECTION();
240
241 return TRC_FAIL;
242 }
243 }
244
245 xResult = xTraceObjectSetName((TraceObjectHandle_t)xEntryHandle, szName);
246
247 TRACE_EXIT_CRITICAL_SECTION();
248
249 return xResult;
250 }
251
xTraceObjectSetSpecificStateWithoutHandle(void * pvObject,uint32_t uiIndex,TraceUnsignedBaseType_t uxState)252 traceResult xTraceObjectSetSpecificStateWithoutHandle(void* pvObject, uint32_t uiIndex, TraceUnsignedBaseType_t uxState)
253 {
254 TraceEntryHandle_t xEntryHandle;
255 traceResult xResult;
256
257 TRACE_ALLOC_CRITICAL_SECTION();
258
259 TRACE_ENTER_CRITICAL_SECTION();
260
261 if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
262 {
263 TRACE_EXIT_CRITICAL_SECTION();
264
265 return TRC_FAIL;
266 }
267
268 xResult = xTraceObjectSetSpecificState((TraceObjectHandle_t)xEntryHandle, uiIndex, uxState);
269
270 TRACE_EXIT_CRITICAL_SECTION();
271
272 return xResult;
273 }
274
xTraceObjectSetOptionsWithoutHandle(void * pvObject,uint32_t uiMask)275 traceResult xTraceObjectSetOptionsWithoutHandle(void* pvObject, uint32_t uiMask)
276 {
277 TraceEntryHandle_t xEntryHandle;
278 traceResult xResult;
279
280 TRACE_ALLOC_CRITICAL_SECTION();
281
282 TRACE_ENTER_CRITICAL_SECTION();
283
284 if (xTraceEntryFind(pvObject, &xEntryHandle) == TRC_FAIL)
285 {
286 /* No previous entry found. Create one. */
287 if (xTraceEntryCreateWithAddress(pvObject, &xEntryHandle) == TRC_FAIL)
288 {
289 TRACE_EXIT_CRITICAL_SECTION();
290
291 return TRC_FAIL;
292 }
293 }
294
295 xResult = xTraceObjectSetOptions((TraceObjectHandle_t)xEntryHandle, uiMask);
296
297 TRACE_EXIT_CRITICAL_SECTION();
298
299 return xResult;
300 }
301
302 #endif
303