You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeRTOS/FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcKernelPort.c

656 lines
24 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
/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */
static portTASK_FUNCTION(TzCtrl, pvParameters);
#endif
#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
#endif
TraceHeapHandle_t xTraceKernelPortGetSystemHeapHandle(void)
{
return pxKernelPortData->xSystemHeapHandle;
}
#endif
#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
uint32_t prvTraceGetQueueNumber(void* handle)
{
return (uint32_t)uxQueueGetQueueNumber(handle);
}
#endif
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_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_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
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
#endif
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
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
#endif