1 /*
2 * Percepio Trace Recorder for Tracealyzer v4.6.6
3 * Copyright 2021 Percepio AB
4 * www.percepio.com
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * The implementation for events.
9 */
10
11 #include <trcRecorder.h>
12
13 #if (TRC_USE_TRACEALYZER_RECORDER == 1)
14
15 #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
16
17 #define VERIFY_EVENT_SIZE(i) \
18 if ((i) > (TRC_MAX_BLOB_SIZE)) \
19 { \
20 xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED, (TraceUnsignedBaseType_t)((i) - (TRC_MAX_BLOB_SIZE))); \
21 (i) = TRC_MAX_BLOB_SIZE; \
22 }
23
24 TraceEventDataTable_t *pxTraceEventDataTable;
25
26 int32_t DUMMY_iTraceBytesCommitted;
27
xTraceEventInitialize(TraceEventDataBuffer_t * pxBuffer)28 traceResult xTraceEventInitialize(TraceEventDataBuffer_t* pxBuffer)
29 {
30 TraceCoreEventData_t* pxCoreEventData;
31 uint32_t i, j;
32
33 TRC_ASSERT_EQUAL_SIZE(TraceEventDataBuffer_t, TraceEventDataTable_t);
34
35 /* This should never fail */
36 TRC_ASSERT(pxBuffer != 0);
37
38 pxTraceEventDataTable = (TraceEventDataTable_t*)pxBuffer;
39
40 for (i = 0; i < TRC_CFG_CORE_COUNT; i++)
41 {
42 pxCoreEventData = &pxTraceEventDataTable->coreEventData[i];
43
44 pxCoreEventData->eventCounter = 0;
45
46 for (j = 0; j < (TRC_CFG_MAX_ISR_NESTING) + 1; j++)
47 {
48 RESET_EVENT_DATA(&pxCoreEventData->eventData[j]);
49 }
50 }
51
52 xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT);
53
54 return TRC_SUCCESS;
55 }
56
xTraceEventBeginRawOffline(uint32_t uiSize,TraceEventHandle_t * pxEventHandle)57 traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle)
58 {
59 TraceEventData_t* pxEventData;
60 TraceCoreEventData_t* pxCoreEventData;
61 int32_t ISR_nesting;
62
63 TRACE_ALLOC_CRITICAL_SECTION();
64
65 /* We need to check this */
66 if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT))
67 {
68 return TRC_FAIL;
69 }
70
71 /* This should never fail */
72 TRC_ASSERT(pxEventHandle != 0);
73
74 TRACE_ENTER_CRITICAL_SECTION();
75
76 pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
77
78 /* We backup the local variable to the CORE specific variable */
79 pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME;
80
81 xTraceISRGetCurrentNesting(&ISR_nesting);
82
83 /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */
84 pxEventData = &pxCoreEventData->eventData[ISR_nesting + 1];
85
86 /* This should never fail */
87 TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
88
89 VERIFY_EVENT_SIZE(uiSize);
90
91 pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t); /* 4-byte align */
92
93 pxEventData->offset = 0;
94
95 /* This can fail and we should handle it */
96 if (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) == TRC_FAIL)
97 {
98 TRACE_EXIT_CRITICAL_SECTION();
99 return TRC_FAIL;
100 }
101
102 *pxEventHandle = (TraceEventHandle_t)pxEventData;
103
104 return TRC_SUCCESS;
105 }
106
xTraceEventBeginRawOfflineBlocking(uint32_t uiSize,TraceEventHandle_t * pxEventHandle)107 traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle)
108 {
109 TraceEventData_t* pxEventData;
110 TraceCoreEventData_t* pxCoreEventData;
111 int32_t ISR_nesting;
112 uint32_t uiAttempts = 0;
113
114 TRACE_ALLOC_CRITICAL_SECTION();
115
116 /* We need to check this */
117 if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT))
118 {
119 return TRC_FAIL;
120 }
121
122 /* This should never fail */
123 TRC_ASSERT(pxEventHandle != 0);
124
125 TRACE_ENTER_CRITICAL_SECTION();
126
127 pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
128
129 /* We backup the local variable to the CORE specific variable */
130 pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME;
131
132 xTraceGetCurrentISRNesting(&ISR_nesting);
133
134 /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */
135 pxEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventData[ISR_nesting + 1];
136
137 /* This should never fail */
138 TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
139
140 VERIFY_EVENT_SIZE(uiSize);
141
142 pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t); /* 4-byte align */
143
144 pxEventData->offset = 0;
145
146 /* This can fail and we should handle it */
147 while (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) != TRC_SUCCESS)
148 {
149 uiAttempts++;
150 }
151
152 *pxEventHandle = (TraceEventHandle_t)pxEventData;
153
154 return TRC_SUCCESS;
155 }
156
xTraceEventEndOffline(TraceEventHandle_t xEventHandle)157 traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle)
158 {
159 TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
160 TraceCoreEventData_t* pxCoreEventData;
161 int32_t iBytesCommitted;
162
163 TRACE_ALLOC_CRITICAL_SECTION()
164
165 pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
166
167 /* We restore the CORE specific variable to the local variable before any EXIT */
168 TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME;
169
170 /* This should never fail */
171 TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
172
173 /* This should never fail */
174 TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
175
176 /* This should never fail */
177 TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
178
179 xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted);
180
181 /* We need to use iBytesCommitted for the above call but do not use the value,
182 * remove potential warnings */
183 (void)iBytesCommitted;
184
185 RESET_EVENT_DATA(pxEventData);
186
187 TRACE_EXIT_CRITICAL_SECTION();
188
189 return TRC_SUCCESS;
190 }
191
xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle)192 traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle)
193 {
194 TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle;
195 TraceCoreEventData_t* pxCoreEventData;
196 int32_t iBytesCommitted;
197
198 TRACE_ALLOC_CRITICAL_SECTION()
199
200 pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()];
201
202 /* We restore the CORE specific variable to the local variable before any EXIT */
203 TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME;
204
205 /* This should never fail */
206 TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
207
208 /* This should never fail */
209 TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
210
211 /* This should never fail */
212 TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; );
213
214 while (pxEventData->size > 0)
215 {
216 iBytesCommitted = 0;
217 xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted);
218
219 pxEventData->size -= iBytesCommitted;
220 pxEventData->pvBlob = ((uint8_t*)pxEventData->pvBlob) + iBytesCommitted;
221 }
222
223 RESET_EVENT_DATA(pxEventData);
224
225 TRACE_EXIT_CRITICAL_SECTION();
226
227 return TRC_SUCCESS;
228 }
229
xTraceEventAddData(TraceEventHandle_t xEventHandle,void * pvData,uint32_t uiSize)230 traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, void* pvData, uint32_t uiSize)
231 {
232 uint32_t i;
233
234 /* This should never fail */
235 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
236
237 /* This should never fail */
238 TRC_ASSERT(xEventHandle != 0);
239
240 /* This should never fail */
241 TRC_ASSERT(pvData != 0);
242
243 /* This should never fail */
244 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + uiSize <= ((TraceEventData_t*)xEventHandle)->size);
245
246 for (i = 0; i < uiSize; i++)
247 {
248 TRC_EVENT_ADD_8(xEventHandle, ((uint8_t*)pvData)[i]);
249 }
250
251 return TRC_SUCCESS;
252 }
253
254 #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
255
xTraceEventGetSize(void * pvAddress,uint32_t * puiSize)256 traceResult xTraceEventGetSize(void *pvAddress, uint32_t* puiSize)
257 {
258 /* This should never fail */
259 TRC_ASSERT(pvAddress != 0);
260
261 /* This should never fail */
262 TRC_ASSERT(puiSize != 0);
263
264 /* This should never fail */
265 TRC_ASSERT((sizeof(TraceBaseEvent_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceBaseEvent_t*)pvAddress)->EventID)) * sizeof(uint32_t)) <= TRC_MAX_BLOB_SIZE);
266
267 return TRC_EVENT_GET_SIZE(pvAddress, puiSize);
268 }
269
xTraceEventGetRawData(TraceEventHandle_t xEventHandle,uint32_t uiOffset,uint32_t uiSize,void ** ppvData)270 traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData)
271 {
272 /* This should never fail */
273 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
274
275 /* This should never fail */
276 TRC_ASSERT(xEventHandle != 0);
277
278 /* This should never fail */
279 TRC_ASSERT(ppvData != 0);
280
281 /* This should never fail */
282 TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size);
283
284 return TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData);
285 }
286
xTraceEventGetPayload(TraceEventHandle_t xEventHandle,uint32_t uiOffset,uint32_t uiSize,void ** ppvData)287 traceResult xTraceEventGetPayload(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData)
288 {
289 /* This should never fail */
290 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
291
292 /* This should never fail */
293 TRC_ASSERT(xEventHandle != 0);
294
295 /* This should never fail */
296 TRC_ASSERT(ppvData != 0);
297
298 /* This should never fail */
299 TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size);
300
301 return TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData);
302 }
303
xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle,uint32_t * puiValue)304 traceResult xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle, uint32_t* puiValue)
305 {
306 /* This should never fail */
307 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
308
309 /* This should never fail */
310 TRC_ASSERT(xEventHandle != 0);
311
312 /* This should never fail */
313 TRC_ASSERT(puiValue != 0);
314
315 /* This should never fail */
316 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0);
317
318 return TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue);
319 }
320
xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle,uint32_t * puiValue)321 traceResult xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle, uint32_t* puiValue)
322 {
323 /* This should never fail */
324 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
325
326 /* This should never fail */
327 TRC_ASSERT(xEventHandle != 0);
328
329 /* This should never fail */
330 TRC_ASSERT(puiValue != 0);
331
332 /* This should never fail */
333 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0);
334
335 return TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue);
336 }
337
xTraceEventPayloadSize(TraceEventHandle_t xEventHandle,uint32_t * puiValue)338 traceResult xTraceEventPayloadSize(TraceEventHandle_t xEventHandle, uint32_t* puiValue)
339 {
340 /* This should never fail */
341 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
342
343 /* This should never fail */
344 TRC_ASSERT(xEventHandle != 0);
345
346 /* This should never fail */
347 TRC_ASSERT(puiValue != 0);
348
349 /* This should never fail */
350 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0);
351
352 return TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue);
353 }
354
xTraceEventAddPointer(TraceEventHandle_t xEventHandle,void * pvAddress)355 traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void* pvAddress)
356 {
357 /* This should never fail */
358 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
359
360 /* This should never fail */
361 TRC_ASSERT(xEventHandle != 0);
362
363 /* This should never fail */
364 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(void*) <= ((TraceEventData_t*)xEventHandle)->size);
365
366 /* Make sure we are writing at void* aligned offset */
367 /* This should never fail */
368 TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(void*) - 1)) == 0);
369
370 return TRC_EVENT_ADD_POINTER(xEventHandle, pvAddress);
371 }
372
xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle,TraceUnsignedBaseType_t uxValue)373 traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue)
374 {
375 /* This should never fail */
376 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
377
378 /* This should never fail */
379 TRC_ASSERT(xEventHandle != 0);
380
381 /* This should never fail */
382 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(TraceUnsignedBaseType_t) <= ((TraceEventData_t*)xEventHandle)->size);
383
384 /* Make sure we are writing at TraceUnsignedBaseType_t aligned offset */
385 /* This should never fail */
386 TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(TraceUnsignedBaseType_t) - 1)) == 0);
387
388 return TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, uxValue);
389 }
390
xTraceEventAdd32(TraceEventHandle_t xEventHandle,uint32_t value)391 traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value)
392 {
393 /* This should never fail */
394 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
395
396 /* This should never fail */
397 TRC_ASSERT(xEventHandle != 0);
398
399 /* This should never fail */
400 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint32_t) <= ((TraceEventData_t*)xEventHandle)->size);
401
402 /* Make sure we are writing at 32-bit aligned offset */
403 /* This should never fail */
404 TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 3) == 0);
405
406 return TRC_EVENT_ADD_32(xEventHandle, value);
407 }
408
xTraceEventAdd16(TraceEventHandle_t xEventHandle,uint16_t value)409 traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value)
410 {
411 /* This should never fail */
412 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
413
414 /* This should never fail */
415 TRC_ASSERT(xEventHandle != 0);
416
417 /* This should never fail */
418 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint16_t) <= ((TraceEventData_t*)xEventHandle)->size);
419
420 /* Make sure we are writing at 16-bit aligned offset */
421 /* This should never fail */
422 TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 1) == 0);
423
424 return TRC_EVENT_ADD_16(xEventHandle, value);
425 }
426
xTraceEventAdd8(TraceEventHandle_t xEventHandle,uint8_t value)427 traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value)
428 {
429 /* This should never fail */
430 TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT));
431
432 /* This should never fail */
433 TRC_ASSERT(xEventHandle != 0);
434
435 /* This should never fail */
436 TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint8_t) <= ((TraceEventData_t*)xEventHandle)->size);
437
438 return TRC_EVENT_ADD_8(xEventHandle, value);
439 }
440
441 #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
442
443 #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
444
445 #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
446