in AVR_Dx_MPLAB.X/TraceRecorder/trcSnapshotRecorder.c [1309:1422]
void vTraceVPrintF(traceString eventLabel, const char* formatStr, va_list vl)
{
#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0)
uint32_t noOfSlots;
UserEvent* ue1;
uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4];
TRACE_ALLOC_CRITICAL_SECTION();
TRACE_ASSERT(formatStr != NULL, "vTraceVPrintF: formatStr == NULL", TRC_UNUSED);
trcCRITICAL_SECTION_BEGIN();
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
{
/* First, write the "primary" user event entry in the local buffer, but
let the event type be "EVENT_BEING_WRITTEN" for now...*/
ue1 = (UserEvent*)(&tempDataBuffer[0]);
ue1->type = EVENT_BEING_WRITTEN; /* Update this as the last step */
noOfSlots = prvTraceUserEventFormat(formatStr, vl, (uint8_t*)tempDataBuffer, 4);
/* Store the format string, with a reference to the channel symbol */
ue1->payload = prvTraceOpenSymbol(formatStr, eventLabel);
ue1->dts = (uint8_t)prvTraceGetDTS(0xFF);
/* prvTraceGetDTS might stop the recorder in some cases... */
if (RecorderDataPtr->recorderActive)
{
/* If the data does not fit in the remaining main buffer, wrap around to
0 if allowed, otherwise stop the recorder and quit). */
if (RecorderDataPtr->nextFreeIndex + noOfSlots > RecorderDataPtr->maxEvents)
{
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
(void)memset(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4],
0,
(RecorderDataPtr->maxEvents - RecorderDataPtr->nextFreeIndex)*4);
RecorderDataPtr->nextFreeIndex = 0;
RecorderDataPtr->bufferIsFull = 1;
#else
/* Stop recorder, since the event data will not fit in the
buffer and not circular buffer in this case... */
vTraceStop();
#endif
}
/* Check if recorder has been stopped (i.e., vTraceStop above) */
if (RecorderDataPtr->recorderActive)
{
/* Check that the buffer to be overwritten does not contain any user
events that would be partially overwritten. If so, they must be "killed"
by replacing the user event and following data with NULL events (i.e.,
using a memset to zero).*/
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
prvCheckDataToBeOverwrittenForMultiEntryEvents((uint8_t)noOfSlots);
#endif
/* Copy the local buffer to the main buffer */
(void)memcpy(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4],
tempDataBuffer,
noOfSlots * 4);
/* Update the event type, i.e., number of data entries following the
main USER_EVENT entry (Note: important that this is after the memcpy,
but within the critical section!)*/
RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4] =
(uint8_t) ( USER_EVENT + noOfSlots - 1 );
/* Update the main buffer event index (already checked that it fits in
the buffer, so no need to check for wrapping)*/
RecorderDataPtr->nextFreeIndex += noOfSlots;
RecorderDataPtr->numEvents += noOfSlots;
if (RecorderDataPtr->nextFreeIndex >= (TRC_CFG_EVENT_BUFFER_SIZE))
{
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
/* We have reached the end, but this is a ring buffer. Start from the beginning again. */
RecorderDataPtr->bufferIsFull = 1;
RecorderDataPtr->nextFreeIndex = 0;
#else
/* We have reached the end so we stop. */
vTraceStop();
#endif
}
}
#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER)
/* Make sure the next entry is cleared correctly */
prvCheckDataToBeOverwrittenForMultiEntryEvents(1);
#endif
}
}
trcCRITICAL_SECTION_END();
#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)
/* Use the separate user event buffer */
traceString formatLabel;
traceUBChannel channel;
if (RecorderDataPtr->recorderActive && handle_of_last_logged_task)
{
formatLabel = xTraceRegisterString(formatStr);
channel = xTraceRegisterUBChannel(eventLabel, formatLabel);
prvTraceUBHelper1(channel, eventLabel, formatLabel, vl);
}
#endif
}