FreeRTOS-Kernel/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/Include/trcRecorder.h
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

1910 lines
82 KiB
C

/*
* Trace Recorder for Tracealyzer v4.6.0
* Copyright 2021 Percepio AB
* www.percepio.com
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef TRC_RECORDER_H
#define TRC_RECORDER_H
/**
* @file
*
* @brief The public API of the Percepio trace recorder.
*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Trace Recorder APIs
* @defgroup trace_recorder_apis Trace Recorder APIs
* @{
* @}
*/
#define TRC_ACKNOWLEDGED ( 0xABC99123 )
#include <trcDefines.h>
#include <trcConfig.h>
#include <trcKernelPortConfig.h>
#include <trcTypes.h>
#ifndef TRC_CFG_TEST_MODE
#define TRC_CFG_TEST_MODE 0
#endif
/* Unless defined by the kernel port, we assume there is no support for
* the classic snapshot mode and default to streaming mode where
* the new RingBuffer snapshot mode provides snapshot functionality.
*/
#ifndef TRC_CFG_RECORDER_MODE
#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING
#endif
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT )
#include <trcSnapshotConfig.h>
#include <trcKernelPortSnapshotConfig.h>
/* Calls xTraceError if the _assert condition is false. For void functions,
* where no return value is to be provided. */
#define TRC_ASSERT_VOID( _assert, _err ) if( !( _assert ) ) { prvTraceError( _err ); return; }
/* Calls xTraceError if the _assert condition is false. For non-void functions,
* where a return value is to be provided. */
#define TRC_ASSERT_RET( _assert, _err, _return ) if( !( _assert ) ) { prvTraceError( _err ); return _return; }
typedef uint8_t traceUBChannel;
typedef uint8_t traceObjectClass;
#undef traceHandle
#if ( TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1 )
typedef uint16_t traceHandle;
#else /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
typedef uint8_t traceHandle;
#endif /* (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) */
#include <trcHardwarePort.h>
#include <trcKernelPort.h>
/* Not yet available in snapshot mode */
#define vTraceConsoleChannelPrintF( fmt, ... ) ( void )
#define xTraceConsoleChannelPrintF( fmt, ... ) ( void )
#define prvTraceStoreEvent_None( ... )
#define prvTraceStoreEvent_Handle( ... )
#define prvTraceStoreEvent_Param( ... )
#define prvTraceStoreEvent_HandleParam( ... )
#define prvTraceStoreEvent_ParamParam( ... )
#define prvTraceStoreEvent_HandleParamParam( ... )
#define prvTraceStoreEvent_ParamParamParam( ... )
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) */
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING )
#include <trcStreamingConfig.h>
#include <trcKernelPortStreamingConfig.h>
/* Unless specified in trcConfig.h we assume this is a single core target */
#ifndef TRC_CFG_CORE_COUNT
#define TRC_CFG_CORE_COUNT 1
#endif
/* Unless specified in trcConfig.h we assume this is a single core target */
#ifndef TRC_CFG_GET_CURRENT_CORE
#define TRC_CFG_GET_CURRENT_CORE() 0
#endif
/* Unless specified in trcConfig.h or trcKernelPortConfig.h we assume
* GCC statement expressions aren't supported. */
#ifndef TRC_CFG_USE_GCC_STATEMENT_EXPR
#define TRC_CFG_USE_GCC_STATEMENT_EXPR 0
#endif
/* Backwards compatibility */
typedef TraceISRHandle_t traceHandle;
/* Maximum event size */
#define TRC_MAX_BLOB_SIZE ( 16 * sizeof( uint32_t ) )
/* Platform name length */
#define TRC_PLATFORM_CFG_LENGTH 8
/* Header size */
#define TRC_HEADER_BUFFER_SIZE ( sizeof( uint32_t ) + sizeof( uint16_t ) + sizeof( uint16_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint32_t ) + ( sizeof( char ) * ( TRC_PLATFORM_CFG_LENGTH ) ) + sizeof( uint16_t ) + sizeof( uint8_t ) + sizeof( uint8_t ) )
typedef struct TraceHeaderBuffer
{
uint8_t buffer[ TRC_HEADER_BUFFER_SIZE ];
} TraceHeaderBuffer_t;
#include <trcHardwarePort.h>
#include <trcKernelPort.h>
#include <trcString.h>
#include <trcStaticBuffer.h>
#include <trcError.h>
#include <trcEvent.h>
#include <trcEventBuffer.h>
#include <trcMultiCoreEventBuffer.h>
#include <trcTimestamp.h>
#include <trcEntryTable.h>
#include <trcStreamPort.h>
#include <trcISR.h>
#include <trcTask.h>
#include <trcObject.h>
#include <trcPrint.h>
#include <trcHeap.h>
#include <trcStateMachine.h>
#include <trcExtension.h>
#include <trcInterval.h>
#include <trcUtility.h>
#include <trcStackMonitor.h>
#include <trcInternalEventBuffer.h>
#include <trcDiagnostics.h>
#include <trcAssert.h>
#include <trcCounter.h>
#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */
#if ( TRC_USE_TRACEALYZER_RECORDER == 1 )
/******************************************************************************/
/*** Common API - both Snapshot and Streaming mode ****************************/
/******************************************************************************/
/**
* @brief
*
* Initializes the recorder data. xTraceInitialize() or xTraceEnable(...)
* must be called before any attempts at adding trace data/information.
* See xTraceEnable(...) for more information.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceInitialize( void );
/**
* @brief
*
* This function enables tracing.
* To use the trace recorder, the startup must call xTraceInitialize() or
* xTraceEnable(...) before any RTOS calls are made (including "create" calls).
* Three start options are provided:
*
* TRC_START: Starts the tracing directly. In snapshot mode this allows for
* starting the trace at any point in your code, assuming xTraceInitialize()
* has been called in the startup. Can also be used for streaming without
* Tracealyzer control, e.g. to a local flash file system (assuming such a
* "stream port", see trcStreamPort.h).
*
* TRC_START_AWAIT_HOST: For streaming mode only. Initializes the trace recorder
* if necessary and waits for a Start command from Tracealyzer ("Start Recording"
* button). This call is intentionally blocking! By calling xTraceEnable with
* this option from the startup code, you start tracing at this point and capture
* the early events.
*
* TRC_START_FROM_HOST: For streaming mode only. Initializes the trace recorder
* if necessary and creates a task that waits for a Start command from
* Tracealyzer ("Start Recording" button). This call is not blocking.
*
* @example Usage examples
*
* Snapshot trace, from startup:
* <board init>
* xTraceEnable(TRC_START); // Will call xTraceInitialize()
* <RTOS init>
*
* Snapshot trace, from a later point:
* <board init>
* xTraceInitialize();
* <RTOS init>
* ...
* xTraceEnable(TRC_START); // e.g., in task context, at some relevant event
*
* Streaming trace, from startup (can only be used with certain stream ports):
* <board startup>
* xTraceInitialize();
* <RTOS startup>
* xTraceEnable(TRC_START);
*
* Streaming trace, from startup:
* <board init>
* xTraceEnable(TRC_START_AWAIT_HOST); // Blocks!
* <RTOS init>
*
* Streaming trace, from a later point:
* <board startup>
* xTraceInitialize();
* <RTOS startup>
* xTraceEnable(TRC_START);
*
* Streaming trace, system executes normally until host starts tracing:
* <board startup>
* xTraceInitialize();
* <RTOS startup>
* xTraceEnable(TRC_START_FROM_HOST)
*
* @param[in] uiStartOption Start option.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceEnable( uint32_t uiStartOption );
/**
* @brief Disables tracing.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceDisable( void );
/**
* @brief
*
* For snapshot mode only: Sets the "filter group" to assign when creating
* RTOS objects, such as tasks, queues, semaphores and mutexes. This together
* with vTraceSetFilterMask allows you to control what events that are recorded,
* based on the objects they refer to.
*
* There are 16 filter groups named FilterGroup0 .. FilterGroup15.
*
* Note: We don't recommend filtering out the Idle task, so make sure to call
* vTraceSetFilterGroup just before initializing the RTOS, in order to assign
* such "default" objects to the right Filter Group (typically group 0).
*
* Example:
*
* // Assign tasks T1 to FilterGroup0 (default)
* <Create Task T1>
*
* // Assign Q1 and Q2 to FilterGroup1
* vTraceSetFilterGroup(FilterGroup1);
* <Create Queue Q1>
* <Create Queue Q2>
*
* // Assigns Q3 to FilterGroup2
* vTraceSetFilterGroup(FilterGroup2);
* <Create Queue Q3>
*
* // Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace
* vTraceSetFilterMask( FilterGroup0 | FilterGroup2 );
*
* // Assign the default RTOS objects (e.g. Idle task) to FilterGroup0
* vTraceSetFilterGroup(FilterGroup0);
* <Start the RTOS scheduler>
*
* Note that you may define your own names for the filter groups using
* preprocessor definitions, to make the code easier to understand.
*
* Example:
*
* #define BASE FilterGroup0
* #define USB_EVENTS FilterGroup1
* #define CAN_EVENTS FilterGroup2
*
* Note that filtering per event type (regardless of object) is also available
* in trcKernelPortConfig.h for certain kernels.
*
* @param[in] filterGroup Filter group
*/
void vTraceSetFilterGroup( uint16_t filterGroup );
/**
* @brief
*
* For snapshot mode only: Sets the "filter mask" that is used to filter
* the events by object. This can be used to reduce the trace data rate, i.e.,
* if your streaming interface is a bottleneck or if you want longer snapshot
* traces without increasing the buffer size.
*
* Note: There are two kinds of filters in the recorder. The other filter type
* excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h.
*
* The filtering is based on bitwise AND with the Filter Group ID, assigned
* to RTOS objects such as tasks, queues, semaphores and mutexes.
* This together with vTraceSetFilterGroup allows you to control what
* events that are recorded, based on the objects they refer to.
*
* See example for vTraceSetFilterGroup.
*
* @param[in] filterMask Filter mask
*/
void vTraceSetFilterMask( uint16_t filterMask );
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT )
#include <stdarg.h>
/**
* @brief Returns lower 16 bits of a value
*
* @param[in] value The starting value
*/
#define TRACE_GET_LOW16( value ) ( ( uint16_t ) ( ( value ) & 0x0000FFFF ) )
/**
* @brief Returns upper 16 bits
*
* @param[in] value The starting value
*/
#define TRACE_GET_HIGH16( value ) ( ( uint16_t ) ( ( ( value ) >> 16 ) & 0x0000FFFF ) )
/**
* @brief Sets lower 16 bits
*
* @param[in] current The starting value
* @param[in] value The value to set
*/
#define TRACE_SET_LOW16( current, value ) ( ( ( current ) & 0xFFFF0000 ) | ( value ) )
/**
* @brief Sets upper 16 bits
*
* @param[in] current The starting value
* @param[in] value The value to set
*/
#define TRACE_SET_HIGH16( current, value ) ( ( ( current ) & 0x0000FFFF ) | ( ( ( uint32_t ) ( value ) ) << 16 ) )
#if defined( TRC_CFG_ENABLE_STACK_MONITOR ) && ( TRC_CFG_ENABLE_STACK_MONITOR == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 )
/**
* @brief Adds a task to the stack monitor
*
* @param[in] task The task
*/
void prvAddTaskToStackMonitor( void * task );
/**
* @brief Remove a task from the stack monitor
*
* @param[in] task The task
*/
void prvRemoveTaskFromStackMonitor( void * task );
/**
* @brief Reports on the current stack usage
*/
void prvReportStackUsage( void );
#else /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
#define prvAddTaskToStackMonitor( task )
#define prvRemoveTaskFromStackMonitor( task )
#define prvReportStackUsage()
#endif /* defined (TRC_CFG_ENABLE_STACK_MONITOR) && (TRC_CFG_ENABLE_STACK_MONITOR == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) */
/**
* @brief Query if recorder is enabled
*
* @retval 1 if recorder is enabled
* @retval 0 if recorder is disabled
*/
uint32_t xTraceIsRecorderEnabled( void );
/**
* @brief
*
* @retval 1 if recorder is initialized
* @retval 0 if recorder isn't initialized
*/
uint32_t xTraceIsRecorderInitialized( void );
/**
* @brief
*
* Creates an event that ends the current task instance at this very instant.
* This makes the viewer to splits the current fragment at this point and begin
* a new actor instance, even if no task-switch has occurred.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskInstanceFinishedNow( void );
/**
* @brief
*
* Marks the current "task instance" as finished on the next kernel call.
*
* If that kernel call is blocking, the instance ends after the blocking event
* and the corresponding return event is then the start of the next instance.
* If the kernel call is not blocking, the viewer instead splits the current
* fragment right before the kernel call, which makes this call the first event
* of the next instance.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTaskInstanceFinishedNext( void );
/**
* @brief Registers a string and returns a handle that can be used when tracing
*
* @param[in] label Label
* @param[out] pxString String handle
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceStringRegister( const char * label,
TraceStringHandle_t * pxString );
/**
* @brief Registers a string and returns a handle that can be used when tracing
*
* @deprecated Backwards compatibility
*
* @param[in] name Name.
*
* @return TraceStringHandle_t String handle
*/
TraceStringHandle_t xTraceRegisterString( const char * name );
#if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 )
/**
* @brief
*
* Generates "User Events", with formatted text and data, similar to a "printf".
* User Events can be used for very efficient logging from your application code.
* It is very fast since the actual string formatting is done on the host side,
* when the trace is displayed. The execution time is just some microseconds on
* a 32-bit MCU.
*
* User Events are shown as yellow labels in the main trace view of $PNAME.
*
* An advantage of User Events is that data can be plotted in the "User Event
* Signal Plot" view, visualizing any data you log as User Events, discrete
* states or control system signals (e.g. system inputs or outputs).
*
* You may group User Events into User Event Channels. The yellow User Event
* labels show the logged string, preceded by the channel name within brackets.
*
* Example:
*
* "[MyChannel] Hello World!"
*
* The User Event Channels are shown in the View Filter, which makes it easy to
* select what User Events you wish to display. User Event Channels are created
* using xTraceStringRegister().
*
* Example:
*
* TraceStringHandle_t adc_uechannel;
* xTraceStringRegister("ADC User Events", &adc_uechannel);
* ...
* xTracePrintF(adc_uechannel,
* "ADC channel %d: %d volts",
* ch, adc_reading);
*
* The following format specifiers are supported in both modes:
* %d - signed integer.
* %u - unsigned integer.
* %X - hexadecimal, uppercase.
* %x - hexadecimal, lowercase.
* %s - string (see comment below)
*
* For integer formats (%d, %u, %x, %X) you may also use width and padding.
* If using -42 as data argument, two examples are:
* "%05d" -> "-0042"
* "%5d" -> " -42".
*
* String arguments are supported in both snapshot and streaming, but in streaming
* mode you need to use xTraceStringRegister and use the returned TraceStringHandle_t as
* the argument. In snapshot you simply provide a char* as argument.
*
* Snapshot: xTracePrintF(myChn, "my string: %s", str);
* Streaming: xTracePrintF(myChn, "my string: %s", strTraceString);
*
* In snapshot mode you can specify 8-bit or 16-bit arguments to reduce RAM usage:
* %hd -> 16 bit (h) signed integer (d).
* %bu -> 8 bit (b) unsigned integer (u).
*
* However, in streaming mode all data arguments are assumed to be 32 bit wide.
* Width specifiers (e.g. %hd) are accepted but ignored (%hd treated like %d).
*
* The maximum event size also differs between the modes. In streaming this is
* limited by a maximum payload size of 52 bytes, including format string and
* data arguments. So if using one data argument, the format string is limited
* to 48 byte, etc. If this is exceeded, the format string is truncated and you
* get a warning in Tracealyzer.
*
* In snapshot mode you are limited to maximum 15 arguments, that must not exceed
* 32 bytes in total (not counting the format string). If exceeded, the recorder
* logs an internal error (displayed when opening the trace) and stops recording.
*
* @param[in] chn Channel.
* @param[in] fmt Formatting.
* @param[in] ...
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTracePrintF( TraceStringHandle_t chn,
const char * fmt,
... );
#else
#define xTracePrintF( chn, fmt, ... ) ( ( void ) ( chn ), ( void ) ( fmt ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
#endif
#if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 )
/**
* @brief
*
* xTracePrintF variant that accepts a va_list.
* See xTracePrintF documentation for further details.
*
* @param[in] eventLabel
* @param[in] formatStr
* @param[in] vl
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceVPrintF( TraceStringHandle_t eventLabel,
const char * formatStr,
va_list vl );
#else
#define xTraceVPrintF( chn, formatStr, vl ) ( ( void ) ( chn ), ( void ) ( formatStr ), ( void ) ( vl ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
#endif
#if ( TRC_CFG_SCHEDULING_ONLY == 0 ) && ( TRC_CFG_INCLUDE_USER_EVENTS == 1 )
/**
* @brief A faster version of xTracePrintF, that only allows for logging a string.
*
* Example:
*
* TraceStringHandle_t chn;
* xTraceStringRegister("MyChannel", &chn);
* ...
* xTracePrint(chn, "Hello World!");
*
* @param[in] chn Channel.
* @param[in] str String.
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTracePrint( TraceStringHandle_t chn,
const char * str );
#else
#define xTracePrint( chn, str ) ( ( void ) ( chn ), ( void ) ( str ), TRC_SUCCESS )
#endif
/******************************************************************************/
/*** Extended API for Snapshot mode *******************************************/
/******************************************************************************/
/**
* @brief Trace stop callback type.
*/
typedef void (* TRACE_STOP_HOOK)( void );
/**
* @brief Sets a function to be called when the recorder is stopped.
*
* @note Snapshot mode only!
*
* @param[in] stopHookFunction
*/
void vTraceSetStopHook( TRACE_STOP_HOOK stopHookFunction );
/**
* @brief
*
* Resets the recorder.
*
* Only necessary if a restart is desired - this is not
* needed in the startup initialization.
*
* @note Snapshot mode only!
*/
void vTraceClear( void );
/*****************************************************************************/
/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/
/*****************************************************************************/
#define TRC_UNUSED
#ifndef TRC_CFG_INCLUDE_OBJECT_DELETE
#define TRC_CFG_INCLUDE_OBJECT_DELETE 0
#endif
#ifndef TRC_CFG_INCLUDE_READY_EVENTS
#define TRC_CFG_INCLUDE_READY_EVENTS 1
#endif
#ifndef TRC_CFG_INCLUDE_OSTICK_EVENTS
#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0
#endif
/* This macro will create a task in the object table */
#undef trcKERNEL_HOOKS_TASK_CREATE
#define trcKERNEL_HOOKS_TASK_CREATE( SERVICE, CLASS, pxTCB ) \
if( ( pxTCB ) != 0 ) \
{ \
TRACE_SET_OBJECT_NUMBER( TASK, pxTCB ); \
TRACE_SET_OBJECT_FILTER( TASK, pxTCB, CurrentFilterGroup ); \
prvTraceSetObjectName( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_GET_TASK_NAME( pxTCB ) ); \
prvTraceSetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_GET_TASK_PRIORITY( pxTCB ) ); \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); \
} \
else \
{ \
/* pxTCB is null */ \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
{ \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, 0 ); \
} \
}
/* This macro will remove the task and store it in the event buffer */
#undef trcKERNEL_HOOKS_TASK_DELETE
#define trcKERNEL_HOOKS_TASK_DELETE( SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); \
prvTraceStoreObjectNameOnCloseEvent( SERVICE_NAME, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_CLASS_TASK ); \
prvTraceStoreObjectPropertiesOnCloseEvent( SERVICE_PROP, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_CLASS_TASK ); \
prvTraceSetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TRACE_GET_TASK_PRIORITY( pxTCB ) ); \
prvTraceSetObjectState( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), TASK_STATE_INSTANCE_NOT_ACTIVE ); \
prvTraceFreeObjectHandle( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) );
/* This macro will setup a task in the object table */
#undef trcKERNEL_HOOKS_OBJECT_CREATE
#define trcKERNEL_HOOKS_OBJECT_CREATE( SERVICE, CLASS, pxObject ) \
TRACE_SET_OBJECT_NUMBER( CLASS, pxObject ); \
TRACE_SET_OBJECT_FILTER( CLASS, pxObject, CurrentFilterGroup ); \
prvMarkObjectAsUsed( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); \
prvTraceSetObjectState( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), 0 );
/* This macro will setup a task in the object table */
#undef trcKERNEL_HOOKS_OBJECT_CREATE_FAILED
#define trcKERNEL_HOOKS_OBJECT_CREATE_FAILED( SERVICE, TRACE_CLASS ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
{ \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS, 0 ); \
}
/* This macro will remove the object and store it in the event buffer */
#undef trcKERNEL_HOOKS_OBJECT_DELETE
#define trcKERNEL_HOOKS_OBJECT_DELETE( SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) ); \
prvTraceStoreObjectNameOnCloseEvent( SERVICE_NAME, TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ) ); \
prvTraceStoreObjectPropertiesOnCloseEvent( SERVICE_PROP, TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ) ); \
prvTraceFreeObjectHandle( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) );
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE
#define trcKERNEL_HOOKS_KERNEL_SERVICE( SERVICE, CLASS, pxObject ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) );
/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT
#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT( SERVICE, TRACECLASS ) \
if( TRACE_GET_TASK_FILTER( TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACECLASS, 0 );
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM( SERVICE, CLASS, pxObject, param ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \
prvTraceStoreKernelCallWithParam( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), ( uint32_t ) param );
/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM
#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM( SERVICE, TRACECLASS, param ) \
if( TRACE_GET_TASK_FILTER( TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
prvTraceStoreKernelCallWithParam( SERVICE, TRACECLASS, 0, param );
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY( SERVICE, param ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, ( uint32_t ) param );
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR
#define trcKERNEL_HOOKS_KERNEL_SERVICE_FROM_ISR( SERVICE, CLASS, pxObject ) \
if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ) );
/* This macro will create a call to a kernel service with a certain result, with a null object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR
#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_FROM_ISR( SERVICE, TRACECLASS ) \
prvTraceStoreKernelCall( SERVICE, TRACECLASS, 0 );
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM_FROM_ISR( SERVICE, CLASS, pxObject, param ) \
if( TRACE_GET_OBJECT_FILTER( CLASS, pxObject ) & CurrentFilterMask ) \
prvTraceStoreKernelCallWithParam( SERVICE, TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), ( uint32_t ) param );
/* This macro will create a call to a kernel service with a certain result, with a null object and other value as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR
#define trcKERNEL_HOOKS_KERNEL_SERVICE_NULL_OBJECT_WITH_PARAM_FROM_ISR( SERVICE, TRACECLASS, param ) \
prvTraceStoreKernelCallWithParam( SERVICE, TRACECLASS, 0, param );
/* This macro will create a call to a kernel service with a certain result, with an object as parameter */
#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR
#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY_FROM_ISR( SERVICE, param ) \
prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, ( uint32_t ) param );
/* This macro will set the state for an object */
#undef trcKERNEL_HOOKS_SET_OBJECT_STATE
#define trcKERNEL_HOOKS_SET_OBJECT_STATE( CLASS, pxObject, STATE ) \
prvTraceSetObjectState( TRACE_GET_OBJECT_TRACE_CLASS( CLASS, pxObject ), TRACE_GET_OBJECT_NUMBER( CLASS, pxObject ), ( uint8_t ) STATE );
/* This macro will flag a certain task as a finished instance */
#undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED
#define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
prvTraceSetTaskInstanceFinished( TRACE_GET_TASK_NUMBER( TRACE_GET_CURRENT_TASK() ) );
#if ( TRC_CFG_INCLUDE_READY_EVENTS == 1 )
/* This macro will create an event to indicate that a task became Ready */
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE( pxTCB ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreTaskReady( TRACE_GET_TASK_NUMBER( pxTCB ) );
#else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE
#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE( pxTCB )
#endif /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/
/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */
#undef trcKERNEL_HOOKS_INCREMENT_TICK
#define trcKERNEL_HOOKS_INCREMENT_TICK() \
{ \
extern uint32_t uiTraceTickCount; \
uiTraceTickCount++; \
prvTracePortGetTimeStamp( 0 ); \
}
#if ( TRC_CFG_INCLUDE_OSTICK_EVENTS == 1 )
/* This macro will create an event indicating that the OS tick count has increased */
#undef trcKERNEL_HOOKS_NEW_TIME
#define trcKERNEL_HOOKS_NEW_TIME( SERVICE, xValue ) \
prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, xValue );
#else /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/
#undef trcKERNEL_HOOKS_NEW_TIME
#define trcKERNEL_HOOKS_NEW_TIME( SERVICE, xValue )
#endif /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/
/* This macro will create a task switch event to the currently executing task */
#undef trcKERNEL_HOOKS_TASK_SWITCH
#define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreTaskswitch( TRACE_GET_TASK_NUMBER( pxTCB ) );
/* This macro will create an event to indicate that the task has been suspended */
#undef trcKERNEL_HOOKS_TASK_SUSPEND
#define trcKERNEL_HOOKS_TASK_SUSPEND( SERVICE, pxTCB ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ); \
prvTraceSetTaskInstanceFinished( ( uint8_t ) TRACE_GET_TASK_NUMBER( pxTCB ) );
/* This macro will create an event to indicate that a task has called a wait/delay function */
#undef trcKERNEL_HOOKS_TASK_DELAY
#define trcKERNEL_HOOKS_TASK_DELAY( SERVICE, pxTCB, xValue ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
{ \
prvTraceStoreKernelCallWithNumericParamOnly( SERVICE, xValue ); \
prvTraceSetTaskInstanceFinished( ( uint8_t ) TRACE_GET_TASK_NUMBER( pxTCB ) ); \
}
/* This macro will create an event to indicate that a task has gotten its priority changed */
#undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE
#define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE( SERVICE, pxTCB, uxNewPriority ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
{ \
prvTraceStoreKernelCallWithParam( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), prvTraceGetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) ) ); \
prvTraceSetPriorityProperty( TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ), ( uint8_t ) uxNewPriority ); \
}
/* This macro will create an event to indicate that the task has been resumed */
#undef trcKERNEL_HOOKS_TASK_RESUME
#define trcKERNEL_HOOKS_TASK_RESUME( SERVICE, pxTCB ) \
if( TRACE_GET_OBJECT_FILTER( TASK, TRACE_GET_CURRENT_TASK() ) & CurrentFilterMask ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) );
/* This macro will create an event to indicate that the task has been resumed from ISR */
#undef trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR
#define trcKERNEL_HOOKS_TASK_RESUME_FROM_ISR( SERVICE, pxTCB ) \
if( TRACE_GET_OBJECT_FILTER( TASK, pxTCB ) & CurrentFilterMask ) \
prvTraceStoreKernelCall( SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER( pxTCB ) );
#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1
/**
* @brief Dynamically enables ready events
*
* @param[in] flag Flag
*/
void prvTraceSetReadyEventsEnabled( uint32_t flag );
/**
* @brief Stores a Task Ready event
*
* @param[in] handle Task handle
*/
void prvTraceStoreTaskReady( traceHandle handle );
#else
#define prvTraceSetReadyEventsEnabled( status ) ( void ) status;
#endif
/**
* @brief Stores a Low Power mode event
*
* @param[in] flag Flag
*/
void prvTraceStoreLowPower( uint32_t flag );
/**
* @brief Stores a Task Switch event
*
* @param[in] task_handle Task
*/
void prvTraceStoreTaskswitch( traceHandle task_handle );
#if ( TRC_CFG_SCHEDULING_ONLY == 0 )
/**
* @brief Stores a Kernel Service call event with an Object handle parameter
*
* @param[in] eventcode Event code
* @param[in] objectClass Object class
* @param[in] objectNumber Object handle
*/
void prvTraceStoreKernelCall( uint32_t eventcode,
traceObjectClass objectClass,
uint32_t objectNumber );
/**
* @brief Stores a Kernel Service call event with only a numeric parameter
*
* @param[in] evtcode Event code
* @param[in] param Parameter
*/
void prvTraceStoreKernelCallWithNumericParamOnly( uint32_t evtcode,
uint32_t param );
/**
* @brief Stores a Kernel Service call event with an Object handle and a numeric parameter
*
* @param[in] evtcode Event code
* @param[in] objectClass Object class
* @param[in] objectNumber Object handle
* @param[in] param Parameter
*/
void prvTraceStoreKernelCallWithParam( uint32_t evtcode,
traceObjectClass objectClass,
uint32_t objectNumber,
uint32_t param );
#else /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */
#define prvTraceStoreKernelCall( eventcode, objectClass, byteParam ) {}
#define prvTraceStoreKernelCallWithNumericParamOnly( evtcode, param ) {}
#define prvTraceStoreKernelCallWithParam( evtcode, objectClass, objectNumber, param ) {}
#endif /* if ( TRC_CFG_SCHEDULING_ONLY == 0 ) */
/**
* @brief Flags a task instance as finished
*
* @param[in] handle Task handle
*/
void prvTraceSetTaskInstanceFinished( traceHandle handle );
/**
* @brief Set priority
*
* @param[in] objectclass Object class
* @param[in] id Object handle
* @param[in] value Value
*/
void prvTraceSetPriorityProperty( uint8_t objectclass,
traceHandle id,
uint8_t value );
/**
* @brief Get priority
*
* @param[in] objectclass Object class
* @param[in] id Object handle
*
* @return uint8_t Value
*/
uint8_t prvTraceGetPriorityProperty( uint8_t objectclass,
traceHandle id );
/**
* @brief Set object state
*
* @param[in] objectclass Object class
* @param[in] id Object handle
* @param[in] value Value
*/
void prvTraceSetObjectState( uint8_t objectclass,
traceHandle id,
uint8_t value );
/**
* @brief Mark object as used
*
* @param[in] objectclass Object class
* @param[in] handle Object handle
*/
void prvMarkObjectAsUsed( traceObjectClass objectclass,
traceHandle handle );
/**
* @brief Stores the name of an object because it is being deleted
*
* @param[in] evtcode Event code
* @param[in] handle Object handle
* @param[in] objectclass Object class
*/
void prvTraceStoreObjectNameOnCloseEvent( uint8_t evtcode,
traceHandle handle,
traceObjectClass objectclass );
/**
* @brief Stores the property of an object because it is being deleted
*
* @param[in] evtcode Event code
* @param[in] handle Object handle
* @param[in] objectclass Object class
*/
void prvTraceStoreObjectPropertiesOnCloseEvent( uint8_t evtcode,
traceHandle handle,
traceObjectClass objectclass );
/* Internal constants for task state */
#define TASK_STATE_INSTANCE_NOT_ACTIVE 0
#define TASK_STATE_INSTANCE_ACTIVE 1
#if ( TRC_CFG_INCLUDE_ISR_TRACING == 0 )
#undef vTraceSetISRProperties
#define vTraceSetISRProperties( handle, name, priority ) ( void ) ( handle ), ( void ) ( name ), ( void ) ( priority ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
#undef vTraceStoreISRBegin
#define vTraceStoreISRBegin( x ) ( void ) ( x )
#undef vTraceStoreISREnd
#define vTraceStoreISREnd( x ) ( void ) ( x )
#undef xTraceSetISRProperties
#define xTraceSetISRProperties( name, priority ) ( ( void ) ( name ), ( void ) ( priority ), ( traceHandle ) 0 ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/
/**
* @brief
*
* Returns a pointer to the recorder data structure. Use this together with
* uiTraceGetTraceBufferSize if you wish to implement an own store/upload
* solution, e.g., in case a debugger connection is not available for uploading
* the data.
*
* @return void* Buffer pointer
*/
void * xTraceGetTraceBuffer( void );
/**
* @brief
*
* Gets the size of the recorder data structure. For use together with
* xTraceGetTraceBuffer if you wish to implement an own store/upload solution,
* e.g., in case a debugger connection is not available for uploading the data.
*
* @return uint32_t Buffer size
*/
uint32_t uiTraceGetTraceBufferSize( void );
#if ( TRC_CFG_SCHEDULING_ONLY == 1 )
#undef TRC_CFG_INCLUDE_USER_EVENTS
#define TRC_CFG_INCLUDE_USER_EVENTS 0
#endif /*(TRC_CFG_SCHEDULING_ONLY == 1)*/
#if ( ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 )
/**
* @brief Register a channel and fixed format string for use with the separate User Event Buffer functions
*
* @param[in] channel Channel name handle
* @param[in] formatStr Format string that will be used for all events on this channel
*
* @return traceUBChannel Channel handle
*/
traceUBChannel xTraceRegisterUBChannel( TraceStringHandle_t channel,
TraceStringHandle_t formatStr );
/**
* @brief Creates a User Event using the channel, previously set format string and data parameters
*
* @param[in] channel Channel
* @param[in] ...
*/
void vTraceUBData( traceUBChannel channel,
... );
/**
* @brief Creates a User Event using the channel and previously set string
*
* @param[in] channel Channel
*/
void vTraceUBEvent( traceUBChannel channel );
#else /* if ( ( TRC_CFG_INCLUDE_USER_EVENTS == 1 ) && ( TRC_CFG_SCHEDULING_ONLY == 0 ) ) && ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 ) */
#define xTraceRegisterChannelFormat( eventLabel, formatStr ) ( ( void ) ( eventLabel ), ( void ) ( formatStr ), 0 )
#define vTraceUBData( label, ... ) ( void ) ( label )
#endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/
#define NEventCodes 0x100
/* Our local critical sections for the recorder */
#define trcCRITICAL_SECTION_BEGIN() { TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++; }
#define trcCRITICAL_SECTION_END() { recorder_busy--; TRACE_EXIT_CRITICAL_SECTION(); }
#if ( TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M )
#define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY TRACE_ALLOC_CRITICAL_SECTION
#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END
#else
#define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY() {}
#define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++;
#define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--;
#endif
/**
* @brief Object handle stack struct.
*
* This data-structure is used to provide a mechanism for 1-byte trace object
* handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer)
* when storing a reference to an object. This allows for up to 255 objects of
* each object class active at any given moment. There can be more "historic"
* objects, that have been deleted - that number is only limited by the size of
* the symbol table.
*
* Note that handle zero (0) is not used, it is a code for an invalid handle.
*
* This data structure keeps track of the FREE handles, not the handles in use.
* This data structure contains one stack per object class. When a handle is
* allocated to an object, the next free handle is popped from the stack. When
* a handle is released (on object delete), it is pushed back on the stack.
* Note that there is no initialization code that pushed the free handles
* initially, that is not necessary due to the following optimization:
*
* The stack of handles (objectHandles) is initially all zeros. Since zero
* is not a valid handle, that is a signal of additional handles needed.
* If a zero is received when popping a new handle, it is replaced by the
* index of the popped handle instead.
*/
typedef struct
{
uint16_t indexOfNextAvailableHandle[ TRACE_NCLASSES ]; /**< For each object class, the index of the next handle to allocate */
uint16_t lowestIndexOfClass[ TRACE_NCLASSES ]; /**< The lowest index of this class (constant) */
uint16_t highestIndexOfClass[ TRACE_NCLASSES ]; /**< The highest index of this class (constant) */
uint16_t handleCountWaterMarksOfClass[ TRACE_NCLASSES ]; /**< The highest use count for this class (for statistics) */
traceHandle objectHandles[ TRACE_KERNEL_OBJECT_COUNT ]; /**< The free object handles - a set of stacks within this array */
} objectHandleStackType;
extern objectHandleStackType objectHandleStacks;
/**
* @brief Object property table struct
*
* The Object Table contains name and other properties of the objects (tasks,
* queues, mutexes, etc). The below data structures defines the properties of
* each object class and are used to cast the byte buffer into a cleaner format.
*
* The values in the object table are continuously overwritten and always
* represent the current state. If a property is changed during runtime, the OLD
* value should be stored in the trace buffer, not the new value (since the new
* value is found in the Object Property Table).
*
* For close events this mechanism is the old names are stored in the symbol
* table), for "priority set" (the old priority is stored in the event data)
* and for "isActive", where the value decides if the task switch event type
* should be "new" or "resume".
*/
typedef struct
{
/* = NCLASSES */
uint32_t NumberOfObjectClasses; /**< */
uint32_t ObjectPropertyTableSizeInBytes; /**< */
/* This is used to calculate the index in the dynamic object table
* (handle - 1 - nofStaticObjects = index)*/
#if ( TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1 )
traceHandle NumberOfObjectsPerClass[ 2 * ( ( TRACE_NCLASSES + 1 ) / 2 ) ]; /** */
#else
traceHandle NumberOfObjectsPerClass[ 4 * ( ( TRACE_NCLASSES + 3 ) / 4 ) ]; /** */
#endif
/* Allocation size rounded up to the closest multiple of 4 */
uint8_t NameLengthPerClass[ 4 * ( ( TRACE_NCLASSES + 3 ) / 4 ) ]; /**< */
/* Allocation size rounded up to the closest multiple of 2 */
uint8_t TotalPropertyBytesPerClass[ 4 * ( ( TRACE_NCLASSES + 3 ) / 4 ) ]; /**< */
/* */
uint16_t StartIndexOfClass[ 2 * ( ( TRACE_NCLASSES + 1 ) / 2 ) ]; /**< */
/* The actual handles issued, should be Initiated to all zeros */
uint8_t objbytes[ 4 * ( ( TRACE_OBJECT_TABLE_SIZE + 3 ) / 4 ) ]; /**< */
} ObjectPropertyTableType;
/**
* @brief Symbol table structure
*/
typedef struct
{
/* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */
uint32_t symTableSize; /**< */
/* Entry 0 is reserved. Any reference to entry 0 implies NULL*/
uint32_t nextFreeSymbolIndex; /**< */
/* Size rounded up to closest multiple of 4, to avoid alignment issues*/
uint8_t symbytes[ 4 * ( ( ( TRC_CFG_SYMBOL_TABLE_SIZE ) + 3 ) / 4 ) ]; /**< */
/* Used for lookups - Up to 64 linked lists within the symbol table
* connecting all entries with the same 6 bit checksum.
* This field holds the current list heads. Should be initiated to zeros */
uint16_t latestEntryOfChecksum[ 64 ]; /**< */
} symbolTableType;
/*******************************************************************************
* The data structures of the different events, all 4 bytes long
******************************************************************************/
typedef struct
{
uint8_t type;
uint8_t objHandle;
uint16_t dts; /* differential timestamp - time since last event */
} TSEvent, TREvent;
typedef struct
{
uint8_t type;
uint8_t dummy;
uint16_t dts; /* differential timestamp - time since last event */
} LPEvent;
typedef struct
{
uint8_t type;
uint8_t objHandle;
uint16_t dts; /* differential timestamp - time since last event */
} KernelCall;
typedef struct
{
uint8_t type;
uint8_t objHandle;
uint8_t param;
uint8_t dts; /* differential timestamp - time since last event */
} KernelCallWithParamAndHandle;
typedef struct
{
uint8_t type;
uint8_t dts; /* differential timestamp - time since last event */
uint16_t param;
} KernelCallWithParam16;
typedef struct
{
uint8_t type;
uint8_t objHandle; /* the handle of the closed object */
uint16_t symbolIndex; /* the name of the closed object */
} ObjCloseNameEvent;
typedef struct
{
uint8_t type;
uint8_t arg1;
uint8_t arg2;
uint8_t arg3;
} ObjClosePropEvent;
typedef struct
{
uint8_t type;
uint8_t unused1;
uint8_t unused2;
uint8_t dts;
} TaskInstanceStatusEvent;
typedef struct
{
uint8_t type;
uint8_t dts;
uint16_t payload; /* the name of the user event */
} UserEvent;
typedef struct
{
uint8_t type;
/* 8 bits extra for storing DTS, if it does not fit in ordinary event
* (this one is always MSB if used) */
uint8_t xts_8;
/* 16 bits extra for storing DTS, if it does not fit in ordinary event. */
uint16_t xts_16;
} XTSEvent;
typedef struct
{
uint8_t type;
uint8_t xps_8;
uint16_t xps_16;
} XPSEvent;
typedef struct
{
uint8_t type;
uint8_t dts;
uint16_t size;
} MemEventSize;
typedef struct
{
uint8_t type;
uint8_t addr_high;
uint16_t addr_low;
} MemEventAddr;
/*******************************************************************************
* The separate user event buffer structure. Can be enabled in trcConfig.h.
******************************************************************************/
#if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 )
typedef struct
{
TraceStringHandle_t name;
TraceStringHandle_t defaultFormat;
} ChannelFormatPair;
typedef struct
{
uint16_t bufferID;
uint16_t version;
uint32_t wraparoundCounter;
uint32_t numberOfSlots;
uint32_t nextSlotToWrite;
uint8_t numberOfChannels;
uint8_t padding1;
uint8_t padding2;
uint8_t padding3;
ChannelFormatPair channels[ ( TRC_CFG_UB_CHANNELS ) + 1 ];
uint8_t channelBuffer[ ( ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) + 3 ) & 0xFFFFFFFC ]; /* 1 byte per slot, with padding for 4 byte alignment */
uint8_t dataBuffer[ ( TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE ) * 4 ]; /* 4 bytes per slot */
} UserEventBuffer;
#endif /* (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) */
/*******************************************************************************
* The main data structure, read by Tracealyzer from the RAM dump
******************************************************************************/
typedef struct
{
volatile uint8_t startmarker0; /* Volatile is important, see init code. */
volatile uint8_t startmarker1;
volatile uint8_t startmarker2;
volatile uint8_t startmarker3;
volatile uint8_t startmarker4;
volatile uint8_t startmarker5;
volatile uint8_t startmarker6;
volatile uint8_t startmarker7;
volatile uint8_t startmarker8;
volatile uint8_t startmarker9;
volatile uint8_t startmarker10;
volatile uint8_t startmarker11;
/* Used to determine Kernel and Endianess */
uint16_t version;
/* Currently 7 */
uint8_t minor_version;
/* This should be 0 if lower IRQ priority values implies higher priority
* levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
* if higher IRQ priority values means higher priority, this should be 1. */
uint8_t irq_priority_order;
/* sizeof(RecorderDataType) - just for control */
uint32_t filesize;
/* Current number of events recorded */
uint32_t numEvents;
/* The buffer size, in number of event records */
uint32_t maxEvents;
/* The event buffer index, where to write the next event */
uint32_t nextFreeIndex;
/* 1 if the buffer is full, 0 otherwise */
uint32_t bufferIsFull;
/* The frequency of the clock/timer/counter used as time base */
uint32_t frequency;
/* The absolute timestamp of the last stored event, in the native
* timebase, modulo frequency! */
uint32_t absTimeLastEvent;
/* The number of seconds in total - lasts for 136 years */
uint32_t absTimeLastEventSecond;
/* 1 if the recorder has been started, 0 if not yet started or stopped.
* This is a 32 bit variable due to alignment issues. */
uint32_t recorderActive;
/* If > 0, tells the maximum time between two traced ISRs that execute
* back-to-back. If the time between vTraceStoreISREnd and a directly
* following vTraceISRBegin is above isrTailchainingThreshold, we assume a
* return to the previous context in between the ISRs, otherwise we assume
* the have executed back-to-back and don't show any fragment of the previous
* context in between. */
uint32_t isrTailchainingThreshold;
/* The maximum amount of heap memory that was allocated */
uint32_t heapMemMaxUsage;
/* The amount of heap memory used */
uint32_t heapMemUsage;
/* 0xF0F0F0F0 - for control only */
int32_t debugMarker0;
/* Set to value of TRC_CFG_USE_16BIT_OBJECT_HANDLES */
uint32_t isUsing16bitHandles;
/* The Object Property Table holds information about currently active
* tasks, queues, and other recorded objects. This is updated on each
* create call and includes object name and other properties. */
ObjectPropertyTableType ObjectPropertyTable;
/* 0xF1F1F1F1 - for control only */
int32_t debugMarker1;
/* The Symbol Table stores strings for User Events and is also used to
* store names of deleted objects, which still may be in the trace but no
* longer are available. */
symbolTableType SymbolTable;
/* For inclusion of float support, and for endian detection of floats.
* The value should be (float)1 or (uint32_t)0 */
#if ( TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1 )
float exampleFloatEncoding;
#else
uint32_t exampleFloatEncoding;
#endif
/* This is non-zero if an internal error occurred in the recorder, e.g., if
* one of the Nxxx constants was too small. The systemInfo string will then
* contain an error message that is displayed when attempting to view the
* trace file. */
uint32_t internalErrorOccurred;
/* 0xF2F2F2F2 - for control only */
int32_t debugMarker2;
/* Error messages from the recorder. */
char systemInfo[ 80 ];
/* 0xF3F3F3F3 - for control only */
int32_t debugMarker3;
/* The event data, in 4-byte records */
uint8_t eventData[ ( TRC_CFG_EVENT_BUFFER_SIZE ) * 4 ];
#if ( TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1 )
UserEventBuffer userEventBuffer;
#endif
/* This should always be 0 */
uint32_t endOfSecondaryBlocks;
uint8_t endmarker0;
uint8_t endmarker1;
uint8_t endmarker2;
uint8_t endmarker3;
uint8_t endmarker4;
uint8_t endmarker5;
uint8_t endmarker6;
uint8_t endmarker7;
uint8_t endmarker8;
uint8_t endmarker9;
uint8_t endmarker10;
uint8_t endmarker11;
} RecorderDataType;
extern RecorderDataType * RecorderDataPtr;
/* Internal functions */
/**
* @brief Signals a trace error
*
* @param[in] msg Message
*/
void prvTraceError( const char * msg );
/**
* @brief
*
* Returns the current time based on the HWTC macros which provide a hardware
* isolation layer towards the hardware timer/counter.
*
* The HWTC macros and prvTracePortGetTimeStamp is the main porting issue
* or the trace recorder library. Typically you should not need to change
* the code of prvTracePortGetTimeStamp if using the HWTC macros.
*
* @param[out] puiTimestamp Timestamp
*/
void prvTracePortGetTimeStamp( uint32_t * puiTimestamp );
/**
* @brief Reserve an object handle
*
* @param[in] objectclass Object class
*
* @return traceHandle
*/
traceHandle prvTraceGetObjectHandle( traceObjectClass objectclass );
/**
* @brief Free an object handle
*
* @param[in] objectclass Object class
* @param[in] handle Handle
*/
void prvTraceFreeObjectHandle( traceObjectClass objectclass,
traceHandle handle );
/* Private function. Use the public functions in trcKernelPort.h */
/**
* @brief Set the object name
*
* @param[in] objectclass Object class
* @param[in] handle Handle
* @param[in] name Name
*/
void prvTraceSetObjectName( traceObjectClass objectclass,
traceHandle handle,
const char * name );
/* Internal macros */
#define TRACE_PROPERTY_NAME_GET( objectclass, objecthandle ) \
( const char * ) ( &RecorderDataPtr->ObjectPropertyTable.objbytes \
[ uiIndexOfObject( objecthandle, objectclass ) ] )
#define TRACE_PROPERTY_OBJECT_STATE( objectclass, handle ) \
RecorderDataPtr->ObjectPropertyTable.objbytes[ uiIndexOfObject( handle, objectclass ) \
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] ]
#define TRACE_PROPERTY_ACTOR_PRIORITY( objectclass, handle ) \
RecorderDataPtr->ObjectPropertyTable.objbytes[ uiIndexOfObject( handle, objectclass ) \
+ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ] + 1 ]
/* DEBUG ASSERTS */
#if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0
#define TRACE_ASSERT( eval, msg, defRetVal ) \
if( !( eval ) ) \
{ \
prvTraceError( "TRACE_ASSERT: " msg ); \
return defRetVal; \
}
#else
#define TRACE_ASSERT( eval, msg, defRetVal )
#endif
typedef RecorderDataType TraceRecorderDataBuffer_t;
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/
#if ( TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING )
#ifndef TRC_EXTERNAL_BUFFERS
#define TRC_EXTERNAL_BUFFERS 0
#endif
typedef struct TraceRecorderData
{
uint32_t uiSessionCounter;
uint32_t uiRecorderEnabled;
uint32_t uiTraceSystemState;
TraceAssertBuffer_t xAssertBuffer;
#if ( TRC_EXTERNAL_BUFFERS == 0 )
TraceHeaderBuffer_t xHeaderBuffer;
TraceEntryTableBuffer_t xEntryTableBuffer;
TraceTimestampBuffer_t xTimestampBuffer;
#endif
TraceStreamPortBuffer_t xStreamPortBuffer;
TraceStaticBufferBuffer_t xStaticBufferBuffer;
TraceEventDataBuffer_t xEventDataBuffer;
TracePrintBuffer_t xPrintBuffer;
TraceErrorBuffer_t xErrorBuffer;
TraceISRInfoBuffer_t xISRInfoBuffer;
TraceKernelPortDataBuffer_t xKernelPortBuffer;
TraceTaskInfoBuffer_t xTaskInfoBuffer;
TraceStackMonitorBuffer_t xStackMonitorBuffer;
TraceDiagnosticsBuffer_t xDiagnosticsBuffer;
} TraceRecorderData_t;
extern TraceRecorderData_t * pxTraceRecorderData;
extern uint32_t RecorderInitialized;
#define TRC_RECORDER_DATA_BUFFER_SIZE ( sizeof( TraceRecorderData_t ) )
typedef struct TraceRecorderDataBuffer
{
uint8_t buffer[ ( TRC_RECORDER_DATA_BUFFER_SIZE ) ];
} TraceRecorderDataBuffer_t;
/**
* @brief Initializes the header data
*
* @param[in] pxBuffer Pointer to header buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceHeaderInitialize( TraceHeaderBuffer_t * pxBuffer );
/**
* @brief Query if recorder is enabled
*
* @retval 1 Recorder enabled
* @retval 0 Recorder not enabled
*/
#define xTraceIsRecorderEnabled() ( xTraceIsRecorderInitialized() & pxTraceRecorderData->uiRecorderEnabled )
/**
* @brief Query if recorder initialized
*
* @retval 1 Recorder initialized
* @retval 0 Recorder not initialized
*/
#define xTraceIsRecorderInitialized() xTraceIsComponentInitialized( TRC_RECORDER_COMPONENT_CORE )
/**
* @brief Flag component as initialized
*
* @param[in] uiComponentBit Component bit
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceSetComponentInitialized( uiComponentBit ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( RecorderInitialized |= ( uiComponentBit ), TRC_SUCCESS )
/**
* @brief Query if component is initialized
*
* @param[in] uiComponentBit Component bit
*
* @retval 1 Component initialized
* @retval 0 Component not initialized
*/
#define xTraceIsComponentInitialized( uiComponentBit ) ( ( RecorderInitialized & ( uiComponentBit ) ) ? 1 : 0 )
/**
* @brief Set the trace state
*
* @param[in] uiState State
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceStateSet( uiState ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( pxTraceRecorderData->uiTraceSystemState = ( uiState ), TRC_SUCCESS )
/**
* @brief Query the trace state
*
* @param[out] puiState State
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
#define xTraceStateGet( puiState ) TRC_COMMA_EXPR_TO_STATEMENT_EXPR_2( *( puiState ) = pxTraceRecorderData->uiTraceSystemState, TRC_SUCCESS )
/**
* @brief Call this function periodically
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceTzCtrl( void );
/******************************************************************************/
/*** INTERNAL STREAMING FUNCTIONS *********************************************/
/******************************************************************************/
/**
* @brief Stores an event without parameters
*
* @param[in] _eventID Event id
*/
#define prvTraceStoreEvent_None( _eventID ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, 0, &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Stores an event with a handle parameter
*
* @param[in] _eventID Event id
* @param[in] _handle Handle
*/
#define prvTraceStoreEvent_Handle( _eventID, _handle ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, sizeof( void * ), &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventAddPointer( _xEventHandle, ( void * ) ( _handle ) ); \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Stores an event with one 32-bit parameter
*
* @param[in] _eventID Event id
* @param[in] _param1 Param
*/
#define prvTraceStoreEvent_Param( _eventID, _param1 ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Stores an event with a handle and one 32-bit parameter
*
* @param[in] _eventID Event id
* @param[in] _handle Handle
* @param[in] _param1 Param
*/
#define prvTraceStoreEvent_HandleParam( _eventID, _handle, _param1 ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, sizeof( void * ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventAddPointer( _xEventHandle, ( void * ) ( _handle ) ); \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Stores an event with two 32-bit parameters
*
* @param[in] _eventID Event id
* @param[in] _param1 Param 1
* @param[in] _param2 Param 2
*/
#define prvTraceStoreEvent_ParamParam( _eventID, _param1, _param2 ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, sizeof( uint32_t ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param2 ) ); \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Stores an event with a handle and two 32-bit parameters
*
* @param[in] _eventID Event id
* @param[in] _handle Handle
* @param[in] _param1 Param 1
* @param[in] _param2 Param 2
*/
#define prvTraceStoreEvent_HandleParamParam( _eventID, _handle, _param1, _param2 ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, sizeof( void * ) + sizeof( uint32_t ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventAddPointer( _xEventHandle, ( void * ) ( _handle ) ); \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param2 ) ); \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Stores an event with three 32-bit parameters
*
* @param[in] _eventID Event id
* @param[in] _param1 Param 1
* @param[in] _param2 Param 2
* @param[in] _param3 Param 3
*/
#define prvTraceStoreEvent_ParamParamParam( _eventID, _param1, _param2, _param3 ) \
{ \
TraceEventHandle_t _xEventHandle = 0; \
if( xTraceEventBegin( _eventID, sizeof( uint32_t ) + sizeof( uint32_t ) + sizeof( uint32_t ), &_xEventHandle ) == TRC_SUCCESS ) \
{ \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param1 ) ); \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param2 ) ); \
xTraceEventAdd32( _xEventHandle, ( uint32_t ) ( _param3 ) ); \
xTraceEventEnd( _xEventHandle ); \
} \
}
/**
* @brief Snapshot mode only. Trace stop hook.
*
* @param[in] x
*/
#define vTraceSetStopHook( x ) ( void ) ( x )
/**
* @brief Snapshot mode only. Initialize timestamps.
*/
#define vTraceInitTimestamps()
#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/
#if ( TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM )
/**
* @brief Set the recorder data buffer
*
* @param[in] pxBuffer Pointer to the recorder data buffer
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceSetBuffer( TraceRecorderDataBuffer_t * pxBuffer );
#else
#define xTraceSetBuffer( p ) ( TRC_SUCCESS )
#endif
/**
* @brief Retrieve the event buffer and event buffer size
*
* @param[out] ppvBuffer Pointer where event buffer pointer will be written
* @param[out] puiSize Event buffer size
*
* @retval TRC_FAIL Failure
* @retval TRC_SUCCESS Success
*/
traceResult xTraceGetEventBuffer( void ** ppvBuffer,
TraceUnsignedBaseType_t * puiSize );
#else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */
#define xTraceInitialize() ( TRC_SUCCESS )
#define xTraceEnable( x ) ( ( void ) ( x ), TRC_SUCCESS )
#define xTraceDisable() ( TRC_SUCCESS )
#define xTraceStringRegister( x, y ) ( ( void ) ( x ), ( void ) y, TRC_SUCCESS ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
#define xTracePrint( chn, ... ) ( ( void ) ( chn ), TRC_SUCCESS )
#define xTracePrintF( chn, fmt, ... ) ( ( void ) ( chn ), ( void ) ( fmt ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
#define xTraceVPrintF( chn, formatStr, vl ) ( ( void ) ( chn ), ( void ) ( formatStr ), ( void ) ( vl ), TRC_SUCCESS ) /* Comma operator is used to avoid "unused variable" compiler warnings in a single statement */
#define xTraceTaskInstanceFinishedNow()
#define xTraceTaskInstanceFinishedNext()
#define vTraceStoreISRBegin( x ) ( void ) ( x )
#define vTraceStoreISREnd( x ) ( void ) ( x )
#define xTraceSetISRProperties( a, b ) ( ( void ) ( a ), ( void ) ( b ), ( traceHandle ) 0 ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
#define xTraceRegisterChannelFormat( eventLabel, formatStr ) ( ( void ) ( eventLabel ), ( void ) ( formatStr ), 0 ) /* Comma operator in parenthesis is used to avoid "unused variable" compiler warnings and return 0 in a single statement */
#define vTraceUBData( label, ... ) ( void ) ( label )
#define vTraceSetFilterGroup( x ) ( void ) ( x )
#define vTraceSetFilterMask( x ) ( void ) ( x )
#define prvTraceSetReadyEventsEnabled( status ) ( void ) ( status )
#define vTraceExcludeTask( handle ) ( void ) ( handle )
#define vTraceConsoleChannelPrintF( fmt, ... ) ( void ) ( fmt )
#ifndef TRC_ALLOC_CUSTOM_BUFFER
#define TRC_ALLOC_CUSTOM_BUFFER( bufname )
#endif
#define xTraceIsRecorderEnabled() ( 0 )
#define xTraceIsRecorderInitialized() ( 0 )
#define xTraceSetBuffer( p ) ( TRC_SUCCESS )
#define xTraceGetEventBuffer( p ) ( TRC_FAIL )
#define vTraceSetStopHook( x ) ( void ) ( x )
#define TraceRecorderDataBuffer_t uint32_t
#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */
/**
* @deprecated Backwards compatibility. Use xTraceInitialize instead.
*/
#define vTraceInitialize ( void ) xTraceInitialize
/**
* @deprecated Backwards compatibility. Use xTraceEnable instead.
*/
#define vTraceEnable ( void ) xTraceEnable
/**
* @deprecated Backwards compatibility. Use xTraceDisable instead.
*/
#define vTraceStop ( void ) xTraceDisable
/**
* @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNow instead.
*/
#define vTraceInstanceFinishedNow ( void ) xTraceTaskInstanceFinishedNow
/**
* @deprecated Backwards compatibility. Use xTraceTaskInstanceFinishedNext instead.
*/
#define vTraceInstanceFinishedNext ( void ) xTraceTaskInstanceFinishedNext
/**
* @deprecated Backwards compatibility. Use xTracePrintF instead.
*/
#define vTracePrintF ( void ) xTracePrintF
/**
* @deprecated Backwards compatibility. Use xTraceVPrintF instead.
*/
#define vTraceVPrintF ( void ) xTraceVPrintF
/**
* @deprecated Backwards compatibility. Use xTracePrint instead.
*/
#define vTracePrint ( void ) xTracePrint
/**
* @deprecated Backwards compatibility. Use xTraceSetBuffer instead.
*/
#define vTraceSetRecorderDataBuffer( pxBuffer ) xTraceSetBuffer( ( TraceRecorderDataBuffer_t * ) ( pxBuffer ) )
#ifdef __cplusplus
}
#endif
#endif /* TRC_RECORDER_H */