mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-10-14 00:37:44 -04:00
* 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.
432 lines
16 KiB
C
432 lines
16 KiB
C
/*
|
|
* Percepio Trace Recorder for Tracealyzer v4.6.0
|
|
* Copyright 2021 Percepio AB
|
|
* www.percepio.com
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* The implementation for events.
|
|
*/
|
|
|
|
#include <trcRecorder.h>
|
|
|
|
#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;
|
|
|
|
TRACE_ALLOC_CRITICAL_SECTION();
|
|
|
|
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;
|
|
int32_t ISR_nesting;
|
|
|
|
/* 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();
|
|
|
|
xTraceISRGetCurrentNesting( &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 */
|
|
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;
|
|
int32_t ISR_nesting;
|
|
uint32_t uiAttempts = 0;
|
|
|
|
/* 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();
|
|
|
|
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 )
|
|
{
|
|
int32_t iBytesCommitted;
|
|
|
|
/* 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 )->pvBlob != 0 );
|
|
|
|
xTraceStreamPortCommit( ( ( TraceEventData_t * ) xEventHandle )->pvBlob, ( ( TraceEventData_t * ) xEventHandle )->size, &iBytesCommitted );
|
|
|
|
RESET_EVENT_DATA( ( TraceEventData_t * ) xEventHandle );
|
|
|
|
TRACE_EXIT_CRITICAL_SECTION();
|
|
|
|
return TRC_SUCCESS;
|
|
}
|
|
|
|
traceResult xTraceEventEndOfflineBlocking( TraceEventHandle_t xEventHandle )
|
|
{
|
|
TraceEventData_t * pxEventData = ( TraceEventData_t * ) xEventHandle;
|
|
int32_t iBytesCommitted;
|
|
|
|
/* This should never fail */
|
|
TRC_ASSERT( xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_EVENT ) );
|
|
|
|
/* This should never fail */
|
|
TRC_ASSERT( pxEventData != 0 );
|
|
|
|
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) */
|