mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-08-19 09:38:32 -04:00
Update to latest FreeRTOS+Trace recorder code.
This commit is contained in:
parent
f9d0a153b4
commit
f928b0e296
17 changed files with 3283 additions and 3136 deletions
|
@ -1,106 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* FreeRTOS+Trace v2.3.0 Recorder Library
|
||||
* Tracealyzer v2.4.1 Recorder Library
|
||||
* Percepio AB, www.percepio.com
|
||||
*
|
||||
* trcKernel.c
|
||||
*
|
||||
* Functions for integration of the trace recorder library in the FreeRTOS
|
||||
* kernel (requires FreeRTOS v7.1.0 or later).
|
||||
*
|
||||
* Functions used by trcKernelHooks.h.
|
||||
*
|
||||
* Terms of Use
|
||||
* This software is copyright Percepio AB. The recorder library is free for
|
||||
* use together with Percepio products. You may distribute the recorder library
|
||||
* in its original form, including modifications in trcPort.c and trcPort.h
|
||||
* in its original form, including modifications in trcHardwarePort.c/.h
|
||||
* given that these modification are clearly marked as your own modifications
|
||||
* and documented in the initial comment section of these source files.
|
||||
* This software is the intellectual property of Percepio AB and may not be
|
||||
* sold or in other ways commercially redistributed without explicit written
|
||||
* and documented in the initial comment section of these source files.
|
||||
* This software is the intellectual property of Percepio AB and may not be
|
||||
* sold or in other ways commercially redistributed without explicit written
|
||||
* permission by Percepio AB.
|
||||
*
|
||||
* Disclaimer
|
||||
* The trace tool and recorder library is being delivered to you AS IS and
|
||||
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
|
||||
* not and cannot warrant the performance or results you may obtain by using the
|
||||
* software or documentation. Percepio AB make no warranties, express or
|
||||
* implied, as to noninfringement of third party rights, merchantability, or
|
||||
* fitness for any particular purpose. In no event will Percepio AB, its
|
||||
* technology partners, or distributors be liable to you for any consequential,
|
||||
* incidental or special damages, including any lost profits or lost savings,
|
||||
* even if a representative of Percepio AB has been advised of the possibility
|
||||
* of such damages, or for any claim by any third party. Some jurisdictions do
|
||||
* not allow the exclusion or limitation of incidental, consequential or special
|
||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
||||
* Disclaimer
|
||||
* The trace tool and recorder library is being delivered to you AS IS and
|
||||
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
|
||||
* not and cannot warrant the performance or results you may obtain by using the
|
||||
* software or documentation. Percepio AB make no warranties, express or
|
||||
* implied, as to noninfringement of third party rights, merchantability, or
|
||||
* fitness for any particular purpose. In no event will Percepio AB, its
|
||||
* technology partners, or distributors be liable to you for any consequential,
|
||||
* incidental or special damages, including any lost profits or lost savings,
|
||||
* even if a representative of Percepio AB has been advised of the possibility
|
||||
* of such damages, or for any claim by any third party. Some jurisdictions do
|
||||
* not allow the exclusion or limitation of incidental, consequential or special
|
||||
* damages, or the exclusion of implied warranties or limitations on how long an
|
||||
* implied warranty may last, so the above limitations may not apply to you.
|
||||
*
|
||||
* FreeRTOS+Trace is available as Free Edition and in two premium editions.
|
||||
* You may use the premium features during 30 days for evaluation.
|
||||
* Download FreeRTOS+Trace at http://www.percepio.com/products/downloads/
|
||||
*
|
||||
* Copyright Percepio AB, 2012.
|
||||
* Copyright Percepio AB, 2013.
|
||||
* www.percepio.com
|
||||
******************************************************************************/
|
||||
|
||||
#include "trcUser.h"
|
||||
#include "task.h"
|
||||
#include "trcKernel.h"
|
||||
|
||||
#if (configUSE_TRACE_FACILITY == 1)
|
||||
#if (USE_TRACEALYZER_RECORDER == 1)
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* TraceObjectClassTable
|
||||
* Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_).
|
||||
* This was added since we want to map both types of Mutex and both types of
|
||||
* Semaphores on common classes for all Mutexes and all Semaphores respectively.
|
||||
*
|
||||
* FreeRTOS Queue types
|
||||
* #define queueQUEUE_TYPE_BASE ( 0U ) => TRACE_CLASS_QUEUE
|
||||
* #define queueQUEUE_TYPE_MUTEX ( 1U ) => TRACE_CLASS_MUTEX
|
||||
* #define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U ) => TRACE_CLASS_SEMAPHORE
|
||||
* #define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U ) => TRACE_CLASS_SEMAPHORE
|
||||
* #define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U ) => TRACE_CLASS_MUTEX
|
||||
******************************************************************************/
|
||||
traceObjectClass TraceObjectClassTable[5] = {TRACE_CLASS_QUEUE,
|
||||
TRACE_CLASS_MUTEX,
|
||||
TRACE_CLASS_SEMAPHORE,
|
||||
TRACE_CLASS_SEMAPHORE,
|
||||
TRACE_CLASS_MUTEX };
|
||||
|
||||
/* This is defined in FreeRTOS! */
|
||||
extern volatile void * volatile pxCurrentTCB;
|
||||
#include <stdint.h>
|
||||
|
||||
/* Internal variables */
|
||||
uint8_t nISRactive = 0;
|
||||
objectHandleType handle_of_last_logged_task = 0;
|
||||
uint8_t inExcludedTask = 0;
|
||||
|
||||
static uint8_t prvTraceIsObjectExcluded(traceObjectClass, uint32_t);
|
||||
|
||||
/*******************************************************************************
|
||||
* prvTraceIsObjectExcluded
|
||||
*
|
||||
* Private function that accepts an object class and an object number and uses
|
||||
* that to determine if the object has been flagged as excluded.
|
||||
******************************************************************************/
|
||||
static uint8_t prvTraceIsObjectExcluded(traceObjectClass objectClass, uint32_t objectNumber)
|
||||
{
|
||||
switch(objectClass)
|
||||
{
|
||||
case TRACE_CLASS_QUEUE:
|
||||
return GET_QUEUE_FLAG_ISEXCLUDED(objectNumber);
|
||||
break;
|
||||
case TRACE_CLASS_SEMAPHORE:
|
||||
return GET_SEMAPHORE_FLAG_ISEXCLUDED(objectNumber);
|
||||
break;
|
||||
case TRACE_CLASS_MUTEX:
|
||||
return GET_MUTEX_FLAG_ISEXCLUDED(objectNumber);
|
||||
break;
|
||||
case TRACE_CLASS_TASK:
|
||||
return GET_TASK_FLAG_ISEXCLUDED(objectNumber);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static uint32_t prvTraceGetParam(uint32_t, uint32_t);
|
||||
|
||||
#if !defined INCLUDE_READY_EVENTS || INCLUDE_READY_EVENTS == 1
|
||||
/*******************************************************************************
|
||||
|
@ -112,79 +58,91 @@ void vTraceStoreTaskReady(objectHandleType handle)
|
|||
{
|
||||
uint16_t dts3;
|
||||
TREvent* tr;
|
||||
|
||||
TRACE_ASSERT(handle > 0 && handle <= NTask, "vTraceStoreTaskReady: Invalid value for handle", );
|
||||
|
||||
if (!GET_TASK_FLAG_ISEXCLUDED(handle))
|
||||
if (recorder_busy)
|
||||
{
|
||||
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
tr = (TREvent*)xTraceNextFreeEventBufferSlot();
|
||||
/***********************************************************************
|
||||
* This should never occur, as the tick- and kernel call ISR is on lowest
|
||||
* interrupt priority and always are disabled during the critical sections
|
||||
* of the recorder.
|
||||
***********************************************************************/
|
||||
|
||||
if (tr != NULL)
|
||||
{
|
||||
tr->type = TR_TASK_READY;
|
||||
tr->dts = dts3;
|
||||
tr->objHandle = handle;
|
||||
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
vTraceError("Recorder busy - high priority ISR using syscall? (1)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
if (!TRACE_GET_TASK_FLAG_ISEXCLUDED(handle))
|
||||
{
|
||||
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
tr = (TREvent*)xTraceNextFreeEventBufferSlot();
|
||||
|
||||
if (tr != NULL)
|
||||
{
|
||||
tr->type = DIV_TASK_READY;
|
||||
tr->dts = dts3;
|
||||
tr->objHandle = handle;
|
||||
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* vTraceStoreKernelCall
|
||||
*
|
||||
* This is the main integration point for storing FreeRTOS kernel calls, and
|
||||
* is called by the hooks in FreeRTOS.h (see trcKernel.h for event codes).
|
||||
* This is the main integration point for storing kernel calls, and
|
||||
* is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes).
|
||||
******************************************************************************/
|
||||
void vTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber)
|
||||
{
|
||||
KernelCall * kse;
|
||||
uint16_t dts1;
|
||||
|
||||
TRACE_ASSERT(ecode < 0xFF, "vTraceStoreKernelCall: ecode >= 0xFF", );
|
||||
TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", );
|
||||
TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCall: Invalid value for objectNumber", );
|
||||
|
||||
if (recorder_busy)
|
||||
{
|
||||
/*************************************************************************
|
||||
* This may occur if a high-priority ISR is illegally using a system call,
|
||||
* or creates a user event.
|
||||
* Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls
|
||||
* or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).
|
||||
*************************************************************************/
|
||||
|
||||
vTraceError("Recorder busy - high priority ISR using syscall? (2)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle_of_last_logged_task == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (RecorderDataPtr->recorderActive)
|
||||
{
|
||||
|
||||
|
||||
/* If it is an ISR or NOT an excluded task, this kernel call will be stored in the trace */
|
||||
if (nISRactive || !inExcludedTask)
|
||||
{
|
||||
/* Make sure ISRs never change the IFE flags of tasks */
|
||||
if (!nISRactive)
|
||||
{
|
||||
/* This checks if this is the first kernel call after a call to
|
||||
vTraceTaskInstanceIsFinished. In that case, calls to this kernel service
|
||||
with this specific kernel object become the "instance finish event"
|
||||
(IFE) of the calling task.*/
|
||||
if (GET_TASK_FLAG_MARKIFE(handle_of_last_logged_task))
|
||||
{
|
||||
/* Reset the flag - this has been handled now */
|
||||
CLEAR_TASK_FLAG_MARKIFE(handle_of_last_logged_task);
|
||||
|
||||
/* Store the kernel service tagged as instance finished event */
|
||||
PROPERTY_TASK_IFE_SERVICECODE(handle_of_last_logged_task) =
|
||||
(uint8_t)ecode;
|
||||
|
||||
/* Store the handle of the specific kernel object */
|
||||
PROPERTY_TASK_IFE_OBJHANDLE(handle_of_last_logged_task) =
|
||||
(objectHandleType)objectNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the referenced object or the event code is excluded */
|
||||
if (!prvTraceIsObjectExcluded(objectClass, objectNumber) && !GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
|
||||
if (!uiTraceIsObjectExcluded(objectClass, objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(ecode))
|
||||
{
|
||||
trcCRITICAL_SECTION_BEGIN();
|
||||
dts1 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
{
|
||||
kse = (KernelCall*) xTraceNextFreeEventBufferSlot();
|
||||
if (kse != NULL)
|
||||
{
|
||||
|
@ -214,17 +172,34 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
|||
KernelCallWithParamAndHandle * kse;
|
||||
uint8_t dts2;
|
||||
|
||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task &&
|
||||
TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCall: evtcode >= 0xFF", );
|
||||
TRACE_ASSERT(objectClass < TRACE_NCLASSES, "vTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", );
|
||||
TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "vTraceStoreKernelCallWithParam: Invalid value for objectNumber", );
|
||||
|
||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task &&
|
||||
(! inExcludedTask || nISRactive))
|
||||
{
|
||||
if (recorder_busy)
|
||||
{
|
||||
/*************************************************************************
|
||||
* This may occur if a high-priority ISR is illegally using a system call,
|
||||
* or creates a user event.
|
||||
* Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls
|
||||
* or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).
|
||||
*************************************************************************/
|
||||
|
||||
vTraceError("Recorder busy - high priority ISR using syscall? (3)");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the referenced object or the event code is excluded */
|
||||
if (!prvTraceIsObjectExcluded(objectClass, objectNumber) && !GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
||||
if (!uiTraceIsObjectExcluded(objectClass, objectNumber) && !TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
||||
{
|
||||
trcCRITICAL_SECTION_BEGIN();
|
||||
dts2 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
{
|
||||
kse = (KernelCallWithParamAndHandle*) xTraceNextFreeEventBufferSlot();
|
||||
if (kse != NULL)
|
||||
{
|
||||
|
@ -232,7 +207,7 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
|||
kse->type = (uint8_t)evtcode;
|
||||
kse->objHandle = (uint8_t)objectNumber;
|
||||
kse->param = param;
|
||||
prvTraceUpdateCounters();
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
trcCRITICAL_SECTION_END();
|
||||
|
@ -240,6 +215,35 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
|||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* prvTraceGetParam
|
||||
*
|
||||
* Used for storing extra bytes for kernel calls with numeric parameters.
|
||||
******************************************************************************/
|
||||
static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param)
|
||||
{
|
||||
XPSEvent* xps;
|
||||
|
||||
TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF, "prvTraceGetParam: Invalid value for param_max", param);
|
||||
|
||||
if (param <= param_max)
|
||||
{
|
||||
return param;
|
||||
}
|
||||
else
|
||||
{
|
||||
xps = (XPSEvent*) xTraceNextFreeEventBufferSlot();
|
||||
if (xps != NULL)
|
||||
{
|
||||
xps->type = DIV_XPS;
|
||||
xps->xps_8 = (param & (0xFF00 & ~param_max)) >> 8;
|
||||
xps->xps_16 = (param & (0xFFFF0000 & ~param_max)) >> 16;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
|
||||
return param & param_max;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* vTraceStoreKernelCallWithNumericParamOnly
|
||||
|
@ -247,124 +251,117 @@ void vTraceStoreKernelCallWithParam(uint32_t evtcode,
|
|||
* Used for storing kernel calls with numeric parameters only. This is
|
||||
* only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment.
|
||||
******************************************************************************/
|
||||
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint16_t param)
|
||||
void vTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param)
|
||||
{
|
||||
KernelCallWithParam16 * kse;
|
||||
uint8_t dts6;
|
||||
uint16_t restParam = 0;
|
||||
|
||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task
|
||||
TRACE_ASSERT(evtcode < 0xFF, "vTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", );
|
||||
|
||||
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task
|
||||
&& (! inExcludedTask || nISRactive))
|
||||
{
|
||||
/* Check if the event code is excluded */
|
||||
if (!GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
||||
if (!TRACE_GET_EVENT_CODE_FLAG_ISEXCLUDED(evtcode))
|
||||
{
|
||||
if (recorder_busy)
|
||||
{
|
||||
/*************************************************************************
|
||||
* This may occur if a high-priority ISR is illegally using a system call,
|
||||
* or creates a user event.
|
||||
* Only ISRs that are disabled by TRACE_ENTER_CRITICAL_SECTION may use system calls
|
||||
* or user events (see TRACE_MAX_SYSCALL_INTERRUPT_PRIORITY).
|
||||
*************************************************************************/
|
||||
|
||||
vTraceError("Recorder busy - high priority ISR using syscall? (4)");
|
||||
return;
|
||||
}
|
||||
|
||||
trcCRITICAL_SECTION_BEGIN();
|
||||
dts6 = (uint8_t)prvTraceGetDTS(0xFF);
|
||||
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
|
||||
if (kse != NULL)
|
||||
{
|
||||
kse->dts = dts6;
|
||||
kse->type = (uint8_t)evtcode;
|
||||
kse->param = param;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
{
|
||||
restParam = (uint16_t)prvTraceGetParam(0xFFFF, param);
|
||||
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
kse = (KernelCallWithParam16*) xTraceNextFreeEventBufferSlot();
|
||||
if (kse != NULL)
|
||||
{
|
||||
kse->dts = dts6;
|
||||
kse->type = (uint8_t)evtcode;
|
||||
kse->param = restParam;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
}
|
||||
trcCRITICAL_SECTION_END();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectHandleType handle_of_running_task = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* vTraceStoreTaskswitch
|
||||
* Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart.
|
||||
* At this point interrupts are assumed to be disabled!
|
||||
******************************************************************************/
|
||||
void vTraceStoreTaskswitch(void)
|
||||
void vTraceStoreTaskswitch(objectHandleType task_handle)
|
||||
{
|
||||
uint16_t dts3;
|
||||
TSEvent* ts;
|
||||
TSEvent* ts;
|
||||
int8_t skipEvent = 0;
|
||||
uint32_t schedulerState = 0;
|
||||
|
||||
/***************************************************************************
|
||||
This is used to detect if a high-priority ISRs is illegally using the
|
||||
recorder ISR trace functions (vTraceStoreISRBegin and ...End) while the
|
||||
|
||||
TRACE_ASSERT(task_handle <= NTask, "vTraceStoreTaskswitch: Invalid value for task_handle", );
|
||||
|
||||
/***************************************************************************
|
||||
This is used to detect if a high-priority ISRs is illegally using the
|
||||
recorder ISR trace functions (vTraceStoreISRBegin and ...End) while the
|
||||
recorder is busy with a task-level event or lower priority ISR event.
|
||||
|
||||
If this is detected, it triggers a call to vTraceError with the error
|
||||
|
||||
If this is detected, it triggers a call to vTraceError with the error
|
||||
"Illegal call to vTraceStoreISRBegin/End". If you get this error, it means
|
||||
that the macro taskENTER_CRITICAL does not disable this ISR, as required.
|
||||
You can solve this by adjusting the value of the FreeRTOS constant
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY, which is defined in FreeRTOSConfig.h
|
||||
that the macro trcCRITICAL_SECTION_BEGIN does not disable this ISR, as required.
|
||||
|
||||
Note: Setting recorder_busy is normally handled in our macros
|
||||
trcCRITICAL_SECTION_BEGIN and _END, but is needed explicitly in this
|
||||
function since critical sections should not be used in the context switch
|
||||
event...)
|
||||
trcCRITICAL_SECTION_BEGIN and _END, but is needed explicitly in this
|
||||
function since critical sections should not be used in the context switch
|
||||
event...)
|
||||
***************************************************************************/
|
||||
recorder_busy++;
|
||||
|
||||
schedulerState = xTaskGetSchedulerState();
|
||||
recorder_busy++;
|
||||
|
||||
if (schedulerState == 0)
|
||||
{
|
||||
/* This occurs on the very first taskswitch event, generated by
|
||||
vTraceStart and uiTraceStart if the scheduler is not yet started.
|
||||
This creates a dummy "(startup)" task entry internally in the
|
||||
recorder */
|
||||
if (handle_of_running_task == 0)
|
||||
{
|
||||
handle_of_running_task = xTraceGetObjectHandle(TRACE_CLASS_TASK);
|
||||
|
||||
vTraceSetObjectName(TRACE_CLASS_TASK,
|
||||
handle_of_running_task,
|
||||
"(startup)");
|
||||
|
||||
vTraceSetPriorityProperty(TRACE_CLASS_TASK,
|
||||
handle_of_running_task,
|
||||
0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handle_of_running_task =
|
||||
(objectHandleType)uxTaskGetTaskNumber(xTaskGetCurrentTaskHandle());
|
||||
}
|
||||
|
||||
/* Skip the event if the task has been excluded, using vTraceExcludeTask */
|
||||
if (GET_TASK_FLAG_ISEXCLUDED(handle_of_running_task))
|
||||
{
|
||||
skipEvent = 1;
|
||||
inExcludedTask = 1;
|
||||
}
|
||||
else
|
||||
inExcludedTask = 0;
|
||||
|
||||
|
||||
/* Skip the event if the same task is scheduled */
|
||||
if (handle_of_running_task == handle_of_last_logged_task)
|
||||
if (TRACE_GET_TASK_FLAG_ISEXCLUDED(task_handle))
|
||||
{
|
||||
skipEvent = 1;
|
||||
inExcludedTask = 1;
|
||||
}
|
||||
|
||||
if (! RecorderDataPtr->recorderActive)
|
||||
else
|
||||
{
|
||||
inExcludedTask = 0;
|
||||
}
|
||||
|
||||
/* Skip the event if the same task is scheduled */
|
||||
if (task_handle == handle_of_last_logged_task)
|
||||
{
|
||||
skipEvent = 1;
|
||||
}
|
||||
|
||||
|
||||
if (!RecorderDataPtr->recorderActive)
|
||||
{
|
||||
skipEvent = 1;
|
||||
}
|
||||
|
||||
/* If this event should be logged, log it! */
|
||||
if (skipEvent == 0)
|
||||
{
|
||||
if (skipEvent == 0)
|
||||
{
|
||||
dts3 = (uint16_t)prvTraceGetDTS(0xFFFF);
|
||||
|
||||
|
||||
if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */
|
||||
{
|
||||
handle_of_last_logged_task = handle_of_running_task;
|
||||
handle_of_last_logged_task = task_handle;
|
||||
ts = (TSEvent*)xTraceNextFreeEventBufferSlot();
|
||||
|
||||
if (ts != NULL)
|
||||
|
@ -382,17 +379,17 @@ void vTraceStoreTaskswitch(void)
|
|||
ts->dts = dts3;
|
||||
ts->objHandle = handle_of_last_logged_task;
|
||||
|
||||
vTraceSetObjectState(TRACE_CLASS_TASK,
|
||||
handle_of_last_logged_task,
|
||||
vTraceSetObjectState(TRACE_CLASS_TASK,
|
||||
handle_of_last_logged_task,
|
||||
TASK_STATE_INSTANCE_ACTIVE);
|
||||
|
||||
prvTraceUpdateCounters();
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See comment on recorder_busy++ above. */
|
||||
recorder_busy--;
|
||||
recorder_busy--;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -404,88 +401,102 @@ void vTraceStoreTaskswitch(void)
|
|||
* "old" one, valid up until this point.
|
||||
******************************************************************************/
|
||||
#if (INCLUDE_OBJECT_DELETE == 1)
|
||||
void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,
|
||||
void vTraceStoreObjectNameOnCloseEvent(objectHandleType handle,
|
||||
traceObjectClass objectclass)
|
||||
{
|
||||
{
|
||||
ObjCloseNameEvent * ce;
|
||||
const char * name;
|
||||
traceLabel idx;
|
||||
|
||||
name = PROPERTY_NAME_GET(objectclass, handle);
|
||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", );
|
||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceStoreObjectNameOnCloseEvent: Invalid value for handle", );
|
||||
|
||||
idx = prvTraceOpenSymbol(name, 0);
|
||||
|
||||
// Interrupt disable not necessary, already done in trcHooks.h macro
|
||||
ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();
|
||||
if (ce != NULL)
|
||||
{
|
||||
ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;
|
||||
ce->objHandle = handle;
|
||||
ce->symbolIndex = idx;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
|
||||
if (RecorderDataPtr->recorderActive)
|
||||
{
|
||||
name = TRACE_PROPERTY_NAME_GET(objectclass, handle);
|
||||
|
||||
idx = prvTraceOpenSymbol(name, 0);
|
||||
|
||||
// Interrupt disable not necessary, already done in trcHooks.h macro
|
||||
ce = (ObjCloseNameEvent*) xTraceNextFreeEventBufferSlot();
|
||||
if (ce != NULL)
|
||||
{
|
||||
ce->type = EVENTGROUP_OBJCLOSE_NAME + objectclass;
|
||||
ce->objHandle = handle;
|
||||
ce->symbolIndex = idx;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
|
||||
void vTraceStoreObjectPropertiesOnCloseEvent(objectHandleType handle,
|
||||
traceObjectClass objectclass)
|
||||
{
|
||||
ObjClosePropEvent * pe;
|
||||
|
||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", );
|
||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", );
|
||||
|
||||
if (objectclass == TRACE_CLASS_ISR)
|
||||
{
|
||||
/* ISR handles should not be closed - never called for ISR */
|
||||
return;
|
||||
}
|
||||
|
||||
// Interrupt disable not necessary, already done in trcHooks.h macro
|
||||
pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();
|
||||
if (pe != NULL)
|
||||
{
|
||||
if (objectclass == TRACE_CLASS_TASK)
|
||||
{
|
||||
pe->arg1 = PROPERTY_ACTOR_PRIORITY(objectclass, handle);
|
||||
pe->arg2 = PROPERTY_TASK_IFE_SERVICECODE(handle);
|
||||
pe->arg3 = PROPERTY_TASK_IFE_OBJHANDLE(handle);
|
||||
PROPERTY_TASK_IFE_SERVICECODE(handle) = 0;
|
||||
PROPERTY_TASK_IFE_OBJHANDLE(handle) = 0;
|
||||
}else{
|
||||
pe->arg1 = PROPERTY_OBJECT_STATE(objectclass, handle);
|
||||
}
|
||||
pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
if (RecorderDataPtr->recorderActive)
|
||||
{
|
||||
// Interrupt disable not necessary, already done in trcHooks.h macro
|
||||
pe = (ObjClosePropEvent*) xTraceNextFreeEventBufferSlot();
|
||||
if (pe != NULL)
|
||||
{
|
||||
if (objectclass == TRACE_CLASS_TASK)
|
||||
{
|
||||
pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle);
|
||||
pe->arg2 = 0; // Legacy - IFE info removed.
|
||||
pe->arg3 = 0; // Legacy - IFE info removed.
|
||||
}else{
|
||||
pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle);
|
||||
}
|
||||
pe->type = EVENTGROUP_OBJCLOSE_PROP + objectclass;
|
||||
prvTraceUpdateCounters();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void vTraceSetPriorityProperty(uint8_t objectclass, uint8_t id, uint8_t value)
|
||||
{
|
||||
PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
|
||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", );
|
||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceSetPriorityProperty: Invalid value for id", );
|
||||
|
||||
TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value;
|
||||
}
|
||||
|
||||
uint8_t uiTraceGetPriorityProperty(uint8_t objectclass, uint8_t id)
|
||||
{
|
||||
return PROPERTY_ACTOR_PRIORITY(objectclass, id);
|
||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0);
|
||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceGetPriorityProperty: Invalid value for id", 0);
|
||||
|
||||
return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id);
|
||||
}
|
||||
|
||||
void vTraceSetObjectState(uint8_t objectclass, uint8_t id, uint8_t value)
|
||||
{
|
||||
PROPERTY_OBJECT_STATE(objectclass, id) = value;
|
||||
}
|
||||
|
||||
void vTraceSetTaskInstanceFinished(objectHandleType handle)
|
||||
{
|
||||
#if (USE_IMPLICIT_IFE_RULES == 1)
|
||||
if (PROPERTY_TASK_IFE_SERVICECODE(handle) == 0)
|
||||
{
|
||||
PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
|
||||
}
|
||||
#endif
|
||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "vTraceSetObjectState: objectclass >= TRACE_NCLASSES", );
|
||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "vTraceSetObjectState: Invalid value for id", );
|
||||
|
||||
TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value;
|
||||
}
|
||||
|
||||
uint8_t uiTraceGetObjectState(uint8_t objectclass, uint8_t id)
|
||||
{
|
||||
return PROPERTY_OBJECT_STATE(objectclass, id);
|
||||
TRACE_ASSERT(objectclass < TRACE_NCLASSES, "uiTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0);
|
||||
TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], "uiTraceGetObjectState: Invalid value for id", 0);
|
||||
|
||||
return TRACE_PROPERTY_OBJECT_STATE(objectclass, id);
|
||||
}
|
||||
|
||||
void vTraceSetTaskInstanceFinished(objectHandleType handle)
|
||||
{
|
||||
TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK], "vTraceSetTaskInstanceFinished: Invalid value for handle", );
|
||||
|
||||
#if (USE_IMPLICIT_IFE_RULES == 1)
|
||||
TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue