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