in FreeRTOS-Plus/Source/FreeRTOS-Plus-Trace/trcSnapshotRecorder.c [858:1007]
static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_t* buffer, uint8_t byteOffset)
{
uint16_t formatStrIndex = 0;
uint8_t argCounter = 0;
uint8_t i = byteOffset;
while (formatStr[formatStrIndex] != '\0')
{
if (formatStr[formatStrIndex] == '%')
{
if (formatStr[formatStrIndex + 1] == '%')
{
formatStrIndex += 2;
continue;
}
/* We found a possible argument */
argCounter++;
formatStrIndex++;
while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.')
formatStrIndex++;
/* This check is necessary to avoid moving past end of string. */
if (formatStr[formatStrIndex] != '\0')
{
switch (formatStr[formatStrIndex])
{
case 'd':
i = writeInt32( buffer,
i,
(uint32_t)va_arg(vl, uint32_t));
break;
case 'x':
case 'X':
case 'u':
i = writeInt32( buffer,
i,
(uint32_t)va_arg(vl, uint32_t));
break;
case 's':
i = writeInt16( buffer,
i,
xTraceRegisterString((char*)va_arg(vl, char*)));
break;
#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
/* Yes, "double" as type also in the float
case. This since "float" is promoted into "double"
by the va_arg stuff. */
case 'f':
i = writeFloat( buffer,
i,
(float)va_arg(vl, double));
break;
#else
/* No support for floats, but attempt to store a float user event
avoid a possible crash due to float reference. Instead store the
data on uint_32 format (will not be displayed anyway). This is just
to keep va_arg and i consistent. */
case 'f':
i = writeInt32( buffer,
i,
(uint32_t)va_arg(vl, double));
break;
#endif
case 'l':
formatStrIndex++;
switch (formatStr[formatStrIndex])
{
#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT)
case 'f': i = writeDouble(buffer,
i,
(double)va_arg(vl, double));
break;
#else
/* No support for floats, but attempt to store a float user event
avoid a possible crash due to float reference. Instead store the
data on uint_32 format (will not be displayed anyway). This is just
to keep va_arg and i consistent. */
case 'f':
i = writeInt32( buffer, /* In this case, the value will not be shown anyway */
i,
(uint32_t)va_arg(vl, double));
i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */
i,
(uint32_t)va_arg(vl, double));
break;
#endif
}
break;
case 'h':
formatStrIndex++;
switch (formatStr[formatStrIndex])
{
case 'd':
i = writeInt16( buffer,
i,
(uint16_t)va_arg(vl, uint32_t));
break;
case 'u':
i = writeInt16( buffer,
i,
(uint16_t)va_arg(vl, uint32_t));
break;
}
break;
case 'b':
formatStrIndex++;
switch (formatStr[formatStrIndex])
{
case 'd':
i = writeInt8( buffer,
i,
(uint8_t)va_arg(vl, uint32_t));
break;
case 'u':
i = writeInt8( buffer,
i,
(uint8_t)va_arg(vl, uint32_t));
break;
}
break;
default:
/* False alarm: this wasn't a valid format specifier */
argCounter--;
break;
}
if (argCounter > 15)
{
prvTraceError("vTracePrintF - Too many arguments, max 15 allowed!");
return 0;
}
}
else
break;
}
formatStrIndex++;
if (i == 255)
{
prvTraceError("vTracePrintF - Too large arguments, max 32 byte allowed!");
return 0;
}
}
return (uint8_t)(i+3)/4;
}