FreeRTOS-Kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcEntryTable.c
Soren Ptak 3a2f6646f0
Use CI-CD-Github-Actions for spelling and formatting, add in the bot formatting action, update the CI-CD workflow files. Fix incorrect spelling and formatting on files. (#1083)
* Use new version of CI-CD Actions,  checkout@v3 instead of checkout@v2 on all jobs
* Use cSpell spell check, and use ubuntu-20.04 for formatting check
* Add in bot formatting action
* Update freertos_demo.yml and freertos_plus_demo.yml files to increase github log readability
* Add in a Qemu demo onto the workflows.
2023-09-06 12:35:37 -07:00

445 lines
15 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) */