1 2 3 4 5 6 7 8 9 10 11 12
13 14 15
16
17 /*!
18 * ======== Log ========
19 * Event logging manager
20 *
21 * RTSC modules and the application code generate `{@link #Event Log_Event}`
22 * events by calling the `Log` module's functions. The `Log` module then
23 * passes those events to an `{@link ILogger}` instance assigned to the event
24 * originating module, specified by that module's configuration parameter
25 * `common$.logger`. `ILogger` instances handle events, usually converting
26 * events to `{@link #EventRec Log_EventRec}` records prior to recording,
27 * transmitting, or displaying them.
28 *
29 * All events generated by a target module are stored and displayed by an
30 * `ILogger`, examples of which are instances of
31 * `{@link LoggerBuf xdc.runtime.LoggerBuf}` or
32 * `{@link LoggerSys xdc.runtime.LoggerSys}`. At runtime, modules
33 * generate events through this module, rather than invoking directly their
34 * `ILogger`s. By doing so, modules can be configured to use different
35 * `ILogger` implementations without any changes to their source code.
36 *
37 * A logger instance can accept `Log` events from any module, but a module
38 * can put `Log` events to only one logger instance. There can be one or
39 * more logger instances in a system. All `Log` calls that are not in a
40 * module are controlled by the module `{@link Main xdc.runtime.Main}`.
41 * For example, top-level application code or any existing sources that
42 * simply call the `Log` or `Assert` methods implicitly use the logger
43 * associated with the `Main` module.
44 *
45 * The generation of a `Log` event is controlled by a module's diagnostics
46 * mask, which is described in details in `{@link Diags}`. Each `Log` event
47 * is associated with a mask. `Log` events are generated only when a
48 * particular bit is set in both the `Log` event mask and the module's
49 * diagnostics mask. For example, a `Log` event mask with the
50 * `{@link Diags#USER1 USER1}` bit set is generated only when the `USER1`
51 * bit is also set in the module's diagnostics mask.
52 *
53 * There are two ways to generate `Log` events:
54 *
55 * @p(blist)
56 * - `{@link #write8 Log_write()}`, which is tailored for module writers
57 * and takes full advantage of the XDC configuration model. For example,
58 * the message string associated with the `Log` event need not be a part of
59 * the final application, significantly reducing the "footprint overhead"
60 * of embedding diagnostics in deployed systems. The `Log_write[0-8]()`
61 * functions allow up to 8 values to be passed to the logger. They expect
62 * the logger to handle any formatting. A `Log` event type allows you to
63 * specify the type of event.
64 * - `{@link #print6 Log_print()}`, which is designed for arbitrary C code.
65 * The `Log_print[0-6]()` functions allow up to 6 values to be passed along
66 * with a printf-like format string to the logger. They handle printf-style
67 * formatting.
68 * @p
69 *
70 * Both functions are controlled by the module's diagnostics mask. Their
71 * storage or output is defined by the logger that is assigned to the
72 * module that calls the `Log` methods or to the
73 * `{@link Main xdc.runtime.Main}` module if the caller is not part of a
74 * module.
75 *
76 * The `Log` function call sites are implemented in such a way that an
77 * optimizer can completely eliminate `Log` code from the program if the
78 * `Log` functions have been permanently disabled at configuration time. If
79 * the `Log` functions are permanently turned on at configuration time,
80 * then the optimizer can eliminate all runtime conditional checking and
81 * simply invoke the `Log` functions directly. Runtime checking is performed
82 * only when the `Log` functions are configured to be runtime modifiable.
83 *
84 * The Log calls can also be completely removed by defining the symbol
85 * `xdc_runtime_Log_DISABLE_ALL`. This can be done on the compile line, e.g.
86 * `-Dxdc_runtime_Log_DISABLE_ALL`. This will completely remove the `Log`
87 * statements from any code compiled with this flag, regardless of the
88 * application's logging configuration or your compiler's optimization
89 * settings.
90 *
91 * It is also possible to remove all logging except for
92 * `{@link #error Log_error}`, `{@link #warning Log_warning}`, or
93 * `{@link #info Log_info}` statements. This is done by first defining
94 * `xdc_runtime_Log_DISABLE_ALL`, followed by defining one or more of the
95 * symbols below to leave that type of logging enabled:
96 * @p(blist)
97 * - `xdc_runtime_Log_ENABLE_ERROR`
98 * - `xdc_runtime_Log_ENABLE_WARNING`
99 * - `xdc_runtime_Log_ENABLE_INFO`
100 * @p
101 * For example, to disable all `Log` statements except for `Log_error`, add
102 * the following to the compile line:
103 * @p(code)
104 * -Dxdc_runtime_Log_DISABLE_ALL -Dxdc_runtime_Log_ENABLE_ERROR
105 * @p
106 *
107 * @a(Examples)
108 * Example 1: The following example defines a `Log` event, uses that `Log`
109 * event in a module, and configures the program to generate the `Log`
110 * event. In this example, both `USER1` and `USER2` bits are set in the
111 * event mask. This means that if either bit is set in the module's
112 * diagnostics mask, then the `Log` event will be generated.
113 *
114 * This is a part of the XDC specification file for the `Mod` module
115 * (Mod.xdc):
116 *
117 * @p(code)
118 * import xdc.runtime.Diags;
119 * import xdc.runtime.Log;
120 *
121 * config Log.Event L_someEvent = {
122 * mask: Diags.USER1 | Diags.USER2,
123 * level: Diags.LEVEL1,
124 * msg: "my log event message, arg1: 0x%x, arg2: 0x%x"
125 * };
126 * @p
127 *
128 * This is a part of the C code implementation of the Mod module:
129 *
130 * @p(code)
131 * #include <xdc/runtime/Log.h>
132 * UInt x, y;
133 *
134 * Log_write2(Mod_L_someEvent, (IArg)x, (IArg)y);
135 * @p
136 *
137 * The following configuration script demonstrates how the application might
138 * control the `Log` statements embedded in the `Mod` module at configuration
139 * time. In this case, the configuration script arranges for the `Log`
140 * statements within the `Mod` module (shown above) to always generate events.
141 * Without these configuration statements, no `Log` events would be generated
142 * by this module.
143 *
144 * This is part of the XDC configuration file for the application:
145 *
146 * @p(code)
147 * var Diags = xdc.useModule('xdc.runtime.Diags');
148 * var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
149 * var Mod = xdc.useModule('my.pkg.Mod');
150 * Mod.common$.diags_USER1 = Diags.ALWAYS_ON;
151 * Mod.common$.logger = LoggerSys.create();
152 * @p
153 *
154 * @p(html)
155 * <hr />
156 * @p
157 *
158 * Example 2: The following XDC configuration statements turn on enter
159 * and exit logging at configuration time for a module. Without any other
160 * changes in the runtime code, every time a module `Mod`'s function is
161 * being called or exits, an event will be logged.
162 *
163 * @p(code)
164 * var Diags = xdc.useModule('xdc.runtime.Diags');
165 * var Mod = xdc.useModule('my.pkg.Mod');
166 *
167 * Mod.common$.diags_ENTER = Diags.ALWAYS_ON;
168 * Mod.common$.diags_EXIT = Diags.ALWAYS_ON;
169 * @p
170 *
171 * @p(html)
172 * <hr />
173 * @p
174 *
175 * Example 3: The following example configures a module to support enter and
176 * exit logging, but defers the actual activation and deactivation of the
177 * logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
178 * function for details on specifying the control string.
179 *
180 * This is a part of the XDC configuration file for the application:
181 *
182 * @p(code)
183 * var Diags = xdc.useModule('xdc.runtime.Diags');
184 * var Mod = xdc.useModule('my.pkg.Mod');
185 *
186 * Mod.common$.diags_ENTER = Diags.RUNTIME_OFF;
187 * Mod.common$.diags_EXIT = Diags.RUNTIME_OFF;
188 * @p
189 *
190 * This is a part of the C code for the application:
191 *
192 * @p(code)
193 * // turn on enter and exit logging in the module
194 * Diags_setMask("my.pkg.Mod+EX");
195 *
196 * // turn off enter and exit logging in the module
197 * Diags_setMask("my.pkg.Mod-EX");
198 * @p
199 */
200
201 @CustomHeader
202 @DirectCall
203 @RomConsts
204
205 module Log {
206
207 /*!
208 * ======== NUMARGS ========
209 * Maximum number of arguments supported in `Log` events.
210 */
211 const Int NUMARGS = 8;
212
213 /*!
214 * ======== PRINTFID ========
215 * The `EventId` for `Log_print()` events
216 */
217 const EventId PRINTFID = 0;
218
219 /*!
220 * ======== EventDesc ========
221 * `Log` event descriptor
222 *
223 * Each `Log` event is defined by a `Log` event descriptor.
224 *
225 * The `mask` defines which bits in the module's diagnostics mask
226 * enable this `Log` event. Events "posted" via `Log_write` are only
227 * written to the underlying logger if one of the mask's bits matches
228 * the caller's module diagnostics settings (see
229 * `{@link xdc.runtime.Types#common$}`).
230 *
231 * The 'level' defines the event level of the event. While the diags
232 * bits selected in the 'mask' signify the "category" of the event (e.g.
233 * Entry/Exit, Analysis, Info), the 'level' field allows you to assign
234 * a "priority" or "detail level" to the event relative to other events in
235 * that category. There are four event levels defined by
236 * '{@link xdc.runtime.Diags#EventLevel}'.
237 *
238 * Filtering of events by level is handled by the ILogger implementation.
239 * ILogger implementations which also implement the {@link IFilterLogger}
240 * interface support filtering of events based on priority level.
241 *
242 * Specifying an event level is optional. Events that don't specify a
243 * level will receive Diags.LEVEL1 by default, making them the highest
244 * priority and ensuring that they will not inadvertently be filtered out
245 * by level-based filtering.
246 *
247 * The `msg` defines a printf style format string that defines how to
248 * render the arguments passed along the event in a `Log_write` call.
249 * For a description of the allowable format strings see
250 * `{@link #print6}`.
251 *
252 * @see #write8
253 * @see #print6
254 */
255 metaonly struct EventDesc {
256 Diags.Mask mask; /*! event enable mask */
257 Diags.EventLevel level; /*! event level relative to other events */
258 String msg; /*! event "printf" message format string */
259 };
260
261 /*!
262 * ======== EventRec ========
263 * The target representation of a recorded event
264 *
265 * This structure defines how events are recorded on the target.
266 */
267 struct EventRec {
268 Types.Timestamp64 tstamp; /*! time event was written */
269 Bits32 serial; /*! serial number of event */
270 Types.Event evt; /*! target encoding of an Event */
271 IArg arg[NUMARGS]; /*! arguments passed via Log_write/print */
272 }
273
274 /*!
275 * ======== Event ========
276 * `Log` event type
277 *
278 * An `Event` is represented on the target as a 32-bit value that can
279 * be decoded offline to recover the `Event` information defined in
280 * a corresponding metaonly `EventDesc`. In addition, `Event`s may be
281 * decoded at runtime via methods provided in this module; see
282 * `{@link #getMask}` and `{@link #getEventId}`.
283 *
284 * When an event is "raised" a `{@link Types#Event Types_Event}` is
285 * created which has the same event ID as the `Log_Event` but also
286 * encodes the module ID of the caller. This new event is passed to
287 * the underlying `{@link ILogger}` module along with any arguments
288 * associated with the event.
289 *
290 * @see #getMask
291 * @see #getEventId
292 */
293 @Encoded typedef EventDesc Event;
294
295 /*!
296 * ======== EventId ========
297 * Unique ID embedded in each `{@link #Event}`
298 *
299 * This ID must be used to compare two `Event`s for equality. Event
300 * ids are not guaranteed to remain constant between different
301 * configurations of an application. For example, adding a module
302 * may cause the event ids of another module to change.
303 *
304 * However, event ids declared by a module are guaranteed to be
305 * consecutive values starting from the first declared
306 * `{@link #Event Log_Event}` and increasing to the last declared
307 * event. As a result, clients of a module can efficiently test ranges
308 * of events and modules can add new events, such as internal trace
309 * events, without breaking clients; simply be careful to add new events
310 * after any existing events in you module's `.xdc` specification.
311 *
312 * @see #getEventId
313 * @see #Event
314 */
315 typedef Types.RopeId EventId;
316
317 /*!
318 * ======== L_construct ========
319 * Lifecycle event posted when an instance is constructed
320 */
321 config Log.Event L_construct = {
322 mask: Diags.LIFECYCLE,
323 msg: "<-- construct: %p('%s')"
324 };
325
326 /*!
327 * ======== L_create ========
328 * Lifecycle event posted when an instance is created
329 */
330 config Log.Event L_create = {
331 mask: Diags.LIFECYCLE,
332 msg: "<-- create: %p('%s')"
333 };
334
335 /*!
336 * ======== L_destruct ========
337 * Lifecycle event posted when an instance is destructed
338 */
339 config Log.Event L_destruct = {
340 mask: Diags.LIFECYCLE,
341 msg: "--> destruct: (%p)"
342 };
343
344 /*!
345 * ======== L_delete ========
346 * Lifecycle event posted when an instance is deleted
347 */
348 config Log.Event L_delete = {
349 mask: Diags.LIFECYCLE,
350 msg: "--> delete: (%p)"
351 };
352
353 /*!
354 * ======== L_error ========
355 * Error event posted by Log_errorX API
356 *
357 * This event is marked as a STATUS event and given the priority level
358 * of ERROR.
359 *
360 * This event prints the Log call site (%$F) and a format string (%$S)
361 * which is recursively formatted with any additional arguments.
362 */
363 config Log.Event L_error = {
364 mask: Diags.STATUS,
365 level: Diags.ERROR,
366 msg: "ERROR: %$F%$S"
367 };
368
369 /*!
370 * ======== L_warning ========
371 * Warning event posted by Log_warningX API
372 *
373 * This event is marked as a STATUS event and given the priority level of
374 * WARNING.
375 *
376 * This event prints the Log call site (%$F) and a format string (%$S)
377 * which is recursively formatted with any addition arguments.
378 */
379 config xdc.runtime.Log.Event L_warning = {
380 mask: Diags.STATUS,
381 level: Diags.WARNING,
382 msg: "WARNING: %$F%$S"
383 };
384
385 /*!
386 * ======== L_info ========
387 * Info event posted by Log_infoX API
388 *
389 * This event is marked as an INFO event. The event priority is not
390 * specified in the event definition. Rather, it is specified as an
391 * argument to the Log_infoX APIs.
392 *
393 * This event prints the Log call site (%$F) and a format string (%$S)
394 * which is recursively formatted with any addition arguments.
395 */
396 config xdc.runtime.Log.Event L_info = {
397 mask: Diags.INFO,
398 msg: "%$F%$S"
399 };
400
401 /*!
402 * ======== L_start ========
403 * Benchmark event used to log the start of an operation
404 * @_nodoc
405 *
406 * @a(Example)
407 * The following C code shows how to log a simple
408 * benchmark 'start' event along with a user-specified
409 * format string describing the event.
410 *
411 * @p(code)
412 * #include <xdc/runtime/Log.h>
413 * ...
414 * Log_write2(Log_L_start, (IArg)"My benchmark event", (IArg)myUniqueId);
415 * Log_write2(Log_L_stop, (IArg)"My benchmark event", (IArg)myUniqueId);
416 * @p
417 *
418 * @param(fmt) a constant string that provides format specifiers for
419 * up to 6 additional parameters
420 * @param(id) a unique ID used to match benchmark start and stop
421 * events
422 */
423 config xdc.runtime.Log.Event L_start = {
424 mask: Diags.ANALYSIS,
425 msg: "Start: %$S"};
426
427 /*!
428 * ======== L_stop ========
429 * Benchmark event used to log the end of an operation
430 * @_nodoc
431 *
432 * @a(Example)
433 * The following C code shows how to log a simple
434 * benchmark 'stop' event along with a user-specified
435 * format string describing the event.
436 *
437 * @p(code)
438 * #include <xdc/runtime/Log.h>
439 * ...
440 * Log_write2(Log_L_start, (IArg)"My benchmark event", (IArg)myUniqueId);
441 * Log_write2(Log_L_stop, (IArg)"My benchmark event", (IArg)myUniqueId);
442 * @p
443 *
444 * @param(fmt) a constant string that provides format specifiers for
445 * up to 6 additional parameters
446 * @param(id) a unique ID used to match benchmark start and stop
447 * events
448 */
449 config xdc.runtime.Log.Event L_stop = {
450 mask: Diags.ANALYSIS,
451 msg: "Stop: %$S"};
452
453 /*!
454 * ======== L_startInstance ========
455 * Benchmark event used to log the start of an operation instance
456 * @_nodoc
457 *
458 * Event parameter provides instance data to differentiate
459 * between multiple instances that can run in parallel.
460 *
461 * @a(Example)
462 * The following C code shows how to log a benchmark
463 * 'startInstance' event along with a user-specified
464 * instance identifier and a format string describing the event.
465 *
466 * @p(code)
467 * #include <xdc/runtime/Log.h>
468 * ...
469 * Log_write3(Log_L_startInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
470 * ...
471 * Log_write3(Log_L_stopInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
472 * @p
473 *
474 * @param(fmt) a constant string that provides format specifiers for
475 * up to 6 additional parameters
476 * @param(id) a unique ID used to match benchmark start and stop
477 * events
478 * @param(instId) a unique instance ID that can be used to match
479 * instance events
480 */
481 config xdc.runtime.Log.Event L_startInstance = {
482 mask: Diags.ANALYSIS,
483 msg: "StartInstance: %$S"
484 };
485
486 /*!
487 * ======== L_stopInstance ========
488 * Benchmark event used to log the end of an operation instance
489 * @_nodoc
490 *
491 * Event parameter provides instance data to differentiate
492 * between multiple instances that can run in parallel.
493 *
494 * @a(Example)
495 * The following C code shows how to log a benchmark
496 * 'stopInstance' event along with a user-specified
497 * instance identifier and a format string describing the event.
498 *
499 * @p(code)
500 * #include <xdc/runtime/Log.h>
501 * ...
502 * Log_write3(Log_L_startInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
503 * ...
504 * Log_write3(Log_L_stopInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
505 * @p
506 *
507 * @param(fmt) a constant string that provides format specifiers for
508 * up to 6 additional parameters
509 * @param(id) a unique ID used to match benchmark start and stop
510 * events
511 * @param(instId) a unique instance ID that can be used to match
512 * instance events
513 */
514 config xdc.runtime.Log.Event L_stopInstance = {
515 mask: Diags.ANALYSIS,
516 msg: "StopInstance: %$S"
517 };
518
519 /*!
520 * ======== getMask ========
521 * Get the `Diags` mask for the specified (encoded) event
522 *
523 * @param(evt) the `Log` event encoding a mask and event ID
524 *
525 * @a(returns) `Diags` mask for the specified event
526 */
527 @Macro Diags.Mask getMask(Event evt);
528
529 /*!
530 * ======== getRope ========
531 * Get RopeId of the Event.msg for the specified (encoded) event
532 * @_nodoc
533 */
534 @Macro Text.RopeId getRope(Event evt);
535
536 /*!
537 * ======== getEventId ========
538 * Get event ID of the specified (encoded) event
539 *
540 * This method is used to compare "known" `Log` events with
541 * "raised" `{@link Types#Event Types_Event}`.
542 *
543 * @param(evt) the `Log` event encoding a mask and event ID
544 *
545 * @a(returns) event ID of the specified event
546 *
547 * @see Types#getEventId
548 */
549 @Macro EventId getEventId(Event evt);
550
551 /*!
552 * ======== print0 ========
553 * Generate a `Log` "print event" with 0 arguments
554 *
555 * @see #print6
556 */
557 @Macro Void print0(Diags.Mask mask, CString fmt);
558
559 /*!
560 * ======== print1 ========
561 * Generate a `Log` "print event" with 1 argument
562 *
563 * @see #print6
564 */
565 @Macro Void print1(Diags.Mask mask, CString fmt, IArg a1);
566
567 /*!
568 * ======== print2 ========
569 * Generate a `Log` "print event" with 2 arguments
570 *
571 * @see #print6
572 */
573 @Macro Void print2(Diags.Mask mask, CString fmt, IArg a1, IArg a2);
574
575 /*!
576 * ======== print3 ========
577 * Generate a `Log` "print event" with 3 arguments
578 *
579 * @see #print6
580 */
581 @Macro Void print3(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
582 IArg a3);
583
584 /*!
585 * ======== print4 ========
586 * Generate a `Log` "print event" with 4 arguments
587 *
588 * @see #print6
589 */
590 @Macro Void print4(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
591 IArg a3, IArg a4);
592
593 /*!
594 * ======== print5 ========
595 * Generate a `Log` "print event" with 5 arguments
596 *
597 * @see #print6
598 */
599 @Macro Void print5(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
600 IArg a3, IArg a4, IArg a5);
601
602 /*!
603 * ======== print6 ========
604 * Generate a `Log` "print event" with 6 arguments
605 *
606 * As a convenience to C (as well as assembly language) programmers,
607 * the `Log` module provides a variation of the ever-popular `printf`
608 * function.
609 * The `print[0-6]` functions generate a `Log` "print event" and route
610 * it to the current module's logger.
611 *
612 * The arguments passed to `print[0-6]` may be characters, integers,
613 * strings, or pointers. However, because the declared type of the
614 * arguments is `{@link xdc IArg}`, all pointer arguments must be cast
615 * to an `IArg` type. `IArg` is an integral type large enough to hold
616 * any pointer or an `int`. So, casting a pointer to an `IArg` does
617 * not cause any loss of information and C's normal integer conversions
618 * make the cast unnecessary for integral arguments.
619 *
620 * The format string can use the following conversion characters.
621 * However, it is important to recall that all arguments referenced by
622 * these conversion characters have been converted to an `IArg`
623 * prior to conversion; so, the use of "length modifiers" should be
624 * avoided.
625 *
626 * @p(code)
627 * Conversion Character Description
628 * ------------------------------------------------
629 * %c Character
630 * %d Signed integer
631 * %u Unsigned integer
632 * %x Unsigned hexadecimal integer
633 * %o Unsigned octal integer
634 * %s Character string
635 * %p Pointer
636 * %f Single precision floating point (float)
637 * @p
638 *
639 * Format strings, while very convenient, are a well known source of
640 * portability problems: each format specification must precisely match
641 * the types of the arguments passed. Underlying "printf" functions use
642 * the format string to determine how far to advance through their
643 * argument list. For targets where pointer types and integers are the
644 * same size there are no problems. However, suppose a target's pointer
645 * type is larger than its integer type. In this case, because integer
646 * arguments are widened to be of type `IArg`, a format specification of
647 * "%d" causes an underlying `printf()` implementation to read the
648 * extended part of the integer argument as part of the next argument(!).
649 *
650 * To get around this problem and still allow the use of "natural"
651 * format specifications (e.g., `%d` and `%x` with optional width
652 * specifications), `{@link System#aprintf()}` is used which assumes
653 * that all arguments have been widened to be of type `IArg`.
654 *
655 * See `{@link System#printf}` for complete details.
656 *
657 * The `%f` format specifier is used to print a single precision float
658 * value. Note that `%f` assumes that sizeof(Float) <= sizeof(IArg).
659 * Most clients that interpret float values expect that they are
660 * represented in IEEE 754 floating point format. Therefore, it is
661 * recommended that the float values be converted into that format prior
662 * to supplying the values to `Log` functions in cases where targets do
663 * not generate the float values in IEEE 754 floating point format by
664 * default.
665 *
666 * The first argument to a `Log_print` call is the diags category to be
667 * associated with the event.
668 *
669 * It is also possible to associate an event level with the event to
670 * enable filtering of events based on event level. Conceptually, it is
671 * best to regard the event level as completely separate from the event's
672 * diags category; however, the priority value actually occupies a part
673 * of the diags mask. For this reason, it is possible to specify an event
674 * level by OR'ing the level with the diags mask. For example, to print
675 * an `Diags_INFO` event of `Diags_LEVEL2`, you'd simply write:
676 * (Diags_INFO | Diags_LEVEL2)
677 *
678 * Specifying an event level is optional. `Log_print` calls which do not
679 * specify a level will receive the highest priority by default.
680 *
681 * @param(mask) enable bits and optional detail level for this event
682 * @param(fmt) a `printf` style format string
683 * @param(a1) value for first format conversion character
684 * @param(a2) value for second format conversion character
685 * @param(a3) value for third format conversion character
686 * @param(a4) value for fourth format conversion character
687 * @param(a5) value for fifth format conversion character
688 * @param(a6) value for sixth format conversion character
689 *
690 * @a(Examples)
691 * The following example demonstrates a typical usage.
692 * @p(code)
693 * String list[];
694 * UInt i;
695 *
696 * Log_print2(Diags_USER2, "list[%u] = %s\n", i, (IArg)list[i]);
697 * @p
698 * Note that the `IArg` cast above is only necessary for pointer
699 * arguments; C's normal parameter conversions implicitly convert
700 * integral arguments.
701 *
702 * To simplify the conversion from `float` arguments to `IArg`,
703 * the standard header `xdc/std.h` provides a macro, named floatToArg(),
704 * to do this conversion in a type safe manner. So, the following
705 * statement will print "`float = 2.3456`":
706 * @p(code)
707 * Log_print1(Diags_USER1, "float = %f", floatToArg(2.34567));
708 * @p
709 *
710 * Note that, if you are formatting events on the target, you must
711 * also add support for floating point to ASCII conversion to
712 * `{@link System#printf}`; for more information, see the
713 * `{@link System#extendedFormats}` reference documenation. For example:
714 * @p(code)
715 * var System = xdc.useModule('xdc.runtime.System');
716 * System.extendedFormats = "%f";
717 * @p
718 */
719 @Macro Void print6(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
720 IArg a3, IArg a4, IArg a5, IArg a6);
721
722 /*!
723 * ======== error0 ========
724 * Generate a `Log` "error event" with 0 arguments
725 *
726 * @see #error5
727 */
728 @Macro Void error0(CString fmt);
729
730 /*!
731 * ======== error1 ========
732 * Generate a `Log` "error event" with 1 argument
733 *
734 * @see #error5
735 */
736 @Macro Void error1(CString fmt, IArg a1);
737
738 /*!
739 * ======== error2 ========
740 * Generate a `Log` "error event" with 2 arguments
741 *
742 * @see #error5
743 */
744 @Macro Void error2(CString fmt, IArg a1, IArg a2);
745
746 /*!
747 * ======== error3 ========
748 * Generate a `Log` "error event" with 3 arguments
749 *
750 * @see #error5
751 */
752 @Macro Void error3(CString fmt, IArg a1, IArg a2, IArg a3);
753
754 /*!
755 * ======== error4 ========
756 * Generate a `Log` "error event" with 4 arguments
757 *
758 * @see #error5
759 */
760 @Macro Void error4(CString fmt, IArg a1, IArg a2, IArg a3,
761 IArg a4);
762
763 /*!
764 * ======== error5 ========
765 * Generate a `Log` "error event" with 5 arguments
766 *
767 * The Log_error APIs are intended to allow users to easily log error
768 * events in their code. Similar to the Log_print APIs, Log_error does not
769 * require that you define an event. You simply pass an informative error
770 * string which can optionally be formatted with additional arguments. The
771 * error is logged with the predefined event {@link #L_error}.
772 *
773 * Log_error prepends a string to the message which identifies it as an
774 * ERROR and specifies the filename and line number of the Log_error call
775 * site. A simple example:
776 *
777 * @p(code)
778 * Log_error0("Invalid argument");
779 * @p
780 * This event will be formatted as (assuming that the above call was line
781 * 35 of "MyCode.c")
782 * @p(code)
783 * ERROR at "MyCode.c", line 35: Invalid argument
784 * @p
785 *
786 * Users may provide additional information in the error event, such as
787 * a predefined error code or details of the error. These additional
788 * values will be used to format the string passed to Log_error.
789 * @see #print6 for information about format strings.
790 *
791 * Log_error does not use a variable length argument list--you must call
792 * the appropriate Log_errorX API based on the number of arguments.
793 *
794 * @param(fmt) a reference to a constant error string / fmt string
795 * @param(a1) value for an additional parameter (e.g. an error code)
796 * @param(a2) value for an additional parameter
797 * @param(a3) value for an additional parameter
798 * @param(a4) value for an additional parameter
799 * @param(a5) value for an additional parameter
800 *
801 * @a(Examples)
802 * The following example demonstrates a typical usage.
803 * @p(code)
804 * Int myArg;
805 *
806 * Log_error1("Invalid argument: %d", myArg);
807 * @p
808 * The above event is formatted as, for example:
809 * @p(code)
810 * ERROR: "MyCode.c", line 35: Invalid argument: -1
811 * @p
812 */
813 @Macro Void error5(CString fmt, IArg a1, IArg a2, IArg a3,
814 IArg a4, IArg a5);
815
816 /*!
817 * ======== warning0 ========
818 * Generate a `Log` "warning event" with 0 arguments
819 *
820 * @see #warning5
821 */
822 @Macro Void warning0(CString fmt);
823
824 /*!
825 * ======== warning1 ========
826 * Generate a `Log` "warning event" with 1 argument
827 *
828 * @see #warning5
829 */
830 @Macro Void warning1(CString fmt, IArg a1);
831
832 /*!
833 * ======== warning2 ========
834 * Generate a `Log` "warning event" with 2 arguments
835 *
836 * @see #warning5
837 */
838 @Macro Void warning2(CString fmt, IArg a1, IArg a2);
839
840 /*!
841 * ======== warning3 ========
842 * Generate a `Log` "warning event" with 3 arguments
843 *
844 * @see #warning5
845 */
846 @Macro Void warning3(CString fmt, IArg a1, IArg a2, IArg a3);
847
848 /*!
849 * ======== warning4 ========
850 * Generate a `Log` "warning event" with 4 arguments
851 *
852 * @see #warning5
853 */
854 @Macro Void warning4(CString fmt, IArg a1, IArg a2, IArg a3,
855 IArg a4);
856
857 /*!
858 * ======== warning5 ========
859 * Generate a `Log` "warning event" with 5 arguments
860 *
861 * The Log_warning APIs provide the same features as the Log_error APIs,
862 * but are used to specifically log "warning" events.
863 * @see #error5
864 *
865 * The Log_warning APIs are equivalent to the Log_error APIs except that
866 * they use the predefined {@link #L_warning} event. Log_warning prepends
867 * a string to the message which identifies it as a WARNING and specifies
868 * the filename and line number of the Log_warning call site.
869 *
870 * @param(fmt) reference to a constant warning string / fmt string
871 * @param(a1) value for an additional parameter (e.g. a warning code)
872 * @param(a2) value for an additional parameter
873 * @param(a3) value for an additional parameter
874 * @param(a4) value for an additional parameter
875 * @param(a5) value for an additional parameter
876 *
877 * @a(Examples)
878 * The following example demonstrates a typical usage.
879 * @p(code)
880 * Int myArg;
881 *
882 * Log_warning1("Value may be too high: %d", myArg);
883 * @p
884 * The above event is formatted as:
885 * @p(code)
886 * WARNING: "MyCode.c", line 50: Value may be too high: 4096
887 * @p
888 */
889 @Macro Void warning5(CString fmt, IArg a1, IArg a2, IArg a3,
890 IArg a4, IArg a5);
891
892 /*!
893 * ======== info0 ========
894 * Generate a `Log` "info event" with 0 arguments
895 *
896 * @see #info5
897 */
898 @Macro Void info0(CString fmt);
899
900 /*!
901 * ======== info1 ========
902 * Generate a `Log` "info event" with 1 argument
903 *
904 * @see #info5
905 */
906 @Macro Void info1(CString fmt, IArg a1);
907
908 /*!
909 * ======== info2 ========
910 * Generate a `Log` "info event" with 2 arguments
911 *
912 * @see #info5
913 */
914 @Macro Void info2(CString fmt, IArg a1, IArg a2);
915
916 /*!
917 * ======== info3 ========
918 * Generate a `Log` "info event" with 3 arguments
919 *
920 * @see #info5
921 */
922 @Macro Void info3(CString fmt, IArg a1, IArg a2, IArg a3);
923
924 /*!
925 * ======== info4 ========
926 * Generate a `Log` "info event" with 4 arguments
927 *
928 * @see #info5
929 */
930 @Macro Void info4(CString fmt, IArg a1, IArg a2, IArg a3, IArg a4);
931
932 /*!
933 * ======== info5 ========
934 * Generate a `Log` "info event" with 5 arguments
935 *
936 * The Log_info APIs are provided for easily logging generic
937 * "informational" events with call site information. They are similar to
938 * the Log_print APIs in that they do not require you to define an event--
939 * you simply pass an informative printf-style string which can optionally
940 * be formatted with additional arguments. The info record is logged with
941 * the predefined event '{@link #L_info}'.
942 *
943 * The Log_info APIs log the {@link #L_info} event which uses the 'INFO'
944 * diags category. They do not allow you to specify an event priority.
945 *
946 * Log_info prepends the filename and line number of the call site to the
947 * message.
948 *
949 * @param(fmt) reference to a constant event string / fmt string
950 * @param(a1) value for an additional parameter (e.g. an event code)
951 * @param(a2) value for an additional parameter
952 * @param(a3) value for an additional parameter
953 * @param(a4) value for an additional parameter
954 * @param(a5) value for an additional parameter
955 *
956 * @a(Examples)
957 * The following example demonstrates a typical usage.
958 * @p(code)
959 * Int load;
960 *
961 * Log_info1("Current load: %d", load);
962 * @p
963 * The above event is formatted as, for example:
964 * @p(code)
965 * "MyCode.c", line 15: Current load: 25
966 * @p
967 */
968 @Macro Void info5(CString fmt, IArg a1, IArg a2, IArg a3, IArg a4,
969 IArg a5);
970
971 /*!
972 * ======== put0 ========
973 * Unconditionally put the specified Log event with 0 arguments
974 *
975 * @see #put8
976 */
977 @Macro Void put0(Log.Event evt, Types.ModuleId mid);
978
979 /*!
980 * ======== put1 ========
981 * Unconditionally put the specified Log event and 1 argument
982 *
983 * @see #put8
984 */
985 @Macro Void put1(Log.Event evt, Types.ModuleId mid, IArg a1);
986
987 /*!
988 * ======== put2 ========
989 * Unconditionally put the specified Log event and 2 arguments
990 *
991 * @see #put8
992 */
993 @Macro Void put2(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2);
994
995 /*!
996 * ======== put4 ========
997 * Unconditionally put the specified Log event and 4 arguments
998 *
999 * @see #put8
1000 */
1001 @Macro Void put4(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
1002 IArg a3, IArg a4);
1003
1004 /*!
1005 * ======== put8 ========
1006 * Unconditionally put the specified Log event and 8 arguments
1007 *
1008 * This method unconditionally puts the specified `{@link Event}`
1009 * `evt` into the log. The `{@link Types#ModuleId}` `mid` should be the
1010 * module ID of the module which is putting the event.
1011 *
1012 * @param(evt) the Log event to put into the log
1013 * @param(mid) module ID of the module putting the event
1014 * @param(a1) value for first format conversion character
1015 * @param(a2) value for second format conversion character
1016 * @param(a3) value for third format conversion character
1017 * @param(a4) value for fourth format conversion character
1018 * @param(a5) value for fifth format conversion character
1019 * @param(a6) value for sixth format conversion character
1020 * @param(a7) value for seventh format conversion character
1021 * @param(a8) value for eighth format conversion character
1022 */
1023 @Macro Void put8(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
1024 IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8);
1025
1026 /*!
1027 * ======== write0 ========
1028 * Generate a `Log` event with 0 arguments
1029 *
1030 * @see #write8
1031 */
1032 @Macro Void write0(Event evt);
1033
1034 /*!
1035 * ======== write1 ========
1036 * Generate a `Log` event with 1 argument
1037 *
1038 * @see #write8
1039 */
1040 @Macro Void write1(Event evt, IArg a1);
1041
1042 /*!
1043 * ======== write2 ========
1044 * Generate a `Log` event with 2 arguments
1045 *
1046 * @see #write8
1047 */
1048 @Macro Void write2(Event evt, IArg a1, IArg a2);
1049
1050 /*!
1051 * ======== write3 ========
1052 * Generate a `Log` event with 3 arguments
1053 *
1054 * @see #write8
1055 */
1056 @Macro Void write3(Event evt, IArg a1, IArg a2, IArg a3);
1057
1058 /*!
1059 * ======== write4 ========
1060 * Generate a `Log` event with 4 arguments
1061 *
1062 * @see #write8
1063 */
1064 @Macro Void write4(Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
1065
1066 /*!
1067 * ======== write5 ========
1068 * Generate a `Log` event with 5 arguments
1069 *
1070 * @see #write8
1071 */
1072 @Macro Void write5(Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
1073
1074 /*!
1075 * ======== write6 ========
1076 * Generate a `Log` event with 6 arguments
1077 *
1078 * @see #write8
1079 */
1080 @Macro Void write6(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
1081 IArg a5, IArg a6);
1082
1083 /*!
1084 * ======== write7 ========
1085 * Generate a `Log` event with 7 arguments
1086 *
1087 * @see #write8
1088 */
1089 @Macro Void write7(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
1090 IArg a5, IArg a6, IArg a7);
1091
1092 /*!
1093 * ======== write8 ========
1094 * Generate a `Log` event with 8 arguments
1095 *
1096 * If the mask in the specified `Log` event has any bit set which is
1097 * also set in the current module's diagnostics mask, then this call to
1098 * write will "raise" the given `Log` event.
1099 *
1100 * @param(evt) the `Log` event to write
1101 * @param(a1) value for first format conversion character
1102 * @param(a2) value for second format conversion character
1103 * @param(a3) value for third format conversion character
1104 * @param(a4) value for fourth format conversion character
1105 * @param(a5) value for fifth format conversion character
1106 * @param(a6) value for sixth format conversion character
1107 * @param(a7) value for seventh format conversion character
1108 * @param(a8) value for eighth format conversion character
1109 */
1110 @Macro Void write8(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
1111 IArg a5, IArg a6, IArg a7, IArg a8);
1112
1113 /*!
1114 * ======== doPrint ========
1115 * Render an event as text via `{@link System#printf System_printf}`
1116 *
1117 * This method is not gated and may make more than one call to
1118 * `System_printf`. This utility method is typically used within the
1119 * implementation of a logger which initializes
1120 * `{@link #EventRec Log_EventRec}` structures based on `Log` events
1121 * produced by the application.
1122 *
1123 * @param(evRec) a non`NULL` pointer to an initialized `Log_EventRec`
1124 * structure to be formated via
1125 * `{@link System#printf System_printf}`.
1126 */
1127 Void doPrint(EventRec *evRec);
1128
1129 /*!
1130 * @_nodoc
1131 * ======== lookupEventMessage ========
1132 * Returns the format string for the event with the given id.
1133 */
1134 function lookupEventMessage(eventId);
1135
1136 /*!
1137 * @_nodoc
1138 * ======== getTargetArgSize ========
1139 * Returns the target size of a record argument in bytes (not MAUs).
1140 */
1141 function getTargetArgSize();
1142
1143 /*!
1144 * @_nodoc
1145 * ======== lookupEventName ========
1146 */
1147 function lookupEventName(eventId);
1148
1149 /*!
1150 * @_nodoc
1151 * ======== lookupModuleName ========
1152 */
1153 function lookupModuleName(modId);
1154
1155 /*!
1156 * @_nodoc
1157 * ======== getTargetEventRecSize ========
1158 * Returns the record size in bytes (not MAUs).
1159 */
1160 function getTargetEventRecSize();
1161
1162 internal:
1163
1164 1165 1166 1167
1168 metaonly config String idToInfo[string] = [];
1169 }
1170 1171 1172
1173