/* * Percepio Trace Recorder for Tracealyzer v4.6.6 * Copyright 2021 Percepio AB * www.percepio.com * * SPDX-License-Identifier: Apache-2.0 * * The implementation for events. */ #include #if (TRC_USE_TRACEALYZER_RECORDER == 1) #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) #define VERIFY_EVENT_SIZE(i) \ if ((i) > (TRC_MAX_BLOB_SIZE)) \ { \ xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_BLOB_MAX_BYTES_TRUNCATED, (TraceUnsignedBaseType_t)((i) - (TRC_MAX_BLOB_SIZE))); \ (i) = TRC_MAX_BLOB_SIZE; \ } TraceEventDataTable_t *pxTraceEventDataTable; int32_t DUMMY_iTraceBytesCommitted; traceResult xTraceEventInitialize(TraceEventDataBuffer_t* pxBuffer) { TraceCoreEventData_t* pxCoreEventData; uint32_t i, j; TRC_ASSERT_EQUAL_SIZE(TraceEventDataBuffer_t, TraceEventDataTable_t); /* This should never fail */ TRC_ASSERT(pxBuffer != 0); pxTraceEventDataTable = (TraceEventDataTable_t*)pxBuffer; for (i = 0; i < TRC_CFG_CORE_COUNT; i++) { pxCoreEventData = &pxTraceEventDataTable->coreEventData[i]; pxCoreEventData->eventCounter = 0; for (j = 0; j < (TRC_CFG_MAX_ISR_NESTING) + 1; j++) { RESET_EVENT_DATA(&pxCoreEventData->eventData[j]); } } xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_EVENT); return TRC_SUCCESS; } traceResult xTraceEventBeginRawOffline(uint32_t uiSize, TraceEventHandle_t* pxEventHandle) { TraceEventData_t* pxEventData; TraceCoreEventData_t* pxCoreEventData; int32_t ISR_nesting; TRACE_ALLOC_CRITICAL_SECTION(); /* We need to check this */ if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)) { return TRC_FAIL; } /* This should never fail */ TRC_ASSERT(pxEventHandle != 0); TRACE_ENTER_CRITICAL_SECTION(); pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()]; /* We backup the local variable to the CORE specific variable */ pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME; xTraceISRGetCurrentNesting(&ISR_nesting); /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */ pxEventData = &pxCoreEventData->eventData[ISR_nesting + 1]; /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); VERIFY_EVENT_SIZE(uiSize); pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t); /* 4-byte align */ pxEventData->offset = 0; /* This can fail and we should handle it */ if (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) == TRC_FAIL) { TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; } *pxEventHandle = (TraceEventHandle_t)pxEventData; return TRC_SUCCESS; } traceResult xTraceEventBeginRawOfflineBlocking(uint32_t uiSize, TraceEventHandle_t* pxEventHandle) { TraceEventData_t* pxEventData; TraceCoreEventData_t* pxCoreEventData; int32_t ISR_nesting; uint32_t uiAttempts = 0; TRACE_ALLOC_CRITICAL_SECTION(); /* We need to check this */ if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)) { return TRC_FAIL; } /* This should never fail */ TRC_ASSERT(pxEventHandle != 0); TRACE_ENTER_CRITICAL_SECTION(); pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()]; /* We backup the local variable to the CORE specific variable */ pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME = TRACE_ALLOC_CRITICAL_SECTION_NAME; xTraceGetCurrentISRNesting(&ISR_nesting); /* We add 1 since xTraceISRGetCurrentNesting(...) returns -1 if no ISR is active */ pxEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()].eventData[ISR_nesting + 1]; /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob == 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); VERIFY_EVENT_SIZE(uiSize); pxEventData->size = ((uiSize + (sizeof(uint32_t) - 1)) / sizeof(uint32_t)) * sizeof(uint32_t); /* 4-byte align */ pxEventData->offset = 0; /* This can fail and we should handle it */ while (xTraceStreamPortAllocate(pxEventData->size, &pxEventData->pvBlob) != TRC_SUCCESS) { uiAttempts++; } *pxEventHandle = (TraceEventHandle_t)pxEventData; return TRC_SUCCESS; } traceResult xTraceEventEndOffline(TraceEventHandle_t xEventHandle) { TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle; TraceCoreEventData_t* pxCoreEventData; int32_t iBytesCommitted; TRACE_ALLOC_CRITICAL_SECTION() pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()]; /* We restore the CORE specific variable to the local variable before any EXIT */ TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME; /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted); /* We need to use iBytesCommitted for the above call but do not use the value, * remove potential warnings */ (void)iBytesCommitted; RESET_EVENT_DATA(pxEventData); TRACE_EXIT_CRITICAL_SECTION(); return TRC_SUCCESS; } traceResult xTraceEventEndOfflineBlocking(TraceEventHandle_t xEventHandle) { TraceEventData_t* pxEventData = (TraceEventData_t*)xEventHandle; TraceCoreEventData_t* pxCoreEventData; int32_t iBytesCommitted; TRACE_ALLOC_CRITICAL_SECTION() pxCoreEventData = &pxTraceEventDataTable->coreEventData[TRC_CFG_GET_CURRENT_CORE()]; /* We restore the CORE specific variable to the local variable before any EXIT */ TRACE_ALLOC_CRITICAL_SECTION_NAME = pxCoreEventData->TRACE_ALLOC_CRITICAL_SECTION_NAME; /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT), TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); /* This should never fail */ TRC_ASSERT_CUSTOM_ON_FAIL(pxEventData->pvBlob != 0, TRACE_EXIT_CRITICAL_SECTION(); return TRC_FAIL; ); while (pxEventData->size > 0) { iBytesCommitted = 0; xTraceStreamPortCommit(pxEventData->pvBlob, pxEventData->size, &iBytesCommitted); pxEventData->size -= iBytesCommitted; pxEventData->pvBlob = ((uint8_t*)pxEventData->pvBlob) + iBytesCommitted; } RESET_EVENT_DATA(pxEventData); TRACE_EXIT_CRITICAL_SECTION(); return TRC_SUCCESS; } traceResult xTraceEventAddData(TraceEventHandle_t xEventHandle, void* pvData, uint32_t uiSize) { uint32_t i; /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(pvData != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + uiSize <= ((TraceEventData_t*)xEventHandle)->size); for (i = 0; i < uiSize; i++) { TRC_EVENT_ADD_8(xEventHandle, ((uint8_t*)pvData)[i]); } return TRC_SUCCESS; } #if ((TRC_CFG_USE_TRACE_ASSERT) == 1) traceResult xTraceEventGetSize(void *pvAddress, uint32_t* puiSize) { /* This should never fail */ TRC_ASSERT(pvAddress != 0); /* This should never fail */ TRC_ASSERT(puiSize != 0); /* This should never fail */ TRC_ASSERT((sizeof(TraceBaseEvent_t) + (TRC_EVENT_GET_PARAM_COUNT(((TraceBaseEvent_t*)pvAddress)->EventID)) * sizeof(uint32_t)) <= TRC_MAX_BLOB_SIZE); return TRC_EVENT_GET_SIZE(pvAddress, puiSize); } traceResult xTraceEventGetRawData(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(ppvData != 0); /* This should never fail */ TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size); return TRC_EVENT_GET_RAW_DATA(xEventHandle, uiOffset, uiSize, ppvData); } traceResult xTraceEventGetPayload(TraceEventHandle_t xEventHandle, uint32_t uiOffset, uint32_t uiSize, void** ppvData) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(ppvData != 0); /* This should never fail */ TRC_ASSERT(uiOffset + uiSize <= ((TraceEventData_t*)xEventHandle)->size); return TRC_EVENT_GET_PAYLOAD(xEventHandle, uiOffset, uiSize, ppvData); } traceResult xTraceEventPayloadRemaining(TraceEventHandle_t xEventHandle, uint32_t* puiValue) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(puiValue != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); return TRC_EVENT_PAYLOAD_REMAINING(xEventHandle, puiValue); } traceResult xTraceEventPayloadUsed(TraceEventHandle_t xEventHandle, uint32_t* puiValue) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(puiValue != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); return TRC_EVENT_PAYLOAD_USED(xEventHandle, puiValue); } traceResult xTraceEventPayloadSize(TraceEventHandle_t xEventHandle, uint32_t* puiValue) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(puiValue != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->pvBlob != 0); return TRC_EVENT_PAYLOAD_SIZE(xEventHandle, puiValue); } traceResult xTraceEventAddPointer(TraceEventHandle_t xEventHandle, void* pvAddress) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(void*) <= ((TraceEventData_t*)xEventHandle)->size); /* Make sure we are writing at void* aligned offset */ /* This should never fail */ TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(void*) - 1)) == 0); return TRC_EVENT_ADD_POINTER(xEventHandle, pvAddress); } traceResult xTraceEventAddUnsignedBaseType(TraceEventHandle_t xEventHandle, TraceUnsignedBaseType_t uxValue) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(TraceUnsignedBaseType_t) <= ((TraceEventData_t*)xEventHandle)->size); /* Make sure we are writing at TraceUnsignedBaseType_t aligned offset */ /* This should never fail */ TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & (sizeof(TraceUnsignedBaseType_t) - 1)) == 0); return TRC_EVENT_ADD_UNSIGNED_BASE_TYPE(xEventHandle, uxValue); } traceResult xTraceEventAdd32(TraceEventHandle_t xEventHandle, uint32_t value) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint32_t) <= ((TraceEventData_t*)xEventHandle)->size); /* Make sure we are writing at 32-bit aligned offset */ /* This should never fail */ TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 3) == 0); return TRC_EVENT_ADD_32(xEventHandle, value); } traceResult xTraceEventAdd16(TraceEventHandle_t xEventHandle, uint16_t value) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint16_t) <= ((TraceEventData_t*)xEventHandle)->size); /* Make sure we are writing at 16-bit aligned offset */ /* This should never fail */ TRC_ASSERT((((TraceEventData_t*)xEventHandle)->offset & 1) == 0); return TRC_EVENT_ADD_16(xEventHandle, value); } traceResult xTraceEventAdd8(TraceEventHandle_t xEventHandle, uint8_t value) { /* This should never fail */ TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_EVENT)); /* This should never fail */ TRC_ASSERT(xEventHandle != 0); /* This should never fail */ TRC_ASSERT(((TraceEventData_t*)xEventHandle)->offset + sizeof(uint8_t) <= ((TraceEventData_t*)xEventHandle)->size); return TRC_EVENT_ADD_8(xEventHandle, value); } #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */ #endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ #endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */