| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434 |
- /*
- * Trace Recorder for Tracealyzer v4.9.2
- * Copyright 2023 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) && (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)
- #include <string.h>
- /* (EntryAddress >= FirstEntryAddress) && (EntryAddress < EntryAddressOutsideArray) */
- #define VALIDATE_ENTRY_HANDLE(xEntryHandle) (((void*)(xEntryHandle) >= (void*)&pxEntryTable->axEntries[0]) && ((void*)(xEntryHandle) < (void*)&pxEntryTable->axEntries[TRC_ENTRY_TABLE_SLOTS]))
- /*cstat !MISRAC2004-19.4 Suppress macro check*/
- #define GIVE_ENTRY_INDEX(xIndex) pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = (xIndex); pxIndexTable->uiFreeIndexCount++
- /*cstat !MISRAC2004-19.4 Suppress macro check*/
- #define GET_FREE_INDEX_COUNT() pxIndexTable->uiFreeIndexCount
- /* Index = (EntryAddress - FirstEntryAddress) / EntrySize */
- #define CALCULATE_ENTRY_INDEX(xEntryHandle) (TraceEntryIndex_t)(((TraceUnsignedBaseType_t)(xEntryHandle) - (TraceUnsignedBaseType_t)&pxEntryTable->axEntries[0]) / sizeof(TraceEntry_t))
- /* Private function definitions */
- static traceResult prvEntryIndexInitialize(void);
- static traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex);
- /* Variables */
- static TraceEntryTable_t *pxEntryTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
- static TraceEntryIndexTable_t *pxIndexTable TRC_CFG_RECORDER_DATA_ATTRIBUTE;
- traceResult xTraceEntryIndexTableInitialize(TraceEntryIndexTable_t* const pxBuffer)
- {
- /* This should never fail */
- TRC_ASSERT(pxBuffer != (void*)0);
- pxIndexTable = pxBuffer;
-
- return prvEntryIndexInitialize();
- }
- traceResult xTraceEntryTableInitialize(TraceEntryTable_t* const pxBuffer)
- {
- uint32_t i, j;
- /* This should never fail */
- TRC_ASSERT(pxBuffer != (void*)0);
- /* This should never fail */
- TRC_ASSERT((TRC_ENTRY_TABLE_SLOTS) != 0);
- pxEntryTable = pxBuffer;
- pxEntryTable->uxSlots = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_SLOTS);
- pxEntryTable->uxEntrySymbolLength = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_SLOT_SYMBOL_SIZE);
- pxEntryTable->uxEntryStateCount = (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT);
- for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
- {
- pxEntryTable->axEntries[i].pvAddress = 0;
- for (j = 0u; j < TRC_ENTRY_TABLE_STATE_COUNT; j++)
- {
- pxEntryTable->axEntries[i].xStates[j] = (TraceUnsignedBaseType_t)0;
- }
- pxEntryTable->axEntries[i].szSymbol[0] = (char)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
- }
- 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) == 0U)
- {
- return TRC_FAIL;
- }
- /* This should never fail */
- TRC_ASSERT(pxEntryHandle != (void*)0);
- TRACE_ENTER_CRITICAL_SECTION();
- if (prvEntryIndexTake(&xIndex) != TRC_SUCCESS)
- {
- (void)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 = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_STATE_COUNT); i++)
- {
- pxEntry->xStates[i] = (TraceUnsignedBaseType_t)0;
- }
- pxEntry->uiOptions = 0u;
- pxEntry->szSymbol[0] = (char)0; /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
- *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)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- /* Calculate the index based on the entry address */
- /* Does not need to be locked. */
- /* This should never fail */
- xIndex = CALCULATE_ENTRY_INDEX(xEntryHandle); /*cstat !MISRAC2004-11.3 !MISRAC2012-Rule-11.4 Suppress conversion from pointer to integer check*/ /*cstat !MISRAC2004-17.2 !MISRAC2012-Rule-18.2 !MISRAC2012-Rule-18.4 Suppress pointer comparison check*/
- TRC_ASSERT((uint32_t)xIndex < (uint32_t)(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. */
- /* We clear the address field which is used on host to see if entries are active. */
- ((TraceEntry_t*)xEntryHandle)->pvAddress = 0;
- /* Give back the index */
- GIVE_ENTRY_INDEX(xIndex);
- TRACE_EXIT_CRITICAL_SECTION();
- return TRC_SUCCESS;
- }
- traceResult xTraceEntryFind(const void* const 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 != (void*)0);
- /* This should never fail */
- TRC_ASSERT(pvAddress != (void*)0);
- for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
- {
- pxEntry = &pxEntryTable->axEntries[i];
- if (pxEntry->pvAddress == pvAddress)
- {
- *pxEntryHandle = (TraceEntryHandle_t)pxEntry;
- return TRC_SUCCESS;
- }
- }
- return TRC_FAIL;
- }
- /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
- traceResult xTraceEntrySetSymbol(const TraceEntryHandle_t xEntryHandle, const char* szSymbol, uint32_t uiLength)
- {
- /* This should never fail */
- TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
- if (szSymbol == (void*)0)
- {
- szSymbol = ""; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
- uiLength = 0u; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
- }
- /* Remember the longest symbol name */
- (void)xTraceDiagnosticsSetIfHigher(TRC_DIAGNOSTICS_ENTRY_SYMBOL_LONGEST_LENGTH, (int32_t)uiLength);
- if (uiLength >= (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH))
- {
- /* No room for null termination. Set to max. */
- uiLength = (uint32_t)(TRC_ENTRY_TABLE_SYMBOL_LENGTH); /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
- }
- else
- {
- /* Include null termination by increasing the size by 1 */
- uiLength = uiLength + 1u; /*cstat !MISRAC2012-Rule-17.8 Suppress modified function parameter check*/
- }
- /* Does not need to be locked. */
- /* This should never fail */
- TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- /* This will also copy the null termination, if possible */
- memcpy(((TraceEntry_t*)xEntryHandle)->szSymbol, szSymbol, uiLength);
- 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 != (void*)0);
- *puiCount = (uint32_t)(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 < (uint32_t)(TRC_ENTRY_TABLE_SLOTS));
- /* This should never fail */
- TRC_ASSERT(pxEntryHandle != (void*)0);
- *pxEntryHandle = (TraceEntryHandle_t)&pxEntryTable->axEntries[index];
- return TRC_SUCCESS;
- }
- #if ((TRC_CFG_USE_TRACE_ASSERT) == 1)
- traceResult xTraceEntryCreateWithAddress(void* const pvAddress, TraceEntryHandle_t* pxEntryHandle)
- {
- /* This should never fail */
- TRC_ASSERT(pvAddress != (void*)0);
- return TRC_ENTRY_CREATE_WITH_ADDRESS(pvAddress, pxEntryHandle);
- }
- traceResult xTraceEntrySetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t uxState)
- {
- /* This should never fail */
- TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
- /* This should never fail */
- TRC_ASSERT(uxStateIndex < (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT));
- /* This should never fail */
- TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- return TRC_ENTRY_SET_STATE(xEntryHandle, uxStateIndex, uxState);
- }
- traceResult xTraceEntrySetOptions(const 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)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
-
- return TRC_ENTRY_SET_OPTIONS(xEntryHandle, uiMask);
- }
- traceResult xTraceEntryClearOptions(const 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)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
-
- return TRC_ENTRY_CLEAR_OPTIONS(xEntryHandle, uiMask);
- }
- traceResult xTraceEntryGetAddress(const TraceEntryHandle_t xEntryHandle, void **ppvAddress)
- {
- /* This should never fail */
- TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
- /* This should never fail */
- TRC_ASSERT(ppvAddress != (void*)0);
- /* Does not need to be locked. */
- /* This should never fail */
- TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- return TRC_ENTRY_GET_ADDRESS(xEntryHandle, ppvAddress);
- }
- void* xTraceEntryGetAddressReturn(const TraceEntryHandle_t xEntryHandle)
- {
- /* This should never fail */
- TRC_ASSERT_CUSTOM_ON_FAIL(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY), return (void*)0);
- /* Does not need to be locked. */
- /* This should never fail */
- TRC_ASSERT_CUSTOM_ON_FAIL(VALIDATE_ENTRY_HANDLE(xEntryHandle), return (void*)0); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- return TRC_ENTRY_GET_ADDRESS_RETURN(xEntryHandle);
- }
- /*cstat !MISRAC2004-6.3 !MISRAC2012-Dir-4.6_a Suppress basic char type usage*/
- traceResult xTraceEntryGetSymbol(const TraceEntryHandle_t xEntryHandle, const char** pszSymbol)
- {
- /* This should never fail */
- TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
- /* This should never fail */
- TRC_ASSERT(pszSymbol != (void*)0);
- /* Does not need to be locked. */
- /* This should never fail */
- TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- return TRC_ENTRY_GET_SYMBOL(xEntryHandle, pszSymbol);
- }
- traceResult xTraceEntryGetState(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex, TraceUnsignedBaseType_t *puxState)
- {
- /* This should never fail */
- TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
- /* This should never fail */
- TRC_ASSERT(puxState != (void*)0);
- /* This should never fail */
- TRC_ASSERT(uxStateIndex < (TraceUnsignedBaseType_t)(TRC_ENTRY_TABLE_STATE_COUNT));
- /* Does not need to be locked. */
- /* This should never fail */
- TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- return TRC_ENTRY_GET_STATE(xEntryHandle, uxStateIndex, puxState);
- }
- /*cstat !MISRAC2012-Rule-8.13 Suppress const check for xEntryHandle*/
- TraceUnsignedBaseType_t xTraceEntryGetStateReturn(const TraceEntryHandle_t xEntryHandle, TraceUnsignedBaseType_t uxStateIndex)
- {
- return TRC_ENTRY_GET_STATE_RETURN(xEntryHandle, uxStateIndex);
- }
- traceResult xTraceEntryGetOptions(const TraceEntryHandle_t xEntryHandle, uint32_t *puiOptions)
- {
- /* This should never fail */
- TRC_ASSERT(xTraceIsComponentInitialized(TRC_RECORDER_COMPONENT_ENTRY));
- /* This should never fail */
- TRC_ASSERT(puiOptions != (void*)0);
- /* Does not need to be locked. */
- /* This should never fail */
- TRC_ASSERT(VALIDATE_ENTRY_HANDLE(xEntryHandle)); /*cstat !MISRAC2004-17.3 !MISRAC2012-Rule-18.3 Suppress pointer comparison check*/
- return TRC_ENTRY_GET_OPTIONS(xEntryHandle, puiOptions);
- }
- #endif /* ((TRC_CFG_USE_TRACE_ASSERT) == 1) */
- /* PRIVATE FUNCTIONS */
- static traceResult prvEntryIndexInitialize(void)
- {
- uint32_t i;
- for (i = 0u; i < (uint32_t)(TRC_ENTRY_TABLE_SLOTS); i++)
- {
- pxIndexTable->axFreeIndexes[i] = (TraceEntryIndex_t)i;
- }
- pxIndexTable->uiFreeIndexCount = TRC_ENTRY_TABLE_SLOTS;
- return TRC_SUCCESS;
- }
- static traceResult prvEntryIndexTake(TraceEntryIndex_t *pxIndex)
- {
- /* Critical Section must be active! */
- TraceEntryIndex_t xIndex;
- if (pxIndexTable->uiFreeIndexCount == 0u)
- {
- return TRC_FAIL;
- }
- /* Always take the first item */
- xIndex = pxIndexTable->axFreeIndexes[0];
- pxIndexTable->uiFreeIndexCount--;
- /* Move the last item to the first slot, to avoid holes */
- pxIndexTable->axFreeIndexes[0] = pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount];
- #if (TRC_ENTRY_TABLE_SLOTS > 256)
- pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = UINT16_MAX;
- #else
- pxIndexTable->axFreeIndexes[pxIndexTable->uiFreeIndexCount] = UINT8_MAX;
- #endif
- *pxIndex = xIndex;
- return TRC_SUCCESS;
- }
- #endif
|