module ti.uiaplus.loggers.stream.LoggerStreamer |
This logger hands a buffer to the application via callback
when full
The general purpose logger is
useful in situations where the application wants to manage the buffers. This
includes managing the sending of the buffers to an instrumentation host (e.g.
System Analyzer in CCS). [ more ... ]
C synopsis |
target-domain |
sourced in ti/uiaplus/loggers/stream/LoggerStreamer.c |
#include <ti/uiaplus/loggers/stream/LoggerStreamer.h>
DETAILS
The general purpose logger is
useful in situations where the application wants to manage the buffers. This
includes managing the sending of the buffers to an instrumentation host (e.g.
System Analyzer in CCS).
LoggerStreamer was designed to have minimal
impact on an application when calling a Log function. There are several configuration
parameters allow an application to get the optimal performance in exchange for
certain restrictions.
LoggerStreamer stores events in a buffer provided
by the application and will call an application provided exchange function when
it is full. The exchange is called within the context of a Log call, so the
exchange function should be design to fast. Since the exchange function is
called within the context of the Log call, LoggerStreamer
guarantees no Log records are dropped (i.e. LoggerStreamer
is lossless).
The application is responsible for
providing the buffers that LoggerStreamer uses. There
are two ways that buffers are provided to LoggerStreamer.
by calling the LoggerStreamer_init API when
starting up.
by returning a pointer to a buffer from the bufferExchange
callback function.
The buffer that is provided is used
to log events. The first four 32-bit words contain a UIAPacket.Hdr structure. This struct is used
by the host (e.g. System Analyzer in CCS) to help decode the data (e.g. endianess, length of data, etc.). The UIAPacket.Hdr structure is initialized via the initBuffer API. All buffers given to LoggerStreamer (via init or exchange) must be initialized
via initBuffer.
The size of buffer -*- includes UIAPacket_Hdr? LoggerStreamer
treats the buffer as an UInt32 array. So the
application must guarantee the buffers are aligned accordingly.
When the buffer is filled, LoggerStreamer will hand it off to the application using
the exchange function (exchangeFxn). The exchange function must be of
type ExchangeFxnType. The exchange function is called in the context of a log
so generally the exchange function should be quick to execute.
Interrupts are disabled during the
duration of the log call including when the exchange function is called. LoggerStreamer will ignore any log events generated during
the exchangeFxn (e.g. posting a semaphore).
EXAMPLES
The following C code demonstrates a
basic init and exchange example. A real implementation would send the buffer to
an instrumentation host (e.g. System Analyzer in CCS, via UDP.). A full example
of this is provided in ti/uia/examples/linuxDemo .
// initialize the BUF_WITH_CONTEXT data
structures, setting a pointer
// to whatever context information you
want to be able to reference when
// working with the buffers
#include <xdc/std.h>
#include <ti/uiaplus/loggers/stream/LoggerStreamer.h>
#define BUFLEN 1024
#define NPACK 10
#define PORT 1235
typedef
struct _BUF_WITH_CONTEXT {
Char udpHdr[44];
// note that header is 42 bytes long, and must start at udpHdr[2]
OR the data structures need to be aligned
//
so that eventPacket is word aligned.
UInt32 eventPacket[BUFLEN/sizeof(UInt32)];
// UIA event data packet - this is what the logger works with. Note that BUFLEN must be a multiple of
4.
Ptr
next;
Ptr
pStartOfUDPPacket; // points to the start of the UDP
packet - i.e. what needs to be transmtted over the
Ethernet link
Ptr
pContextInfo; // points to whatever context info
you want to associate with this buffer
Int
coreNumber; // DNUM value for the
core that logged the events
} BUF_WITH_CONTEXT;
volatile Int count = 0;
#define NUM_BUFFERS (NPACK)
BUF_WITH_CONTEXT buffer[NUM_BUFFERS];
void init(Ptr pCtxInfo){
int i;
short
cpuId = 0;
// Each
application needs to generate a CRC16 of the application name so that
// System Analyzer can
identify which executable file to read symbols from in order
// to decode string
constants for the application properly.
When multiple applications
// are generating events
simultaneously, the appName MUST match
// the name of the
executable (without extension or path) in order for System Analyzer
// to be able to locate the
correct file containing each application's symbols.
// In System Analyzer's UIA Config file, a separate endpoint must be configured
// to identify each Linux
user-space application that can log events.
unsigned
char const appName[] = "demo";
short
crcApp16 = LoggerStreamer_generateCRC(appName,strlen((char *)appName));
for
(i=0;i<NUM_BUFFERS;i++){
if (i < (NUM_BUFFERS+1)){
buffer[i].next =
&buffer[1+1];
}
else {
buffer[i].next =
&buffer[0];
}
buffer[i].pContextInfo = pCtxInfo;
buffer[i].pStartOfUDPPacket = &buffer[i].udpHdr[2];
buffer[i].coreNumber = 0;
LoggerStreamer_initBuffer(buffer[i].eventPacket,
cpuId,crcApp16);
}
// initialize LoggerStreamer
LoggerStreamer_init(buffer[0].eventPacket,BUFLEN);
}
.
typedef LoggerStreamer_ExchangeFxnType |
Typedef for the exchange function pointer
C synopsis |
target-domain |
typedef Ptr (*LoggerStreamer_ExchangeFxnType)(Ptr);
config LoggerStreamer_exchangeFxn // module-wide |
Function pointer to the exchange function
C synopsis |
target-domain |
extern const LoggerStreamer_ExchangeFxnType LoggerStreamer_exchangeFxn;
DETAILS
returns a pointer to a buffer that is word
aligned, initialized with a UIA header and the correct size. The exchange
function is called in the context of a log so generally the exchange function
should be quick to execute.
LoggerStreamer_flush() // module-wide |
Force LoggerStream to
call the exchange function
C synopsis |
target-domain |
Void LoggerStreamer_flush();
DETAILS
This API makes LoggerStreamer
call the application provided exchangeFxn function if there are Log events
present in the buffer.
The call to the exchangeFxn function is called in the context
of the flush call.
LoggerStreamer_initBuffer() // module-wide |
Initializes the UIA packet header
C synopsis |
target-domain |
macro Void LoggerStreamer_initBuffer(Ptr buffer, UInt16 src);
ARGUMENTS
buffer — Pointer
to the buffer that LoggerStreamer will fill with Log
events. The first four 32-bit words will contain the UIAPacket_Hdr
structure.
src — Used to
initialize the UIA source address. For a single core device, this will
generally be 0. For multi-core devices, it generally corresponds to the DNUM
(on C6xxxx deviecs) or the Ipc
MultiProc id. It must be unique for all cores and
match the configuration in the System Analyzer endpoint configuration.
DETAILS
This API is used to initialize a
buffer before it is given to LoggerStreamer (via
priming or exchange). The function initializes the UIAPacket
portion of the buffer.
LoggerStreamer_init() // module-wide |
Assigns an initialized buffer that
LoggerStreamer can store events in, of size bufSizeInMAUs.
C synopsis |
target-domain |
Void LoggerStreamer_init(UInt32* buffer1, UInt32 bufSizeInMAUs);
ARGUMENTS
buffer1 — Pointer
to the first buffer that LoggerStreamer will fill
with Log events. The buffer should have previously
been initialized by passing it to the initBuffer API.
bufSizeInMAUs — The
length of the buffer1 buffer, including the length of the UIAPacket_Hdr
data structure..
DETAILS
This API is used to initialize LoggerStreamer. LoggerStreamer
will not log events until this API is called.
LoggerStreamer_disable() |
Disable event logging
C synopsis |
target-domain |
Bool LoggerStreamer_disable();
DETAILS
Events written to a disabled log
are silently discarded.
RETURNS
The function returns the state of
the log (TRUE if enabled, FALSE if disabled) before the call. This return value allows
clients to restore the previous state. Note: not thread safe.
LoggerStreamer_enable() |
Enable a log
C synopsis |
target-domain |
Bool LoggerStreamer_enable();
RETURNS
The function returns the state of
the log (TRUE if enabled, FALSE if disabled) before the call. This return value allows
clients to restore the previous state. Note: not thread safe.
LoggerStreamer_write0() |
Process a log event with 0 arguments and the
calling address
C synopsis |
target-domain |
Void LoggerStreamer_write0( Log_Event evt, Types_ModuleId mid);
DETAILS
Same as write4 except with 0 arguments rather than 4.
Same as write4 except with 0 arguments rather than 4.
SEE
LoggerStreamer_write1() |
Process a log event with 1 arguments and the
calling address
C synopsis |
target-domain |
Void LoggerStreamer_write1( Log_Event evt, Types_ModuleId mid, IArg a1);
DETAILS
Same as write4 except with 1 arguments rather
than 4.
Same as write4 except with 1 arguments rather
than 4.
SEE
LoggerStreamer_write2() |
Process a log event with 2 arguments and the
calling address
C synopsis |
target-domain |
Void LoggerStreamer_write2(Log_Event evt, Types_ModuleId mid, IArg a1, IArg a2);
DETAILS
Same as write4 except with 2 arguments rather than 4.
Same as write4 except with 2 arguments rather than 4.
SEE
LoggerStreamer_write4() |
Process a log event with 4 arguments and the
calling address
C synopsis |
target-domain |
Void LoggerStreamer_write4(Log_Event evt, Types_ModuleId mid, IArg a1, IArg a2, IArg a3, IArg a4);
evt — event to be
logged
mid — module
ID of the module which logged the event
a1 — arbitrary
argument passed by caller
DETAILS
The evt argument is of type Log.Event,
which encodes the Log.EventId, the Diags.Mask, and the Diags.EventLevel of the event. The event ID can be
obtained via Types.getEventId(evt), the Diags
mask can be obtained via Diags.getMask(evt), and the event level can be obtained via Diags.getLevel(evt).
The modId argument is the module ID of the module that logged the
event.
The event information can be used
by the logger to handle different events specially. For example, the event ID
can be used to compare against other known Log.Events.
if (Log_getEventId(MY_EVENT) == Log_getEventId(evt)) {
:
}
The event ID value of 0 is used to indicate an event triggered by a call to one of the Log_print[0-6] methods. These methods take a
format string rather than a Log_Event argument and, as a result, the event ID encoded in evt is 0 and the parameter a1 is the format string.
The arguments a1, a2, etc. are
parameters that are to be interpreted according to the message format string
associated with evt.
SEE
LoggerStreamer_write8() |
Process a log event with 8 arguments and the
calling address
C synopsis |
target-domain |
Void LoggerStreamer_write8(Log_Event evt, Types_ModuleId mid, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8);
DETAILS
Same as write4 except with 8 arguments rather than 4.
Same as write4 except with 8 arguments rather than 4.
SEE
LoggerStreamer_writeMemoryRange() |
Log an event along with values from a range of
memory addresses
C synopsis |
target-domain |
Void LoggerStreamer_writeMemoryRange(Log_Event evt, Types_ModuleId mid, UInt32 snapshotId, IArg fileName,
IArg LineNum,
IArg fmt,
IArg startAdrs,
UInt32 lengthInMAUs);
ARGUMENTS
evt — event to be
logged
snapshotId — 0
= no other snapshot groups, Use value from LogSnapshot.getSnapshotId()
for all snapshots to be grouped.
fileName — __FILE__
result
lineNum — __LINE__
result
fmt — a printf style
format string
startAdrs — value
for first format conversion character
lengthInMAUs — value
for second format conversion character
DETAILS
If the mask in the specified LogSnapshot event has any bit set which is
also set in the current module's diagnostics mask, then this call to write will
log the given LogSnapshot event.
Note that this API supports null
terminated strings, arrays of characters and memory mapped registgers
as well as blocks of memory. The LogSnapshot module
provides macros that map the appropriate values to the writeMemoryRange
API's arguments
SEE
|