/* * 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 #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) */