Files
Erik Tamlin c568ba8c44 Percepio Trace Recorder v4.6.0 (#789)
* * Percepio Trace Recorder v4.6.0

* Add space between inclusion of header and comment

* Fix broken posix build - part 1

* Add percepio timer implementation

* Remove delted trace recorder header file

* Fix Networking demo  build

* Fix CLI demo

* Fix visual studio version number

* Fix core header check

* Fix more core checks

* Fix last of core checks

Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
Co-authored-by: Alfred Gedeon <alfred2g@hotmail.com>
2022-11-03 13:58:38 -07:00

430 lines
11 KiB
C

/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The implementation of the entry table.
*/
#include <trcRecorder.h>
#if (TRC_USE_TRACEALYZER_RECORDER == 1)
#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
#define VALIDATE_ENTRY_HANDLE(xEntryHandle) ((((TraceUnsignedBaseType_t)(xEntryHandle) >= (TraceUnsignedBaseType_t)pxEntryTable) && ((TraceUnsignedBaseType_t)(xEntryHandle) < ((TraceUnsignedBaseType_t)pxEntryTable + sizeof(TraceEntryTable_t)))))
#define GIVE_ENTRY_INDEX(xIndex) xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount] = (xIndex); xIndexTable.uiFreeIndexCount++
#define GET_FREE_INDEX_COUNT() xIndexTable.uiFreeIndexCount
#define CALCULATE_ENTRY_INDEX(xEntryHandle) (TraceEntryIndex_t)(((TraceUnsignedBaseType_t)((TraceUnsignedBaseType_t)(xEntryHandle) - (TraceUnsignedBaseType_t)pxEntryTable) / sizeof(TraceEntry_t)))
#if (TRC_ENTRY_TABLE_SLOTS > 256)
typedef uint16_t TraceEntryIndex_t;
#else
typedef uint8_t TraceEntryIndex_t;
#endif /* (TRC_CFG_ENTRY_TABLE_SLOTS > 256) */
typedef struct EntryIndexTable
{
TraceEntryIndex_t axFreeIndexes[TRC_ENTRY_TABLE_SLOTS];
uint32_t uiFreeIndexCount;
} TraceEntryIndexTable_t;
typedef struct TraceEntryTable
{
uint32_t uiSlots;
uint32_t uiEntrySymbolLength;
uint32_t uiEntryStateCount;
TraceEntry_t axEntries[TRC_ENTRY_TABLE_SLOTS];
} TraceEntryTable_t;
/* Private function definitions */
traceResult prvEntryIndexInitialize(TraceEntryIndexTable_t *pxIndexTable);
traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex);
/* Variables */
static TraceEntryTable_t *pxEntryTable;
static TraceEntryIndexTable_t xIndexTable;
traceResult xTraceEntryTableInitialize(TraceEntryTableBuffer_t *pxBuffer)
{
uint32_t i, j;
TRC_ASSERT_EQUAL_SIZE(TraceEntryTableBuffer_t, TraceEntryTable_t);
/* This should never fail */
TRC_ASSERT(pxBuffer != 0);
/* This should never fail */
TRC_ASSERT((TRC_ENTRY_TABLE_SLOTS) != 0);
pxEntryTable = (TraceEntryTable_t*)pxBuffer;
pxEntryTable->uiSlots = TRC_ENTRY_TABLE_SLOTS;
pxEntryTable->uiEntrySymbolLength = TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE;
pxEntryTable->uiEntryStateCount = TRC_ENTRY_TABLE_STATE_COUNT;
for (i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++)
{
pxEntryTable->axEntries[i].pvAddress = 0;
for (j = 0; j < TRC_ENTRY_TABLE_STATE_COUNT; j++)
{
pxEntryTable->axEntries[i].xStates[j] = 0;
}
pxEntryTable->axEntries[i].szSymbol[0] = 0;
}
prvEntryIndexInitialize(&xIndexTable);
xTraceSetComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY);
return TRC_SUCCESS;
}
traceResult xTraceEntryCreate(TraceEntryHandle_t *pxEntryHandle)
{
uint32_t i;
TraceEntryIndex_t xIndex;
TraceEntry_t *pxEntry;
TRACE_ALLOC_CRITICAL_SECTION();
/* We always check this */
if (!xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY))
{
return TRC_FAIL;
}
/* This should never fail */
TRC_ASSERT(pxEntryHandle != 0);
TRACE_ENTER_CRITICAL_SECTION();
if (prvEntryIndexTake(&xIndex) != TRC_SUCCESS)
{
xTraceDiagnosticsIncrease(TRC_DIAGNOSTICS_ENTRY_SLOTS_NO_ROOM);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
pxEntry = &pxEntryTable->axEntries[xIndex];
pxEntry->pvAddress = (void*)pxEntry; /* We set a temporary address */
for (i = 0; i < TRC_ENTRY_TABLE_STATE_COUNT; i++)
{
pxEntry->xStates[i] = 0;
}
pxEntry->uiOptions = 0;
pxEntry->szSymbol[0] = 0;
*pxEntryHandle = (TraceEntryHandle_t)pxEntry;
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceEntryDelete(TraceEntryHandle_t xEntryHandle)
{
TraceEntryIndex_t xIndex;
TRACE_ALLOC_CRITICAL_SECTION();
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
/* Calculate the index based on the entry address */
/* Does not need to be locked. */
/* This should never fail */
xIndex = CALCULATE_ENTRY_INDEX(xEntryHandle);
TRC_ASSERT(xIndex < TRC_ENTRY_TABLE_SLOTS);
TRACE_ENTER_CRITICAL_SECTION();
if (((TraceEntry_t*)xEntryHandle)->pvAddress == 0)
{
/* Someone else has deleted this already? */
TRACE_EXIT_CRITICAL_SECTION();
return TRC_FAIL;
}
/* A valid address, so we assume it is OK. */
/* For good measure, we clear the address field */
((TraceEntry_t*)xEntryHandle)->pvAddress = 0;
/* Give back the index */
GIVE_ENTRY_INDEX(xIndex);
TRACE_EXIT_CRITICAL_SECTION();
return TRC_SUCCESS;
}
traceResult xTraceEntryFind(void* pvAddress, TraceEntryHandle_t* pxEntryHandle)
{
uint32_t i;
TraceEntry_t* pxEntry;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(pxEntryHandle != 0);
/* This should never fail */
TRC_ASSERT(pvAddress != 0);
for (i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++)
{
pxEntry = (TraceEntry_t*)(((uint32_t)pxEntryTable->axEntries) + (i * sizeof(TraceEntry_t)));
if (pxEntry->pvAddress == pvAddress)
{
*pxEntryHandle = (TraceEntryHandle_t)pxEntry;
return TRC_SUCCESS;
}
}
return TRC_FAIL;
}
traceResult xTraceEntrySetSymbol(TraceEntryHandle_t xEntryHandle, const char* szSymbol)
{
uint32_t i;
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
if (szSymbol == 0)
{
szSymbol = "";
}
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
for (i = 0; i < (TRC_ENTRY_TABLE_SYMBOL_LENGTH); i++)
{
((TraceEntry_t*)xEntryHandle)->szSymbol[i] = szSymbol[i]; /* We do this first to ensure we also get the 0 termination, if there is one */
if (szSymbol[i] == 0)
{
break;
}
}
/* Check the length of "name", if longer than TRC_ENTRY_TABLE_SYMBOL_LENGTH */
while ((szSymbol[i] != 0) && i < 128)
{
i++;
}
/* Remember the longest symbol name */
xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH, i);
return TRC_SUCCESS;
}
traceResult xTraceEntryGetCount(uint32_t* puiCount)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(puiCount != 0);
*puiCount = TRC_ENTRY_TABLE_SLOTS - GET_FREE_INDEX_COUNT();
return TRC_SUCCESS;
}
traceResult xTraceEntryGetAtIndex(uint32_t index, TraceEntryHandle_t* pxEntryHandle)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(index < TRC_ENTRY_TABLE_SLOTS);
/* This should never fail */
TRC_ASSERT(pxEntryHandle != 0);
*pxEntryHandle = (TraceEntryHandle_t)((uint32_t)(pxEntryTable->axEntries) + (index * sizeof(TraceEntry_t)));
return TRC_SUCCESS;
}
#if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
traceResult xTraceEntryCreateWithAddress(void* pvAddress, TraceEntryHandle_t* pxEntryHandle)
{
/* This should never fail */
TRC_ASSERT(pvAddress != 0);
return TRC_ENTRY_CREATE_WITH_ADDRESS(pvAddress, pxEntryHandle);
}
traceResult xTraceEntrySetState(TraceEntryHandle_t xEntryHandle, uint32_t uiStateIndex, TraceUnsignedBaseType_t uxState)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(uiStateIndex < (TRC_ENTRY_TABLE_STATE_COUNT));
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_SET_STATE(xEntryHandle, uiStateIndex, uxState);
}
traceResult xTraceEntrySetOptions(TraceEntryHandle_t xEntryHandle, uint32_t uiMask)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask);
}
traceResult xTraceEntryClearOptions(TraceEntryHandle_t xEntryHandle, uint32_t uiMask)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask);
}
traceResult xTraceEntryGetAddress(TraceEntryHandle_t xEntryHandle, void **ppvAddress)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(ppvAddress != 0);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress);
}
traceResult xTraceEntryGetSymbol(TraceEntryHandle_t xEntryHandle, const char** pszSymbol)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(pszSymbol != 0);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol);
}
traceResult xTraceEntryGetState(TraceEntryHandle_t xEntryHandle, uint32_t uiStateIndex, TraceUnsignedBaseType_t *puxState)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(puxState != 0);
/* This should never fail */
TRC_ASSERT(uiStateIndex < TRC_ENTRY_TABLE_STATE_COUNT);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_GET_STATE(xEntryHandle, uiStateIndex, puxState);
}
traceResult xTraceEntryGetOptions(TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions)
{
/* This should never fail */
TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
/* This should never fail */
TRC_ASSERT(puiOptions != 0);
/* Does not need to be locked. */
/* This should never fail */
TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle));
return TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions);
}
#endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
/* PRIVATE FUNCTIONS */
traceResult prvEntryIndexInitialize(TraceEntryIndexTable_t* pxIndexTable)
{
uint32_t i;
for (i = 0; i < TRC_ENTRY_TABLE_SLOTS; i++)
{
pxIndexTable->axFreeIndexes[i] = (TraceEntryIndex_t)i;
}
xIndexTable.uiFreeIndexCount = TRC_ENTRY_TABLE_SLOTS;
return TRC_SUCCESS;
}
traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex)
{
/* Critical Section must be active! */
TraceEntryIndex_t xIndex;
if (xIndexTable.uiFreeIndexCount == 0)
{
return TRC_FAIL;
}
/* Always take the first item */
xIndex = xIndexTable.axFreeIndexes[0];
xIndexTable.uiFreeIndexCount--;
/* Move the last item to the first slot, to avoid holes */
xIndexTable.axFreeIndexes[0] = xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount];
#if (TRC_ENTRY_TABLE_SLOTS > 256)
xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount] = UINT16_MAX;
#else
xIndexTable.axFreeIndexes[xIndexTable.uiFreeIndexCount] = UINT8_MAX;
#endif
*pxIndex = xIndex;
return TRC_SUCCESS;
}
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */