FreeRTOS-Kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.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

683 lines
31 KiB
C

/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*
* The FreeRTOS specific parts of the trace recorder
*/
#include <FreeRTOS.h>
#include <trcRecorder.h>
#if ( !defined( TRC_USE_TRACEALYZER_RECORDER ) && configUSE_TRACE_FACILITY == 1 )
#error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h!
#endif
#if ( defined( TRC_USE_TRACEALYZER_RECORDER ) && TRC_USE_TRACEALYZER_RECORDER == 1 )
#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS
/* TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS is missing in trcConfig.h. */
#error "TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS must be defined in trcConfig.h."
#endif
#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS
/* TRC_CFG_INCLUDE_TIMER_EVENTS is missing in trcConfig.h. */
#error "TRC_CFG_INCLUDE_TIMER_EVENTS must be defined in trcConfig.h."
#endif
#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS
/* TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS is missing in trcConfig.h. */
#error "TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS must be defined in trcConfig.h."
#endif
#ifndef TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS
/* TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS is missing in trcConfig.h. Define this as 1 if using FreeRTOS v10 or later and like to trace stream buffer or message buffer events, otherwise 0. */
#error "TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be defined in trcConfig.h."
#endif
#if ( configUSE_TICKLESS_IDLE != 0 && ( TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR ) )
/*
* The below error message is to alert you on the following issue:
*
* The hardware port selected in trcConfig.h uses the operating system timer for the
* timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt.
*
* When using "tickless idle" mode, the recorder needs an independent time source in
* order to correctly record the durations of the idle times. Otherwise, the trace may appear
* to have a different length than in reality, and the reported CPU load is also affected.
*
* You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
* macro in your trcConfig.h file. But then the time scale may be incorrect during
* tickless idle periods.
*
* To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT
* in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros
* accordingly, using a free running counter or an independent periodic interrupt timer.
* See trcHardwarePort.h for details.
*
* For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the
* DWT cycle counter for timestamping in these cases.
*/
#ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING
#error Trace Recorder: This timestamping mode is not recommended with Tickless Idle.
#endif
#endif
#include <task.h>
#include <queue.h>
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) || ( defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) )
#if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 )
#if ( TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 )
static StackType_t stackTzCtrl[ TRC_CFG_CTRL_TASK_STACK_SIZE ];
static StaticTask_t tcbTzCtrl;
#else
#error "configSUPPORT_STATIC_ALLOCATION not supported before FreeRTOS v9"
#endif
#endif /* if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
static portTASK_FUNCTION( TzCtrl, pvParameters );
#endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) || ( defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) */
#if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X )
/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
#include <timers.h>
#endif
#if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X )
/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */
#include <event_groups.h>
#endif
#if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 )
/* If the project does not include the FreeRTOS stream buffers, TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS must be set to 0 */
#include <stream_buffer.h>
#endif
#if ( TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND != TRC_ACKNOWLEDGED ) && ( TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_0 || TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_10_3_1 ) && ( configUSE_QUEUE_SETS == 1 )
#error "When using FreeRTOS v10.3.0 or v10.3.1, please make sure that the trace point in prvNotifyQueueSetContainer() in queue.c is renamed from traceQUEUE_SEND to traceQUEUE_SET_SEND in order to tell them apart from other traceQUEUE_SEND trace points. Then set TRC_CFG_ACKNOWLEDGE_QUEUE_SET_SEND in trcConfig.h to TRC_ACKNOWLEDGED to get rid of this error."
#endif
#if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 )
traceResult xTraceKernelPortGetUnusedStack( void * pvTask,
TraceUnsignedBaseType_t * puxUnusedStack )
{
*puxUnusedStack = uxTaskGetStackHighWaterMark( pvTask );
return TRC_SUCCESS;
}
#endif
traceResult xTraceKernelPortDelay( uint32_t uiTicks )
{
vTaskDelay( uiTicks );
return TRC_SUCCESS;
}
unsigned char xTraceKernelPortIsSchedulerSuspended( void )
{
/* Assumed to be available in FreeRTOS. According to the FreeRTOS docs,
* INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in
* FreeRTOSConfig.h for this function to be available. */
return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED;
}
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING )
typedef struct TraceKernelPortData
{
TraceHeapHandle_t xSystemHeapHandle;
TraceKernelPortTaskHandle_t xTzCtrlHandle;
} TraceKernelPortData_t;
static TraceKernelPortData_t * pxKernelPortData;
#define TRC_PORT_MALLOC( size ) pvPortMalloc( size )
traceResult xTraceKernelPortInitialize( TraceKernelPortDataBuffer_t * pxBuffer )
{
TRC_ASSERT_EQUAL_SIZE( TraceKernelPortDataBuffer_t, TraceKernelPortData_t );
if( pxBuffer == 0 )
{
return TRC_FAIL;
}
pxKernelPortData = ( TraceKernelPortData_t * ) pxBuffer;
pxKernelPortData->xSystemHeapHandle = 0;
pxKernelPortData->xTzCtrlHandle = 0;
return TRC_SUCCESS;
}
traceResult xTraceKernelPortEnable( void )
{
HeapStats_t xHeapStats;
void * pvAlloc;
if( pxKernelPortData->xSystemHeapHandle == 0 )
{
/* Some magic to make sure the heap has been initialized! */
pvAlloc = pvPortMalloc( 1 );
if( pvAlloc != 0 )
{
vPortFree( pvAlloc );
}
vPortGetHeapStats( &xHeapStats );
xTraceHeapCreate( "System Heap", configTOTAL_HEAP_SIZE - xHeapStats.xAvailableHeapSpaceInBytes, configTOTAL_HEAP_SIZE - xHeapStats.xMinimumEverFreeBytesRemaining, configTOTAL_HEAP_SIZE, &pxKernelPortData->xSystemHeapHandle );
}
if( pxKernelPortData->xTzCtrlHandle == 0 )
{
/* Creates the TzCtrl task - receives trace commands (start, stop, ...) */
#if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 )
pxKernelPortData->xTzCtrlHandle = xTaskCreateStatic( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl );
#else
xTaskCreate( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &pxKernelPortData->xTzCtrlHandle );
#endif
if( pxKernelPortData->xTzCtrlHandle == 0 )
{
xTraceError( TRC_ERROR_TZCTRLTASK_NOT_CREATED );
return TRC_FAIL;
}
}
return TRC_SUCCESS;
}
static portTASK_FUNCTION( TzCtrl, pvParameters )
{
( void ) pvParameters;
while( 1 )
{
xTraceTzCtrl();
vTaskDelay( TRC_CFG_CTRL_TASK_DELAY );
}
}
#if ( TRC_CFG_SCHEDULING_ONLY == 0 )
void vTraceSetQueueName( void * pvQueue,
const char * szName )
{
xTraceObjectSetNameWithoutHandle( pvQueue, szName );
}
void vTraceSetSemaphoreName( void * pvSemaphore,
const char * szName )
{
xTraceObjectSetNameWithoutHandle( pvSemaphore, szName );
}
void vTraceSetMutexName( void * pvMutex,
const char * szName )
{
xTraceObjectSetNameWithoutHandle( pvMutex, szName );
}
#if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X )
void vTraceSetEventGroupName( void * pvEventGroup,
const char * szName )
{
xTraceObjectSetNameWithoutHandle( pvEventGroup, szName );
}
#endif
#if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 )
void vTraceSetStreamBufferName( void * pvStreamBuffer,
const char * szName )
{
xTraceObjectSetNameWithoutHandle( pvStreamBuffer, szName );
}
void vTraceSetMessageBufferName( void * pvMessageBuffer,
const char * szName )
{
xTraceObjectSetNameWithoutHandle( pvMessageBuffer, szName );
}
#endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */
#endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */
TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle( void )
{
return pxKernelPortData->xSystemHeapHandle;
}
#endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING ) */
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT )
uint32_t prvTraceGetQueueNumber( void * handle );
#if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X )
extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue );
extern void vQueueSetQueueNumber( xQueueHandle pxQueue,
unsigned char ucQueueNumber );
extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue );
uint32_t prvTraceGetQueueNumber( void * handle )
{
return ( uint32_t ) ucQueueGetQueueNumber( handle );
}
#else /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X ) */
uint32_t prvTraceGetQueueNumber( void * handle )
{
return ( uint32_t ) uxQueueGetQueueNumber( handle );
}
#endif /* if ( TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X_X ) */
uint8_t prvTraceGetQueueType( void * pvQueue )
{
/* This is either declared in header file in FreeRTOS 8 and later, or as extern above */
return ucQueueGetQueueType( pvQueue );
}
/* Tasks */
uint16_t prvTraceGetTaskNumberLow16( void * pvTask )
{
return TRACE_GET_LOW16( uxTaskGetTaskNumber( pvTask ) );
}
uint16_t prvTraceGetTaskNumberHigh16( void * pvTask )
{
return TRACE_GET_HIGH16( uxTaskGetTaskNumber( pvTask ) );
}
void prvTraceSetTaskNumberLow16( void * pvTask,
uint16_t uiValue )
{
vTaskSetTaskNumber( pvTask, TRACE_SET_LOW16( uxTaskGetTaskNumber( pvTask ), uiValue ) );
}
void prvTraceSetTaskNumberHigh16( void * pvTask,
uint16_t uiValue )
{
vTaskSetTaskNumber( pvTask, TRACE_SET_HIGH16( uxTaskGetTaskNumber( pvTask ), uiValue ) );
}
uint16_t prvTraceGetQueueNumberLow16( void * pvQueue )
{
return TRACE_GET_LOW16( prvTraceGetQueueNumber( pvQueue ) );
}
uint16_t prvTraceGetQueueNumberHigh16( void * pvQueue )
{
return TRACE_GET_HIGH16( prvTraceGetQueueNumber( pvQueue ) );
}
void prvTraceSetQueueNumberLow16( void * pvQueue,
uint16_t uiValue )
{
vQueueSetQueueNumber( pvQueue, TRACE_SET_LOW16( prvTraceGetQueueNumber( pvQueue ), uiValue ) );
}
void prvTraceSetQueueNumberHigh16( void * pvQueue,
uint16_t uiValue )
{
vQueueSetQueueNumber( pvQueue, TRACE_SET_HIGH16( prvTraceGetQueueNumber( pvQueue ), uiValue ) );
}
#if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 )
uint16_t prvTraceGetTimerNumberLow16( void * pvTimer )
{
return TRACE_GET_LOW16( uxTimerGetTimerNumber( pvTimer ) );
}
uint16_t prvTraceGetTimerNumberHigh16( void * pvTimer )
{
return TRACE_GET_HIGH16( uxTimerGetTimerNumber( pvTimer ) );
}
void prvTraceSetTimerNumberLow16( void * pvTimer,
uint16_t uiValue )
{
vTimerSetTimerNumber( pvTimer, TRACE_SET_LOW16( uxTimerGetTimerNumber( pvTimer ), uiValue ) );
}
void prvTraceSetTimerNumberHigh16( void * pvTimer,
uint16_t uiValue )
{
vTimerSetTimerNumber( pvTimer, TRACE_SET_HIGH16( uxTimerGetTimerNumber( pvTimer ), uiValue ) );
}
#endif /* if ( TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */
#if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 )
uint16_t prvTraceGetEventGroupNumberLow16( void * pvEventGroup )
{
return TRACE_GET_LOW16( uxEventGroupGetNumber( pvEventGroup ) );
}
uint16_t prvTraceGetEventGroupNumberHigh16( void * pvEventGroup )
{
return TRACE_GET_HIGH16( uxEventGroupGetNumber( pvEventGroup ) );
}
void prvTraceSetEventGroupNumberLow16( void * pvEventGroup,
uint16_t uiValue )
{
vEventGroupSetNumber( pvEventGroup, TRACE_SET_LOW16( uxEventGroupGetNumber( pvEventGroup ), uiValue ) );
}
void prvTraceSetEventGroupNumberHigh16( void * pvEventGroup,
uint16_t uiValue )
{
vEventGroupSetNumber( pvEventGroup, TRACE_SET_HIGH16( uxEventGroupGetNumber( pvEventGroup ), uiValue ) );
}
#endif /* if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */
#if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 )
uint16_t prvTraceGetStreamBufferNumberLow16( void * pvStreamBuffer )
{
return TRACE_GET_LOW16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ) );
}
uint16_t prvTraceGetStreamBufferNumberHigh16( void * pvStreamBuffer )
{
return TRACE_GET_HIGH16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ) );
}
void prvTraceSetStreamBufferNumberLow16( void * pvStreamBuffer,
uint16_t uiValue )
{
vStreamBufferSetStreamBufferNumber( pvStreamBuffer, TRACE_SET_LOW16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ), uiValue ) );
}
void prvTraceSetStreamBufferNumberHigh16( void * pvStreamBuffer,
uint16_t uiValue )
{
vStreamBufferSetStreamBufferNumber( pvStreamBuffer, TRACE_SET_HIGH16( uxStreamBufferGetStreamBufferNumber( pvStreamBuffer ), uiValue ) );
}
#endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */
static TraceKernelPortTaskHandle_t xTzCtrlHandle = 0; /* TzCtrl task TCB */
/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */
int uiInEventGroupSetBitsFromISR = 0;
/**
* @internal Class reference table
*/
traceObjectClass TraceQueueClassTable[ 5 ] =
{
TRACE_CLASS_QUEUE,
TRACE_CLASS_MUTEX,
TRACE_CLASS_SEMAPHORE,
TRACE_CLASS_SEMAPHORE,
TRACE_CLASS_MUTEX
};
#if ( TRC_CFG_SCHEDULING_ONLY == 0 )
void vTraceSetQueueName( void * pvQueue,
const char * szName )
{
prvTraceSetObjectName( TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER( QUEUE, pvQueue ), szName );
}
void vTraceSetSemaphoreName( void * pvSemaphore,
const char * szName )
{
prvTraceSetObjectName( TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER( QUEUE, pvSemaphore ), szName );
}
void vTraceSetMutexName( void * pvMutex,
const char * szName )
{
prvTraceSetObjectName( TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER( QUEUE, pvMutex ), szName );
}
#if ( TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X_X )
void vTraceSetEventGroupName( void * pvEventGroup,
const char * szName )
{
prvTraceSetObjectName( TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER( EVENTGROUP, pvEventGroup ), szName );
}
#endif
#if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 )
void vTraceSetStreamBufferName( void * pvStreamBuffer,
const char * szName )
{
prvTraceSetObjectName( TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER( STREAMBUFFER, pvStreamBuffer ), szName );
}
void vTraceSetMessageBufferName( void * pvStreamBuffer,
const char * szName )
{
prvTraceSetObjectName( TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER( STREAMBUFFER, pvStreamBuffer ), szName );
}
#endif /* if ( TRC_CFG_INCLUDE_STREAM_BUFFER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0 ) */
#endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */
void * prvTraceGetCurrentTaskHandle()
{
return xTaskGetCurrentTaskHandle();
}
traceResult xTraceKernelPortInitialize( TraceKernelPortDataBuffer_t * pxBuffer )
{
( void ) pxBuffer;
return TRC_SUCCESS;
}
traceResult xTraceKernelPortEnable( void )
{
#if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 )
if( xTzCtrlHandle == 0 )
{
#if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 )
xTzCtrlHandle = xTaskCreateStatic( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl );
#else
xTaskCreate( TzCtrl, STRING_CAST( "TzCtrl" ), TRC_CFG_CTRL_TASK_STACK_SIZE, 0, TRC_CFG_CTRL_TASK_PRIORITY, &xTzCtrlHandle );
#endif
}
#else
( void ) xTzCtrlHandle;
#endif
return TRC_SUCCESS;
}
#if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 )
static portTASK_FUNCTION( TzCtrl, pvParameters )
{
( void ) pvParameters;
while( 1 )
{
if( xTraceIsRecorderEnabled() )
{
prvReportStackUsage();
}
vTaskDelay( TRC_CFG_CTRL_TASK_DELAY );
}
}
#endif /* if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) */
traceResult xTraceKernelPortInitObjectPropertyTable()
{
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 0 ] = TRC_CFG_NQUEUE;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 1 ] = TRC_CFG_NSEMAPHORE;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 2 ] = TRC_CFG_NMUTEX;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 3 ] = TRC_CFG_NTASK;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 4 ] = TRC_CFG_NISR;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 5 ] = TRC_CFG_NTIMER;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 6 ] = TRC_CFG_NEVENTGROUP;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 7 ] = TRC_CFG_NSTREAMBUFFER;
RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[ 8 ] = TRC_CFG_NMESSAGEBUFFER;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 0 ] = TRC_CFG_NAME_LEN_QUEUE;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 1 ] = TRC_CFG_NAME_LEN_SEMAPHORE;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 2 ] = TRC_CFG_NAME_LEN_MUTEX;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 3 ] = TRC_CFG_NAME_LEN_TASK;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 4 ] = TRC_CFG_NAME_LEN_ISR;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 5 ] = TRC_CFG_NAME_LEN_TIMER;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 6 ] = TRC_CFG_NAME_LEN_EVENTGROUP;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 7 ] = TRC_CFG_NAME_LEN_STREAMBUFFER;
RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ 8 ] = TRC_CFG_NAME_LEN_MESSAGEBUFFER;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 0 ] = PropertyTableSizeQueue;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 1 ] = PropertyTableSizeSemaphore;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 2 ] = PropertyTableSizeMutex;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 3 ] = PropertyTableSizeTask;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 4 ] = PropertyTableSizeISR;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 5 ] = PropertyTableSizeTimer;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 6 ] = PropertyTableSizeEventGroup;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 7 ] = PropertyTableSizeStreamBuffer;
RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[ 8 ] = PropertyTableSizeMessageBuffer;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 0 ] = StartIndexQueue;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 1 ] = StartIndexSemaphore;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 2 ] = StartIndexMutex;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 3 ] = StartIndexTask;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 4 ] = StartIndexISR;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 5 ] = StartIndexTimer;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 6 ] = StartIndexEventGroup;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 7 ] = StartIndexStreamBuffer;
RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[ 8 ] = StartIndexMessageBuffer;
RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE;
return TRC_SUCCESS;
}
traceResult xTraceKernelPortInitObjectHandleStack()
{
uint32_t i = 0;
objectHandleStacks.indexOfNextAvailableHandle[ 0 ] = objectHandleStacks.lowestIndexOfClass[ 0 ] = 0;
objectHandleStacks.indexOfNextAvailableHandle[ 1 ] = objectHandleStacks.lowestIndexOfClass[ 1 ] = ( TRC_CFG_NQUEUE );
objectHandleStacks.indexOfNextAvailableHandle[ 2 ] = objectHandleStacks.lowestIndexOfClass[ 2 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE );
objectHandleStacks.indexOfNextAvailableHandle[ 3 ] = objectHandleStacks.lowestIndexOfClass[ 3 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX );
objectHandleStacks.indexOfNextAvailableHandle[ 4 ] = objectHandleStacks.lowestIndexOfClass[ 4 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK );
objectHandleStacks.indexOfNextAvailableHandle[ 5 ] = objectHandleStacks.lowestIndexOfClass[ 5 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR );
objectHandleStacks.indexOfNextAvailableHandle[ 6 ] = objectHandleStacks.lowestIndexOfClass[ 6 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER );
objectHandleStacks.indexOfNextAvailableHandle[ 7 ] = objectHandleStacks.lowestIndexOfClass[ 7 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP );
objectHandleStacks.indexOfNextAvailableHandle[ 8 ] = objectHandleStacks.lowestIndexOfClass[ 8 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER );
objectHandleStacks.highestIndexOfClass[ 0 ] = ( TRC_CFG_NQUEUE ) -1;
objectHandleStacks.highestIndexOfClass[ 1 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) -1;
objectHandleStacks.highestIndexOfClass[ 2 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) -1;
objectHandleStacks.highestIndexOfClass[ 3 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) -1;
objectHandleStacks.highestIndexOfClass[ 4 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) -1;
objectHandleStacks.highestIndexOfClass[ 5 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) -1;
objectHandleStacks.highestIndexOfClass[ 6 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) -1;
objectHandleStacks.highestIndexOfClass[ 7 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER ) -1;
objectHandleStacks.highestIndexOfClass[ 8 ] = ( TRC_CFG_NQUEUE ) + ( TRC_CFG_NSEMAPHORE ) + ( TRC_CFG_NMUTEX ) + ( TRC_CFG_NTASK ) + ( TRC_CFG_NISR ) + ( TRC_CFG_NTIMER ) + ( TRC_CFG_NEVENTGROUP ) + ( TRC_CFG_NSTREAMBUFFER ) + ( TRC_CFG_NMESSAGEBUFFER ) -1;
for( i = 0; i < TRACE_NCLASSES; i++ )
{
objectHandleStacks.handleCountWaterMarksOfClass[ i ] = 0;
}
for( i = 0; i < TRACE_KERNEL_OBJECT_COUNT; i++ )
{
objectHandleStacks.objectHandles[ i ] = 0;
}
return TRC_SUCCESS;
}
const char * pszTraceGetErrorNotEnoughHandles( traceObjectClass objectclass )
{
switch( objectclass )
{
case TRACE_CLASS_TASK:
return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h";
case TRACE_CLASS_ISR:
return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h";
case TRACE_CLASS_SEMAPHORE:
return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h";
case TRACE_CLASS_MUTEX:
return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h";
case TRACE_CLASS_QUEUE:
return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h";
case TRACE_CLASS_TIMER:
return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h";
case TRACE_CLASS_EVENTGROUP:
return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h";
case TRACE_CLASS_STREAMBUFFER:
return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h";
case TRACE_CLASS_MESSAGEBUFFER:
return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h";
default:
return "pszTraceGetErrorHandles: Invalid objectclass!";
}
}
#endif /* if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT ) */
#endif /* if ( defined( TRC_USE_TRACEALYZER_RECORDER ) && TRC_USE_TRACEALYZER_RECORDER == 1 ) */