1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32
33 34 35
36 package ti.uia.runtime;
37 import xdc.runtime.Types;
38 import ti.uia.runtime.LoggerTypes;
39 import xdc.runtime.ILogger;
40 import ti.uia.runtime.CtxFilter;
41 import xdc.runtime.ILogger;
42 import xdc.runtime.Diags;
43 import xdc.runtime.Text;
44 import ti.uia.events.UIASnapshot;
45 import ti.uia.runtime.IUIATraceSyncClient;
46
47 /*!
48 * ======== LogSnapshot ========
49 * Snapshot Event logging manager for logging blocks of memory, strings in memory
50 * and names of dynamically created objects
51 *
52 * {@link ti.uia.events.UIASnapshot Snapshot events} are used to log dynamic
53 * target state information in order to
54 * capture the execution context of the application at a particular moment in
55 * time. Types of information that can be logged include:
56 * @p(blist)
57 * - Blocks of memory (using the {@link #writeMemoryBlock LogSnapshot_writeMemoryBlock} API)
58 * - Strings that reside in memory (using the {@link #writeString LogSnapshot_writeString} API)
59 * - Names of dynamically created objects (using the {@link #writeNameOfReference LogSnapshot_writeNameOfReference} API)
60 * @p
61 * The host-side tooling can be instructed to treat a series of LogSnapshot
62 * events as representing the state of the target at the same moment in time by
63 * using the same non-zero value in the {@link #getSnapshotId snapshot ID} parameter
64 * of each of the LogSnapshot events in the series.
65 *
66 * Snapshot events are logged by a logger that implements the
67 * {@link ti.uia.runtime.ILoggerSnapshot ILoggerSnapshot}
68 * interface (e.g. {@link ti.uia.runtime.LoggerCircBuf LoggerCircBuf},
69 * {@link ti.uia.runtime.LoggerStopMode LoggerStopMode},
70 * {@link ti.uia.runtime.LoggerProbePoint LoggerProbePoint}).
71 * Rather than invoking the logger's APIs directly, the APIs are
72 * called indirectly via the LogSnapshot module's APIs so that different types
73 * of loggers can be used without having to recompile the source code that is
74 * logging the snapshot events.
75 * @a(Examples)
76 * @p(html)
77 * <B>Example 1: A simple 2-line configuration script</B>
78 * @p
79 * The following configuration script shows the simplest way
80 * to configure an application to use log snapshot events:
81 * @p(code)
82 * var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
83 * var LogSnapshot = xdc.useModule('ti.uia.runtime.LogSnapshot');
84 * @p
85 * The first line causes the {@link ti.uia.sysbios.LoggingSetup LoggingSetup}
86 * module's .xs script to automatically create a 32K Byte logger and assign it to
87 * xdc.runtime.Main.common$.logger. It also sets any unconfigured Diags masks
88 * for the Main module to Diags.RUNTIME_ON, enabling the events to be logged.
89 * @p
90 * The second line causes the LogSnapshot .xs script to run during the configuration
91 * process when building the application. The script detects that a logger has
92 * not been assigned to the LogSnapshot module, so it checks if
93 * a logger has been configured for either the Main module or the Defaults module.
94 * Since there is a logger for the Main module, the script configures the LogSnapshot
95 * module to log events to the same logger instance.
96 *
97 * @p(html)
98 * <hr />
99 * <B>Example 2: Using a dedicated low priority logger for snapshot events</B>
100 * @p
101 * In some situations, the amount of data logged by the LogSnapshot
102 * APIs may exceed the ability of the target to move the event data out of the
103 * Main module's logger's circular buffer and up to the host. One way of
104 * ensuring that the other events that are logged are not dropped due to this
105 * type of situation is to configure the LogSnapshot module to write events
106 * to a separate lower priority logger.
107 * @p
108 * The following is an example of a
109 * configuration script that configures a logger for use by the LogSnapshot
110 * module. This example uses a LoggerCircBuf logger, which is appropriate for
111 * uploading events in real-time as the target executes using either
112 * JTAG RunMode(C6X targets) or using a non-JTAG transport such as Ethernet.
113 * Assigning this logger a {@link ti.uia.runtime.IUIATransferlow#Priority_LOW
114 * low priority} causes the contents of this logger to be uploaded after
115 * higher priority events (e.g. sync point events, context change events,
116 * and error, warning, info events) have been uploaded.
117 * @p
118 * @p(code)
119 * var Logger = xdc.useModule('ti.uia.runtime.LoggerCircBuf');
120 * var LogSnapshot = xdc.useModule('ti.uia.runtime.LogSnapshot');
121 *
122 * // Create a low priority logger and use it for snapshot events
123 * var IUIATransfer = xdc.useModule('ti.uia.runtime.IUIATransfer');
124 * var loggerParams = new Logger.Params();
125 * loggerParams.priority = IUIATransfer.Priority_LOW;
126 * // set the logger buffer size in bytes
127 * loggerParams.transferBufSize = 32768;
128 * var snapshotLogger = Logger.create(loggerParams);
129 * snapshotLogger.instance.name = "SnapshotLog";
130 * LogSnapshot.common$.logger = snapshotLogger;
131 * @p
132 * Using different types of loggers:
133 * @p(blist)
134 * - To upload events by JTAG when the target halts (JTAG StopMode),
135 * replace the first line in the example with
136 * @p(code)
137 * Logger = xdc.useModule('ti.uia.runtime.LoggerStopMode');
138 * @p(blist)
139 * - To upload events by JTAG whenever an event is logged using probe point
140 * breakpoints (i.e. momentarily halting the target while the event is uploaded
141 * and then resuming execution), replace the first line in the example with
142 * @p(code)
143 * Logger = xdc.useModule('ti.uia.runtime.LoggerProbePoint');
144 * @p
145 *
146 *
147 * @p(html)
148 * <hr />
149 * <B>Example 3: Using Diags masks to control snapshot events</B>
150 * @p
151 * The generation of a 'Snapshot' event is controlled by a module's diagnostics
152 * mask, which is described in details in the CDoc for xdc.runtime.Diags. Each
153 * {@link ti.uia.events.UIASnapshot snapshot event} is controlled using the
154 * Diags.ANALYSIS mask, and will only be logged when the diagnostics mask for
155 * the module that is logging the code has the Diags.ANALYSIS bit
156 * configured as either ALWAYS_ON or RUNTIME_ON.
157 * @p
158 * The `LogSnapshot` function call sites are implemented in such a way that an
159 * optimizer can completely eliminate `LogSnapshot` code from the program if
160 * the module's `ANALYSIS` events have been disabled at configuration time. If
161 * the 'ANALYSIS' events are permanently turned on at configuration time,
162 * then the optimizer can eliminate all runtime conditional checking and
163 * simply invoke the 'LogSnapshot' functions directly. Runtime checking is
164 * performed only when the ANALYSIS events are configured to be runtime
165 * modifiable.
166 * @p
167 * The following is an example of the configuration script used
168 * to configure the default mask for modules to have Analysis events such as
169 * the UIASnapshot events always on.
170 * @p(code)
171 * // Configure all modules to always log Analysis events
172 * var Diags = xdc.useModule('xdc.runtime.Diags');
173 * var Defaults = xdc.useModule('xdc.runtime.Defaults');
174 * Defaults.common$.diags_ANALYSIS = Diags.ALWAYS_ON;
175 * @p
176 *
177 */
178
179 @CustomHeader
180 module LogSnapshot inherits IUIATraceSyncClient {
181
182 /*!
183 * ======== EventRec ========
184 * The target representation of a recorded event
185 *
186 * This structure defines how events are recorded on the target.
187 */
188 struct EventRec {
189 Types.Timestamp64 tstamp; /*! time event was written */
190 Bits32 serial; /*! serial number of event */
191 Types.Event evt; /*! target encoding of an Event */
192 Int snapshotId;
193 IArg fmt;
194 Ptr pData;
195 UInt16 lengthInMAUs; /*! arguments passed via Log_write/print */
196 }
197 /*!
198 * ======== maxLengthInMAUs ========
199 * Maximum number of MAUs (miniumum addressable units, e.g. bytes)
200 * supported by `LogSnapshot` events.
201 *
202 * Attempting to write more than the maximum length results in the
203 * multiple events being logged. The maxLengthInMAUs must be
204 * lower than the size of the buffer that the events are being logged to.
205 * Must be less than 1400 in order to support streaming of event
206 * data over UDP.
207 */
208 config Int maxLengthInMAUs = 512;
209
210 /*!
211 * ======== isTimestampEnabled ========
212 * used to enable or disable logging the 64b local CPU timestamp
213 * at the start of each event
214 */
215 config Bool isTimestampEnabled = true;
216
217 /*! @_nodoc
218 * ======== loggerDefined ========
219 * set to true in the configuration script when a logger that implements
220 * ILoggerSnapshot is attached
221 */
222 config Bool loggerDefined = false;
223 /*!
224 * ======== loggerObj ========
225 * handle of the logger that is to be used to log snapshot events
226 */
227 config Ptr loggerObj = null;
228
229 /*! @_nodoc */
230 config ti.uia.runtime.LoggerTypes.LogMemoryRangeFxn loggerMemoryRangeFxn = null;
231
232
233 /*!
234 * ======== putMemoryRange ========
235 * Unconditionally put the specified `Types` event.
236 * Supports both writeMemoryRange and writeString.
237 *
238 * This method unconditionally puts the specified memoryRange`{@link Types#Event}`
239 * `evt` into the log. This type of event is created either implicitly
240 * (and passed to an `{@link ISnapshotLogger}` implementation) or explicitly
241 * via `{@link Types#makeEvent()}`.
242 *
243 * @param(evt) the `Types` event to put into the log
244 * @param(mid) the module ID of the caller
245 * @param(snapshotId) unique ID that binds together a series of events used to
246 * log a large memory range
247 * @param(fileName) the name of the file that the event was logged from
248 * @param(lineNum) the line number that the event was logged from
249 * @param(fmt) a user-specified print format string
250 * @param(startAdrs) the start address of the memory range to log
251 * @param(lengthInMAUs) the number of minimum addressable units (e.g. bytes) to log
252 * @a(return) value to use as snapshotId parameter for subsequent events
253 */
254 @Macro Void putMemoryRange(Types.Event evt, Types.ModuleId mid,
255 IArg fileName, IArg lineNum, UInt32 snapshotID, IArg fmt, IArg startAdrs, IArg lengthInMAUs);
256
257 /*!
258 * ======== memoryBlock ========
259 * Generate a `LogSnapshot` event for a block of memory
260 *
261 * @a(Examples)
262 * Example: The following C code shows how to log a snapshot event to
263 * capture a block of memory.
264 *
265 * @p(code)
266 * #include <ti/uia/runtime/LogSnapshot.h>
267 * ...
268 * UInt32* pIntArray = (UInt32 *)malloc(sizeof(UInt32) * 200);
269 * ...
270 * LogSnapshot_writeMemoryBlock(0,"pIntArray ptr=0x%x, numBytes=%d",(UInt32)pIntArray,200);
271 * ...
272 * @p
273 * The following text will be displayed for the event, if it was logged
274 * from file demo.c at line 1234 and all 200 bytes were logged in the
275 * same event.
276 * @p(code)
277 * Memory Snapshot at [demo.c:1234] [snapshotID=0,adrs=0x80002000,
278 * numMAUsDataInEvent=200,numMAUsDataInRecord=200] ptr=0x80002000, numBytes=200
279 * @p
280 * If the 200 bytes were spread across multiple events,
281 * the numMAUsDataInRecord would indicate how many bytes were in the
282 * memory block, and numMAUsDataInEvent would indicate how many bytes
283 * were stored in that particular event.
284 * @p
285 * @param(snapshotID) ID used to identify snapshot events taken at the same
286 * time. Set to 0 for first in series, set rest to return
287 * value of LogSnapshot API. {@link #getSnapshotId see getSnapshotId()}
288 * @param(fmt) a constant string that provides a user-readable description
289 * of what information the event is capturing
290 * @param(pMemoryRange) the start address of the range of memory
291 * @param(lengthInMAUs) the number of MAUs of data payload for the
292 * multi-event data record
293 */
294 @Macro Void writeMemoryBlock(UInt32 snapshotID, IArg fmt, Ptr pMemoryRange,
295 UInt16 lengthInMAUs);
296
297 /*!
298 * ======== string ========
299 * Generate a `LogSnapshot` event for a string in memory
300 *
301 * @a(Example)
302 * The following C code shows how to log a snapshot event to log the
303 * contents of a string in memory.
304 *
305 * @p(code)
306 * #include <ti/uia/runtime/LogSnapshot.h>
307 * ...
308 * Void myFunc(String name){
309 * ...
310 * LogSnapshot_writeString(0,"User-defined name=%s.",name, strlen(name));
311 * }
312 * @p
313 * The following text will be displayed for the event, if it was logged
314 * from file demo.c at line 1234 and all bytes in the 40 character string
315 * was logged in the same event.
316 * @p(code)
317 * String Snapshot at [../demo.c:1234] [snapshotID=0,adrs=0x80001234,40,40] User-defined name=ValueOfParm.
318 * @p
319 * @param(snapshotID) ID used to identify snapshot events taken at the same
320 * time. Set to 0 for first in series, set rest to return
321 * value of LogSnapshot API. {@link #getSnapshotId see getSnapshotId()}
322 * @param(fmt) a constant string that provides a user-readable description
323 * of what information the event is capturing
324 * @param(pString) the start address of the string in memory
325 * @param(lengthInMAUs) the number of MAUs to log (e.g. strlen(pString))
326 */
327 @Macro Void writeString(UInt32 snapshotID, IArg fmt, Ptr pString,
328 UInt16 lengthInMAUs);
329
330 /*!
331 * ======== nameOfReference ========
332 * Used to log the contents of a dynamic string on the heap so that host-side
333 * tooling can display this string as the name of handle / reference ID
334 *
335 * @a(Example)
336 * The following C code shows how to log a task name for use by task
337 * execution graphs etc.
338 *
339 * @p(code)
340 * #include <ti/uia/runtime/LogSnapshot.h>
341 * #include <ti/sysbios/BIOS.h>
342 * #include <ti/sysbios/knl/Task.h>
343 * ...
344 * // Task create hook function that logs the task name.
345 * // Notes: Task name is not trequired when creating a BIOS task. Please \
346 * // make sure a name is provided in order for the host side analysis tool
347 * // to work properly.
348 * Void tskCreateHook(Task_Handle hTask, Error_Block *eb) {
349 * String name;
350 * name = Task_Handle_name(hTask);
351 * LogSnapshot_writeNameOfReference(hTask,"Task_create: name=%s",
352 * name,strlen(name)+1);
353 * }
354 * @p
355 * This event prints the Log call site (%$F) and a format string (%$S)
356 * which describes what information the event is logging.
357 * The following text will be displayed for the event:
358 * @p(code)
359 * nameOfReference at [demo.c:line 1234] [refID=0x80002000,adrs=0x80001234,40,40] Task_create: name=10msThread.
360 * @param(refID) reference ID (e.g. task handle) that the name is
361 * associated with
362 * @param(pString) the start address of the string on the heap
363 * @param(lengthInMAUs) the number of MAUs to log (e.g. strlen(pString))
364 * @param(fmt) a constant string that provides format specifiers
365 * describing the string
366 */
367 @Macro Void writeNameOfReference(UInt32 refID, IArg fmt, Ptr pString,
368 UInt16 lengthInMAUs);
369
370 /*!
371 * ======== getSnapshotId ========
372 * returns a unique ID to use to group a set of snapshot event logs together
373 *
374 * Allows tooling to treat a set of consecutive event logs as a unit and
375 * display all of the relevent data together as a set
376 * @a(Example)
377 * The following C code shows how to log two snapshot events that capture
378 * the target state of two different data structures, using a common unique
379 * non-zero snapshot ID provided by the getSnapshotId to inform the host-side
380 * tooling that the events represent the target state at the same point in time
381 * @p(code)
382 * #include <ti/uia/runtime/LogSnapshot.h>
383 * ...
384 * MyStruct1 myStruct1;
385 * MyStruct2 myStruct2;
386 * UInt32 snapshotId;
387 * ...
388 * snapshotId = LogSnapshot_getSnapshotId();
389 * LogSnapshot_writeMemoryBlock(snapshotId,"myStruct1 ptr=0x%x, numBytes=%d",(UInt32)&myStruct1,sizeof(MyStruct1));
390 * LogSnapshot_writeMemoryBlock(snapshotId,"myStruct2 ptr=0x%x, numBytes=%d",(UInt32)&myStruct2,sizeof(MyStruct2));
391 * ...
392 * @p
393 * @a(return) a unique non-zero snapshot ID to pass in as a parameter to the
394 * LogSnapshot APIs
395 */
396 @DirectCall
397 UInt32 getSnapshotId();
398
399 /*!
400 * ======== doPrint ========
401 * Render an event as text via `{@link System#printf System_printf}`
402 *
403 * This method is not currently implemented.
404 *
405 * @param(evRec) a non`NULL` pointer to an initialized `
406 * LogSnapshot_EventRec`structure to be formated via
407 * {@link System#printf System_printf}`.
408 */
409
410 Void LogSnapshot_doPrint(EventRec *er);
411
412 413 414 415
416 metaonly config String idToInfo[string] = [];
417
418 }