1 /* --COPYRIGHT--,ESD
2 * Copyright (c) 2008 Texas Instruments. All rights reserved.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License
5 * v. 1.0 which accompanies this distribution. The Eclipse Public License is
6 * available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
7 * Distribution License is available at
8 * http://www.eclipse.org/org/documents/edl-v10.php.
9 *
10 * Contributors:
11 * Texas Instruments - initial implementation
12 * --/COPYRIGHT--*/
13 /*
14 * ======== Log.xdc ========
15 *
16 *! Revision History
17 *! ================
18 *! 06-May-2009 cmcc Fixed ROV bug SDOCM00057314
19 *! 06-Feb-2008 nitya Fixed SDSCM00020676
20 *! 17-Dec-2007 sasha implemented code review changes
21 */
22
23 /*!
24 * ======== Log ========
25 * Event logging manager
26 *
27 * RTSC modules and the application code generate `{@link #Event Log_Event}`
28 * events by calling the `Log` module's functions. The `Log` module then
29 * passes those events to an `{@link ILogger}` instance assigned to the event
30 * originating module, specified by that module's configuration parameter
31 * `common$.logger`. `ILogger` instances handle events, usually converting
32 * events to `{@link #EventRec Log_EventRec}` records prior to recording,
33 * transmitting, or displaying them.
34 *
35 * All events generated by a target module are stored and displayed by an
36 * `ILogger`, for example, an instance of
37 * `{@link LoggerBuf xdc.runtime.LoggerBuf}` or
38 * `{@link LoggerSys xdc.runtime.LoggerSys}`. However at runtime, modules
39 * generate events through this module, rather than invoking directly their
40 * `ILogger`s. By doing so, modules can be configured to use different
41 * `ILogger` implementations without any changes to their source code.
42 *
43 * A logger instance can accept `Log` events from any module, but a module
44 * can put `Log` events to only one logger instance. There can be one or
45 * more logger instances in a system. All `Log` calls that are not in a
46 * module are controlled by the module `{@link Main xdc.runtime.Main}`.
47 * For example, top-level application code or any existing sources that
48 * simply call the `Log` or `Assert` methods implicitly use the logger
49 * associated with the `Main` module.
50 *
51 * The generation of a `Log` event is controlled by a module's diagnostics
52 * mask, which is described in details in `{@link Diags}`. Each `Log` event
53 * is associated with a mask. `Log` events are generated only when a
54 * particular bit is set in both the `Log` event mask
55 * and the module's diagnostics mask. For example, a `Log` event mask with
56 * the `{@link Diags#USER1 USER1}` bit set is generated only when the `USER1`
57 * bit is also set in the module's diagnostics mask.
58 *
59 * There are two ways to generate `Log` events:
60 *
61 * @p(blist) 62 * - `{@link #write8 LOG_write()}`, which is tailored for module writers
63 * and takes full advantage of the XDC configuration model. For example,
64 * the message string associated with the `Log` event need not be a part of
65 * the final application, significantly reducing the "footprint overhead"
66 * of embedding diagnostics in deployed systems. The `Log_write[0-8]()`
67 * functions allow up to 8 values to be passed to the logger. They expect
68 * the logger to handle any formatting. A `Log` event type allows you to
69 * specify the type of event.
70 * - `{@link #print6 LOG_print()}`, which is designed for arbitrary C code.
71 * The `Log_print[0-6]()` functions allow up to 6 values to be passed along
72 * with a printf-like format string to the logger. They handle printf-style
73 * formatting.
74 * @p 75 *
76 * Both functions are controlled by the module's diagnostics mask. Their
77 * storage or output is defined by the logger that is assigned to the
78 * module that calls the `Log` methods or to the
79 * `{@link Main xdc.runtime.Main}` module if the caller is not part of a
80 * module.
81 *
82 * The `Log` function call sites are implemented in such a way that an
83 * optimizer can completely eliminate `Log` code from the program if the
84 * `Log` functions have been permanently disabled at configuration time. If
85 * the `Log` functions are permanently turned on at configuration time,
86 * then the optimizer can eliminate all runtime conditional checking and
87 * simply invoke the `Log` functions directly. Runtime checking is performed
88 * only when the `Log` functions are configured to be runtime modifiable.
89 *
90 * @a(Examples) 91 * Example 1: The following example defines a `Log` event, uses that `Log`
92 * event in a module, and configures the program to generate the `Log`
93 * event. In this example, both `USER1` and `USER2` bits are set in the
94 * event mask. This means that if either bit is set in the module's
95 * diagnostics mask, then the `Log` event will be generated.
96 *
97 * This is a part of the XDC specification file for the `Mod` module
98 * (Mod.xdc):
99 *
100 * @p(code) 101 * import xdc.runtime.Diags;
102 * import xdc.runtime.Log;
103 *
104 * config Log.Event L_someEvent = {
105 * mask: Diags.USER1 | Diags.USER2,
106 * msg: "my log event message, arg1: 0x%x, arg2: 0x%x"
107 * };
108 * @p 109 *
110 * This is a part of the C code implementation of the Mod module:
111 *
112 * @p(code) 113 * #include <xdc/runtime/Log.h>
114 * UInt x, y;
115 *
116 * Log_write2(Mod_L_someEvent, (IArg)x, (IArg)y);
117 * @p 118 *
119 * The following configuration script demonstrates how the application might
120 * control the `Log` statements embedded in the `Mod` module at configuration
121 * time. In this case, the configuration script arranges for the `Log`
122 * statements within the `Mod` module (shown above) to always generate events.
123 * Without these configuration statements, no `Log` events would be generated
124 * by this module.
125 *
126 * This is part of the XDC configuration file for the application:
127 *
128 * @p(code) 129 * var Diags = xdc.useModule('xdc.runtime.Diags');
130 * var Mod = xdc.useModule('my.pkg.Mod');
131 * Mod.common$.diags_USER1 = Diags.ALWAYS_ON;
132 * @p 133 *
134 * @p(html) 135 * <hr />
136 * @p 137 *
138 * Example 2: The following XDC configuration statements turn on enter
139 * and exit logging at configuration time for a module. Without any other
140 * changes in the runtime code, every time a module `Mod`'s function is
141 * being called or exits, an event will be logged.
142 *
143 * @p(code) 144 * var Diags = xdc.useModule('xdc.runtime.Diags');
145 * var Mod = xdc.useModule('my.pkg.Mod');
146 *
147 * Mod.common$.diags_ENTER = Diags.ALWAYS_ON;
148 * Mod.common$.diags_EXIT = Diags.ALWAYS_ON;
149 * @p 150 *
151 * @p(html) 152 * <hr />
153 * @p 154 *
155 * Example 3: The following example configures a module to support enter and
156 * exit logging, but defers the actual activation and deactivation of the
157 * logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
158 * function for details on specifying the control string.
159 *
160 * This is a part of the XDC configuration file for the application:
161 *
162 * @p(code) 163 * var Diags = xdc.useModule('xdc.runtime.Diags');
164 * var Mod = xdc.useModule('my.pkg.Mod');
165 *
166 * Mod.common$.diags_ENTER = Diags.RUNTIME_OFF;
167 * Mod.common$.diags_EXIT = Diags.RUNTIME_OFF;
168 * @p 169 *
170 * This is a part of the C code for the application:
171 *
172 * @p(code) 173 * // turn on enter and exit logging in the module
174 * Diags_setMask("my.pkg.Mod+EX");
175 *
176 * // turn off enter and exit logging in the module
177 * Diags_setMask("my.pkg.Mod-EX");
178 * @p 179 */
180
181 @CustomHeader
182
183 module Log {
184
185 /*!
186 * ======== NUMARGS ========
187 * Maximum number of arguments supported in `Log` events.
188 */
189 const Int NUMARGS = 8;
190
191 /*!
192 * ======== PRINTFID ========
193 * The `EventId` for `Log_print()` events
194 */
195 const EventId PRINTFID = 0;
196
197 /*!
198 * ======== EventDesc ========
199 * `Log` event descriptor
200 *
201 * Each `Log` event is defined by a `Log` event descriptor.
202 *
203 * The `mask` defines which bits in the module's diagnostics mask
204 * enable this `Log` event. Events "posted" via `Log_write` are only
205 * written to the underlying logger if one of the mask's bits matches
206 * the caller's module diagnostics settings (see
207 * `{@link xdc.runtime.Types#common$}`).
208 *
209 * The `msg` defines a printf style format string that defines how to
210 * render the arguments passed along the event in a `Log_write` call.
211 * For a description of the allowable format strings see
212 * `{@link #print6}`.
213 *
214 * @see #write8
215 * @see #print6
216 */
217 metaonlystruct EventDesc {
218 Diags.Mask mask; /*! event enable mask */
219 String msg; /*! event "printf" message format string */
220 };
221
222 /*!
223 * ======== EventRec ========
224 * The target representation of a recorded event
225 *
226 * This structure defines how events are recorded on the target.
227 */
228 struct EventRec {
229 Types.Timestamp64 tstamp; /*! time event was written */
230 Bits32 serial; /*! serial number of event */
231 Types.Event evt; /*! target encoding of an Event */
232 IArg arg[NUMARGS]; /*! arguments passed via Log_write/print */
233 }
234
235 /*!
236 * ======== Event ========
237 * `Log` event type
238 *
239 * An `Event` is represented on the target as a 32-bit value that can
240 * be decoded offline to recover the `Event` information defined in
241 * a corresponding metaonly `EventDesc`. In addition, `Event`s may be
242 * decoded at runtime via methods provided in this module; see
243 * `{@link #getMask}` and `{@link #getEventId}`.
244 *
245 * When an event is "raised" a `{@link Types#Event Types_Event}` is
246 * created which has the same event ID as the `Log_Event` but also
247 * encodes the module ID of the caller. This new event is passed to
248 * the underlying `{@link ILogger}` module along with any arguments
249 * associated with the event.
250 *
251 * @see #getMask
252 * @see #getEventId
253 */
254 @Encoded typedef EventDesc Event;
255
256 /*!
257 * ======== EventId ========
258 * Unique ID embedded in each `{@link #Event}`
259 *
260 * This ID must be used to compare two `Event`s for equality. Event
261 * ids are not guaranteed to remain constant between different
262 * configurations of an application. For example, adding a module
263 * may cause the event ids of another module to change.
264 *
265 * However, event ids declared by a module are guaranteed to be
266 * consecutive values starting from the first declared
267 * `{@link #Event Log_Event}` and increasing to the last declared
268 * event. As a result, clients of a module can efficiently test ranges
269 * of events and modules can add new events, such as internal trace
270 * events, without breaking clients; simply be careful to add new events
271 * after any existing events in you module's `.xdc` specification.
272 *
273 * @see #getEventId
274 * @see #Event
275 */
276 typedef Types.RopeId EventId;
277
278 /*!
279 * ======== L_construct ========
280 * Lifecycle event posted when an instance is constructed
281 */
282 config Log.Event L_construct = {
283 mask: Diags.LIFECYCLE, msg: "<-- construct: %p('%s')"
284 };
285
286 /*!
287 * ======== L_create ========
288 * Lifecycle event posted when an instance is created
289 */
290 config Log.Event L_create = {
291 mask: Diags.LIFECYCLE, msg: "<-- create: %p('%s')"
292 };
293
294 /*!
295 * ======== L_destruct ========
296 * Lifecycle event posted when an instance is destructed
297 */
298 config Log.Event L_destruct = {
299 mask: Diags.LIFECYCLE, msg: "--> destruct: (%p)"
300 };
301
302 /*!
303 * ======== L_delete ========
304 * Lifecycle event posted when an instance is deleted
305 */
306 config Log.Event L_delete = {
307 mask: Diags.LIFECYCLE, msg: "--> delete: (%p)"
308 };
309
310 /*!
311 * ======== getMask ========
312 * Get the `Diags` mask for the specified (encoded) event
313 *
314 * @param(evt) the `Log` event encoding a mask and event ID
315 *
316 * @a(returns) `Diags` mask for the specified event
317 */
318 @Macro Diags.Mask getMask(Event evt);
319
320 /*!
321 * ======== getRope ========
322 * Get RopeId of the Event.msg for the specified (encoded) event
323 * @_nodoc 324 */
325 @Macro Text.RopeId getRope(Event evt);
326
327 /*!
328 * ======== getEventId ========
329 * Get event ID of the specified (encoded) event
330 *
331 * This method is used to compare "known" `Log` events with
332 * "raised" `{@link Types#Event Types_Event}`.
333 *
334 * @param(evt) the `Log` event encoding a mask and event ID
335 *
336 * @a(returns) event ID of the specified event
337 *
338 * @see Types#getEventId
339 */
340 @Macro EventId getEventId(Event evt);
341
342 /*!
343 * ======== print0 ========
344 * Generate a `Log` "print event" with 0 arguments
345 *
346 * @see #print6
347 */
348 @Macro Void print0(Diags.Mask mask, String fmt);
349
350 /*!
351 * ======== print1 ========
352 * Generate a `Log` "print event" with 1 argument
353 *
354 * @see #print6
355 */
356 @Macro Void print1(Diags.Mask mask, String fmt, IArg a1);
357
358 /*!
359 * ======== print2 ========
360 * Generate a `Log` "print event" with 2 arguments
361 *
362 * @see #print6
363 */
364 @Macro Void print2(Diags.Mask mask, String fmt, IArg a1, IArg a2);
365
366 /*!
367 * ======== print3 ========
368 * Generate a `Log` "print event" with 3 arguments
369 *
370 * @see #print6
371 */
372 @Macro Void print3(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3);
373
374 /*!
375 * ======== print4 ========
376 * Generate a `Log` "print event" with 4 arguments
377 *
378 * @see #print6
379 */
380 @Macro Void print4(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3,
381 IArg a4);
382
383 /*!
384 * ======== print5 ========
385 * Generate a `Log` "print event" with 5 arguments
386 *
387 * @see #print6
388 */
389 @Macro Void print5(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3,
390 IArg a4, IArg a5);
391
392 /*!
393 * ======== print6 ========
394 * Generate a `Log` "print event" with 6 arguments
395 *
396 * As a convenience to C (as well as assembly language) programmers,
397 * the `Log` module provides a variation of the ever-popular `printf`
398 * function.
399 * The `print[0-6]` functions generate a `Log` "print event" and route
400 * it to the current module's logger.
401 *
402 * The arguments passed to `print[0-6]` may be characters, integers,
403 * strings, or pointers. However, because the declared type of the
404 * arguments is `{@link xdc IArg}`, all pointer arguments must be cast
405 * to an `IArg` type. `IArg` is an integral type large enough to hold
406 * any pointer or an `int`. So, casting a pointer to an `IArg` does
407 * not cause any loss of information and C's normal integer conversions
408 * make the cast unnecessary for integral arguments.
409 *
410 * The format string can use the following conversion characters.
411 * However, it is important to recall that all arguments referenced by
412 * these conversion characters have been converted to an `IArg`
413 * prior to conversion; so, the use of "length modifiers" should be
414 * avoided.
415 *
416 * @p(code) 417 * Conversion Character Description
418 * ------------------------------------------------
419 * %c Character
420 * %d Signed integer
421 * %u Unsigned integer
422 * %x Unsigned hexadecimal integer
423 * %o Unsigned octal integer
424 * %s Character string
425 * %p Pointer
426 * %f Single precision floating point (float)
427 * @p 428 *
429 * Format strings, while very convenient, are a well known source of
430 * portability problems: each format specification must precisely match
431 * the types of the arguments passed. Underlying "printf" functions use
432 * the format string to determine how far to advance through their
433 * argument list. For targets where pointer types and integers are the
434 * same size there are no problems. However, suppose a target's pointer
435 * type is larger than its integer type. In this case, because integer
436 * arguments are widened to be of type `IArg`, a format specification of
437 * "%d" causes an underlying `printf()` implementation to read the
438 * extended part of the integer argument as part of the next argument(!).
439 *
440 * To get around this problem and still allow the use of "natural"
441 * format specifications (e.g., `%d` and `%x` with optional width
442 * specifications), `{@link System#aprintf()}` is used which assumes
443 * that all arguments have been widened to be of type `IArg`.
444 *
445 * See `{@link System#printf}` for complete details.
446 *
447 * The `%f` format specifier is used to print a single precision float
448 * value. Note that `%f` assumes that sizeof(Float) <= sizeof(IArg).
449 * Most clients that interpret float values except that they are
450 * represented in IEEE 754 floating point format. Therefore, it is
451 * recommended that the float values are converted into that format prior
452 * to supplying the values to `Log` functions in cases where targets do
453 * not generate the float values in IEEE 754 floating point format by
454 * default.
455 *
456 * @param(mask) enable bits for this `Log` event
457 * @param(fmt) a `printf` style format string
458 * @param(a1) value for first format conversion character
459 * @param(a2) value for second format conversion character
460 * @param(a3) value for third format conversion character
461 * @param(a4) value for fourth format conversion character
462 * @param(a5) value for fifth format conversion character
463 * @param(a6) value for sixth format conversion character
464 *
465 * @a(Examples) 466 * The following example demonstrates a typical usage.
467 * @p(code) 468 * String list[];
469 * UInt i;
470 *
471 * Log_print2(Diags_USER2, "list[%u] = %s\n", i, (IArg)list[i]);
472 * @p 473 * Note that the `IArg` cast above is only necessary for pointer
474 * arguments; C's normal parameter conversions implicitly convert
475 * integral arguments.
476 */
477 @Macro Void print6(Diags.Mask mask, String fmt, IArg a1, IArg a2, IArg a3,
478 IArg a4, IArg a5, IArg a6);
479
480 /*!
481 * ======== put4 ========
482 * Unconditionally put the specified `Types` event
483 *
484 * This method unconditionally puts the specified `{@link Types#Event}`
485 * `evt` into the log. This type of event is created either implicitly
486 * (and passed to an `{@link ILogger}` implementation) or explicitly
487 * via `{@link Types#makeEvent()}`.
488 *
489 * @param(evt) the `Types` event to put into the log
490 * @param(a1) value for first format conversion character
491 * @param(a2) value for second format conversion character
492 * @param(a3) value for third format conversion character
493 * @param(a4) value for fourth format conversion character
494 *
495 * @see #put8
496 */
497 @Macro Void put4(Types.Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
498
499 /*!
500 * ======== put8 ========
501 * Unconditionally put the specified `Types` event
502 *
503 * This method is identical to `{@link #put4}` except that it allows
504 * up to eight arguments to be passed.
505 *
506 * @see #put4
507 */
508 @Macro Void put8(Types.Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
509 IArg a5, IArg a6, IArg a7, IArg a8);
510
511 /*!
512 * ======== write0 ========
513 * Generate a `Log` event with 0 arguments
514 *
515 * @see #write8
516 */
517 @Macro Void write0(Event evt);
518
519 /*!
520 * ======== write1 ========
521 * Generate a `Log` event with 1 argument
522 *
523 * @see #write8
524 */
525 @Macro Void write1(Event evt, IArg a1);
526
527 /*!
528 * ======== write2 ========
529 * Generate a `Log` event with 2 arguments
530 *
531 * @see #write8
532 */
533 @Macro Void write2(Event evt, IArg a1, IArg a2);
534
535 /*!
536 * ======== write3 ========
537 * Generate a `Log` event with 3 arguments
538 *
539 * @see #write8
540 */
541 @Macro Void write3(Event evt, IArg a1, IArg a2, IArg a3);
542
543 /*!
544 * ======== write4 ========
545 * Generate a `Log` event with 4 arguments
546 *
547 * @see #write8
548 */
549 @Macro Void write4(Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
550
551 /*!
552 * ======== write5 ========
553 * Generate a `Log` event with 5 arguments
554 *
555 * @see #write8
556 */
557 @Macro Void write5(Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
558
559 /*!
560 * ======== write6 ========
561 * Generate a `Log` event with 6 arguments
562 *
563 * @see #write8
564 */
565 @Macro Void write6(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
566 IArg a5, IArg a6);
567
568 /*!
569 * ======== write7 ========
570 * Generate a `Log` event with 7 arguments
571 *
572 * @see #write8
573 */
574 @Macro Void write7(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
575 IArg a5, IArg a6, IArg a7);
576
577 /*!
578 * ======== write8 ========
579 * Generate a `Log` event with 8 arguments
580 *
581 * If the mask in the specified `Log` event has any bit set which is
582 * also set in the current module's diagnostics mask, then this call to
583 * write will "raise" the given `Log` event.
584 *
585 * @param(evt) the `Log` event to write
586 * @param(a1) value for first format conversion character
587 * @param(a2) value for second format conversion character
588 * @param(a3) value for third format conversion character
589 * @param(a4) value for fourth format conversion character
590 * @param(a5) value for fifth format conversion character
591 * @param(a6) value for sixth format conversion character
592 * @param(a7) value for seventh format conversion character
593 * @param(a8) value for eighth format conversion character
594 */
595 @Macro Void write8(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
596 IArg a5, IArg a6, IArg a7, IArg a8);
597
598 /*!
599 * ======== doPrint ========
600 * Render an event as text via `{@link System#printf System_printf}`
601 *
602 * This method is not gated and may make more than one call to
603 * `System_printf`. This utility method is typically used within the
604 * implementation of a logger which initializes
605 * `{@link #EventRec Log_EventRec}` structures based on `Log` events
606 * produced by the application.
607 *
608 * @param(evRec) a non`NULL` pointer to an initialized `Log_EventRec`
609 * structure to be formated via
610 * `{@link System#printf System_printf}`.
611 */
612 Void doPrint(EventRec *evRec);
613
614 /*!
615 * @_nodoc 616 * ======== lookupEventMessage ========
617 * Returns the format string for the event with the given id.
618 */
619 function lookupEventMessage(eventId);
620
621 /*!
622 * @_nodoc 623 * ======== getTargetArgSize ========
624 * Returns the target size of a record argument in bytes (not MAUs).
625 */
626 function getTargetArgSize();
627
628 /*!
629 * @_nodoc 630 * ======== lookupEventName ========
631 */
632 function lookupEventName(eventId);
633
634 /*!
635 * @_nodoc 636 * ======== lookupModuleName ========
637 */
638 function lookupModuleName(modId);
639
640 /*!
641 * @_nodoc 642 * ======== getTargetEventRecSize ========
643 * Returns the record size in bytes (not MAUs).
644 */
645 function getTargetEventRecSize();
646
647 internal:
648
649 /*
650 * ======== idToInfo ========
651 * Map event ID strings into a string of the form <eventName>::<eventMsg>
652 */
653 metaonlyconfig String idToInfo[string] = [];
654
655 }
656 /*
657 * @(#) xdc.runtime; 2, 0, 0, 0,239; 6-9-2010 16:24:58; /db/ztree/library/trees/xdc/xdc-u18x/src/packages/
658 */
659