1 2 3 4 5 6 7 8 9 10 11 12
13 14 15
16
17 package xdc.runtime;
18
19 /*!
20 * ======== System ========
21 * Basic system services
22 *
23 * This module provides basic low-level "system" services; e.g.,
24 * character output, `printf`-like output, and exit handling.
25 *
26 * This module is gated and other modules use its gate via the
27 * `{@link Gate#enterSystem}` and `{@link Gate#leaveSystem}`. The `System`
28 * gate must be enterable by any thread in a multi-threaded environments. For
29 * example, in many real-time multi-threaded environments some types of
30 * threads, such as Interrupt Service Routines (ISRs), are not allowed to call
31 * operations that block the caller. In such an environment, either the
32 * `System` gate must disable all interrupts or ISRs must never call a function
33 * in the `xdc.runtime` package.
34 */
35
36 @Template("./System.xdt")
37 @Gated
38 @ModuleStartup
39 @DirectCall
40 @RomConsts
41
42 module System {
43
44 /*!
45 * ======== AtexitHandler ========
46 * `System`'s atexit function prototype.
47 *
48 * Fuctions of this type can be added to the list of functions that
49 * are executed during application termination.
50 *
51 * @see #atexit
52 */
53 typedef Void (*AtexitHandler)(Int);
54
55 /*!
56 * ======== STATUS_UNKNOWN ========
57 * Unknown exit status value
58 *
59 * When the program exits by calling {@link #exit System_exit()} the
60 * `System`'s `atexit` functions are passed the status value passed to
61 * `System_exit()`. However, if the program exits using
62 * the ANSI C Standard Library `exit()` function, the `System`'s `atexit`
63 * functions are passed `System_STATUS_UNKNOWN`; ANSI C `atexit`
64 * functions are not passed the exit status.
65 */
66 const Int STATUS_UNKNOWN = 0xCAFE;
67
68 /*!
69 * ======== AbortFxn ========
70 * System abort function prototype.
71 *
72 * Fuctions of this type can be plugged in to `System`'s abort function
73 * that will be executed during abnormal application termination.
74 *
75 * @see #abort
76 */
77 typedef Void (*AbortFxn)();
78
79 /*!
80 * ======== ExitFxn ========
81 * System exit function prototype.
82 *
83 * Fuctions of this type can be plugged in to `System`'s exit function that
84 * will be executed during normal application termination.
85 *
86 * @see #exit
87 */
88 typedef Void (*ExitFxn)(Int);
89
90 /*! @_nodoc */
91 @XmlDtd
92 metaonly struct Module_View {
93 String atexitHandlers[];
94 Int numAtexitHandlers;
95 };
96
97 /*! @_nodoc */
98 metaonly struct PathEntryView {
99 String entry;
100 }
101
102 /*!
103 * ======== rovViewInfo ========
104 * @_nodoc
105 */
106 @Facet
107 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
108 xdc.rov.ViewInfo.create({
109 viewMap: [
110 ['XDCROOT',
111 {
112 type: xdc.rov.ViewInfo.MODULE_DATA,
113 viewInitFxn: 'viewInitXdcRoot',
114 structName: 'PathEntryView'
115 }
116 ],
117 ['XDCPATH',
118 {
119 type: xdc.rov.ViewInfo.MODULE_DATA,
120 viewInitFxn: 'viewInitXdcPath',
121 structName: 'PathEntryView'
122 }
123 ],
124 ]
125 });
126
127 /*!
128 * ======== A_cannotFitIntoArg ========
129 * Assert that the target's `Float` type fits in an `IArg`
130 *
131 * This assertion is triggered when the `%f` format specifier is used,
132 * the argument treated as an `IArg`, but for the current target
133 * `sizeof(Float)` > `sizeof(IArg)`.
134 */
135 config Assert.Id A_cannotFitIntoArg = {
136 msg: "A_cannotFitIntoArg: sizeof(Float) > sizeof(Arg)"
137 };
138
139 /*!
140 * ======== extendedFormats ========
141 * Optional conversions supported by `{@link #printf System_printf}`
142 *
143 * This string specifies the set of optional argument conversion
144 * specifiers required by the application. By reducing the number of
145 * optional conversions understood by the `System {@link #printf}`
146 * methods, it is possible to significantly reduce the code size
147 * footprint of the `System` module. This configuration parameter
148 * enables one to balance `printf` functionality against code size
149 * footprint.
150 *
151 * The format of this string is simply a concatenated list of the desired
152 * conversion specifiers (with the leading `%` character). For example,
153 * to support both `%f` and `%$L` set `extendedFormats` to `"%$L%f"`.
154 *
155 * To disable all optional converstions, set `extendedFormats` to `null`
156 * or the empty string ("").
157 *
158 * For a complete list of supported extensions, see the
159 * `{@link #printf System_printf}` "Extended_Format_Specifiers" section.
160 *
161 * @a(Note)
162 * If an optional conversion is used by some part of the application and
163 * it is not specified in `extendedFormats`, the conversion character(s)
164 * and leading `%` are treated as ordinary characters to be output. As
165 * a result, all subsequent arguments will almost certainly be converted
166 * using the wrong conversion specifier!
167 *
168 * @see #printf
169 */
170 metaonly config String extendedFormats = "%$L%$S%$F";
171
172 /*!
173 * ======== SupportProxy ========
174 * The implementation module of the low-level system functions.
175 *
176 * This configuration parameter allows one to "bind" a different
177 * implementation of the low-level services required to implement
178 * `System`.
179 * @p(code)
180 * var System = xdc.useModule("xdc.runtime.System");
181 * var SysStd = xdc.useModule("xdc.runtime.SysStd");
182 * System.SupportProxy = SysStd;
183 * @p
184 *
185 * If this parameter is not set, it defaults to `{@link SysMin}`.
186 */
187 proxy SupportProxy inherits ISystemSupport;
188
189 /*!
190 * ======== maxAtexitHandlers ========
191 * Maximum number of dynamic atexit handlers allowed in the system.
192 *
193 * Maximum number of `System` `atexit` handlers set during runtime via
194 * the `{@link System#atexit}` function.
195 *
196 */
197 config Int maxAtexitHandlers = 8;
198
199 /*!
200 * ======== abortFxn ========
201 * Abort handler function
202 *
203 * This configuration parameter allows user to plug in their own abort
204 * function. By default `{@link #abortStd}` which calls ANSI C Standard
205 * `abort()` is plugged in. Alternatively `{@link #abortSpin}` can be
206 * plugged which loops infinitely.
207 *
208 */
209 config AbortFxn abortFxn = System.abortStd;
210
211 /*!
212 * ======== exitFxn ========
213 * Exit handler function
214 *
215 * This configuration parameter allows user to plug in their own exit
216 * function. By default `{@link #exitStd}` which calls ANSI C Standard
217 * `exit()` is plugged in. Alternatively `{@link #exitSpin}` can be
218 * plugged which loops infinitely.
219 *
220 */
221 config ExitFxn exitFxn = System.exitStd;
222
223 /*!
224 * ======== abort ========
225 * Print a message and abort currently running executable.
226 *
227 * This is called when an executable abnormally terminates.
228 * The `System` gate is entered, the
229 * `{@link #SupportProxy}`'s `abort` function is called
230 * and then `{@link #abortFxn}` is called.
231 * No exit functions bound via `System_atexit()` or the ANSI C Standard
232 * Library `atexit()` functions are executed.
233 *
234 * @param(str) abort message (not a format string)
235 */
236 Void abort(CString str);
237
238 /*!
239 * ======== abortStd ========
240 * ANSI C Standard implementation of abortFxn function
241 *
242 * This function calls ANSI C Standard `abort()` to terminate currently
243 * running executable. This function is used by default in
244 * `{@link #abortFxn}`.
245 *
246 */
247 Void abortStd();
248
249 /*!
250 * ======== abortSpin ========
251 * Lightweight implementation of abortFxn function
252 *
253 * This functions loops indefinitely. This can used as an alternative
254 * `{@link #abortFxn}` when a lightweight implementation is
255 * required instead of the ANSI C Standard `abort()`.
256 */
257 Void abortSpin();
258
259 /*!
260 * ======== atexit ========
261 * Add an exit handler
262 *
263 * `System_atexit` pushes `handler` onto an internal stack of functions
264 * to be executed when system is exiting (e.g. `System_exit` is called).
265 * Up to `{@link #maxAtexitHandlers}` functions can be specified in this
266 * manner. During the exit processing, the functions are popped off the
267 * internal stack and called until the stack is empty.
268 *
269 * The `System` gate is entered before the `System_atexit` functions
270 * are called.
271 *
272 * The `SupportProxy`'s `{@link ISystemSupport#exit}` function is called
273 * after all the atexit functions are called.
274 *
275 * @param(handler) the `AtexitHandler` to invoke during system
276 * exit processing.
277 *
278 * @a(returns)
279 * If `FALSE` is returned, the exit handler was not added and it will
280 * not be called during an exit.
281 */
282 Bool atexit(AtexitHandler handler);
283
284 /*!
285 * ======== atexitMeta ========
286 * Add an exit handler during configuration
287 *
288 * This is the static counterpart to `System_atexit()`. This method can
289 * be used to add `atexit` handlers at configuration time. These
290 * handlers do not count against the `maxAtexitHandlers`.
291 *
292 * @param(handler) the `AtexitHandler` to invoke during system
293 * exit processing.
294 */
295 metaonly Void atexitMeta(AtexitHandler handler);
296
297 /*!
298 * ======== exit ========
299 * Exit currently running executable.
300 *
301 * This function is called when an executable needs to terminate
302 * normally. This function processes all functions bound via
303 * `System_atexit` and then calls `{@link #exitFxn}`. The
304 * `{@link #SupportProxy}`'s `exit` function is called during this time.
305 *
306 * @param(stat) exit status to return to calling environment.
307 */
308 Void exit(Int stat);
309
310 /*!
311 * ======== exitStd ========
312 * Implements an `exitFxn` function
313 *
314 * This function calls ANSI C Standard `exit()` to terminate currently
315 * running executable normally. This function is used by default in
316 * `{@link #exitFxn}`.
317 *
318 * @param(stat) exit status to return to calling environment.
319 */
320 Void exitStd(Int stat);
321
322 /*!
323 * ======== exitSpin ========
324 * Implements an `exitFxn` function
325 *
326 * This functions loops indefinitely. This can used as an alternative
327 * `{@link #exitFxn}` when a light weight implementation is
328 * required instead of the ANSI C Standard `exit()`.
329 *
330 * @param(stat) exit status to return to calling environment.
331 */
332 Void exitSpin(Int stat);
333
334 /*!
335 * ======== processAtExit ========
336 * Processes all functions bound via `System_atexit`
337 *
338 * This function is called by `System_exit` to process all functions
339 * bound via `System_atexit`. User can add this to ANSI C standard
340 * `atexit` function so that all functions bound via `System_atexit` are
341 * processed when ANSI C standard `exit` function is called.
342 *
343 * @param(stat) exit status which will passed to all functions
344 * processed.
345 */
346 Void processAtExit(Int stat);
347
348 /*!
349 * ======== putch ========
350 * Output a single character
351 *
352 * The `{@link #SupportProxy}`'s `putch` function is called
353 * by this function.
354 *
355 * @param(ch) character to be output.
356 */
357 Void putch(Char ch);
358
359 /*!
360 * ======== flush ========
361 * Flush standard System I/O
362 *
363 * This function causes any buffered output characters are "written"
364 * to the output device.
365 *
366 * The `{@link #SupportProxy}`'s `flush` function is called
367 * by this function.
368 */
369 Void flush();
370
371 /*!
372 * ======== printf ========
373 * A smaller faster printf
374 *
375 * This function behaves much like the ANSI C Standard `printf`
376 * but does not support the full range of format strings specified by
377 * the C Standard. In addition, several non-standard format specifiers
378 * are recognized.
379 *
380 * @a(Format Strings)
381 * The format string is a character string composed of zero or
382 * more directives: ordinary characters (not %), which are copied
383 * unchanged to the output stream; and conversion specifications, each of
384 * which results in fetching zero or more subsequent arguments. Each
385 * conversion specification is introduced by the character %, and ends
386 * with a conversion specifier. In between there may be (in this order)
387 * zero or more flags, an optional minimum field width, an optional
388 * precision and an optional length modifier.
389 *
390 * @a(Flags)
391 * The following flags are supported:
392 * @p(dlist)
393 * - `-`
394 * The converted value is to be left adjusted on the field
395 * boundary (the default is right justification.)
396 * - `0`
397 * The value should be zero padded. For d, i, o, u, and x
398 * conversions, the converted value is padded on the left
399 * with zeros rather than blanks.
400 * @p
401 *
402 * @a(Field Width)
403 * The optional field width specifier is a decimal digit string (with
404 * nonzero first digit) specifying a minimum field width. If the
405 * converted value has fewer characters than the field width, it will
406 * be padded with spaces on the left (or right, if the left-adjustment
407 * flag has been given). Instead of a decimal digit string one may
408 * write `*` to specify that the field width is given in the next
409 * argument. A negative field width is taken as a '-' flag followed
410 * by a positive field width.
411 *
412 * @a(Precision)
413 * The optional precision specifier is a period ('.') followed by an
414 * optional decimal digit string. Instead of a decimal digit string
415 * one may write `*` to specify that the precision is given in the
416 * next argument which must be of type int.
417 *
418 * If the precision is given as just '.', or the precision is
419 * negative, the precision is taken to be zero. This gives the
420 * minimum number of digits to appear for d, i, o, u, and x
421 * conversions, or the maximum number of characters to be printed from
422 * a string for s conversions.
423 *
424 * @a(Length Modifiers)
425 * The optional length modifier is a single character from the following
426 * list.
427 * @p(dlist)
428 * - `l`
429 * A following integer conversion corresponds to a long int
430 * or unsigned long int argument
431 *
432 * @p
433 *
434 * @a(Conversion Specifiers)
435 * The following conversion specifiers are supported.
436 * @p(dlist)
437 * - `d`, `i`
438 * signed integer
439 * - `u`
440 * unsigned decimal
441 * - `x`
442 * unsigned hex
443 * - `o`
444 * unsigned octal
445 * - `p`
446 * pointer (@ + hex num)
447 * - `c`
448 * character
449 * - `s`
450 * string
451 * @p
452 * @a(Extended Conversion Specifiers)
453 * The following conversion specifiers are optionally supported. See
454 * the `{@link #extendedFormats}` configuration parameter for more
455 * information about how to enable these conversion specifiers.
456 *
457 * @p(dlist)
458 * - `f`
459 * decimal floating point.
460 * - `$`
461 * non-ANSI conversion prefix. This prefix indicates that the
462 * next character identifies a non-ANSI standard conversion. See
463 * the next section for details.
464 * @p
465 *
466 * @a(Non ANSI Conversion Specifiers)
467 * Among the extended conversion specifiers are unique specifiers which
468 * are not part of ANSI printf. These are specified using a $, for
469 * example %$L.
470 *
471 * These unique specifiers do not support the minimum field width
472 * attribute. Certain specifiers have additional restrictions; see below.
473 *
474 * @p(dlist)
475 * - '$L'
476 * The argument is treated as a pointer to a `{@link Types#Label}`
477 * and is converted to an appropriate string.
478 * - '$F'
479 * Displays a file and line number; used for displaying the call
480 * site. This specifier consumes two arguments, the file and line
481 * number, in that order. See an example below.
482 * - '$S'
483 * The argument is treated as a format string, and is recursively
484 * formatted using any following arguments. This specifier does
485 * not support the use of the "precision" field for specifying
486 * maximum string length.
487 * @p
488 *
489 * The following are example uses of the %$F and %$S format specifiers.
490 *
491 * In this call using %$F, the compiler recognizes these symbols and
492 * fills in the file and line number.
493 * @p(code)
494 * System_printf("%$F", __FILE__, __LINE__);
495 * @p
496 * This call outputs, for example,
497 * @p(code)
498 * "MyCode.c", line 35:
499 * @p
500 * Here is an example using %$S, passing a recursive format string.
501 * @p(code)
502 * System_printf("Msg: %$S", "My msg, code: %d", 5);
503 * @p
504 * This outputs:
505 * @p(code)
506 * Msg: My msg, code: 5
507 * @p
508 *
509 * @param(fmt) a 'printf-style' format string
510 *
511 * @a(returns)
512 * `printf` returns the number of characters printed.
513 */
514 Int printf(CString fmt, ...);
515
516 /*!
517 * ======== aprintf ========
518 * `{@link #printf}` where all optional arguments are `IArg`s
519 *
520 * This function will treat each argument as though it was widened to be
521 * of type `IArg` prior to being passed to the `{@link #printf}` function
522 *
523 * @see #printf
524 */
525 Int aprintf(CString fmt, ...);
526
527 /*!
528 * ======== sprintf ========
529 * Write formated output to a character buffer
530 *
531 * This function is identical to `{@link #printf}` except that the
532 * output is copied to the specified character buffer `buf` followed
533 * by a terminating '\0' character.
534 *
535 * @param(buf) a character output buffer
536 * @param(fmt) a 'printf-style' format string
537 *
538 * @a(returns)
539 * `sprintf` returns the number of characters output not including the
540 * '\0' termination character.
541 */
542 Int sprintf(Char buf[], CString fmt, ...);
543
544 /*!
545 * ======== asprintf ========
546 * `{@link #sprintf}` where all optional arguments are `IArg`s
547 *
548 * This function will treat each argument as though it was widened to be
549 * of type `IArg` prior to being passed to the `{@link #sprintf}`
550 * function.
551 *
552 * @see #sprintf
553 */
554 Int asprintf(Char buf[], CString fmt, ...);
555
556 /*!
557 * ======== vprintf ========
558 * A VaList printf
559 *
560 * This function is identical to `{@link #printf}` except that its
561 * arguments are passed via a VaList (a "varargs list").
562 *
563 * @param(fmt) a standard 'printf-style' format string.
564 * @param(va) an args list that points to the arguments referenced
565 * by the fmt string
566 *
567 * @a(returns)
568 * `vprintf` returns the number of characters output.
569 */
570 Int vprintf(CString fmt, VaList va);
571
572 /*!
573 * ======== avprintf ========
574 * `{@link #vprintf}` where all optional arguments are `IArg`s
575 *
576 * This function will treat each argument as though it was widened to be
577 * of type `IArg` prior to being passed to the `{@link #vprintf}`
578 * function.
579 *
580 * @see #vprintf
581 */
582 Int avprintf(CString fmt, VaList va);
583
584 /*!
585 * ======== vsprintf ========
586 * A `VaList` sprintf
587 *
588 * This function is identical to `{@link #sprintf}` except that
589 * its arguments are passed via a `VaList` (a "varargs list").
590 *
591 * @param(buf) a character output buffer
592 * @param(fmt) a standard '`printf`-style' format string.
593 * @param(va) an arguments list that points to the arguments referenced
594 * by the `fmt` string
595 *
596 * @a(returns)
597 * `vsprintf` returns the number of characters output.
598 */
599 Int vsprintf(Char buf[], CString fmt, VaList va);
600
601 /*!
602 * ======== avsprintf ========
603 * `{@link #vsprintf}` where all optional arguments are `IArg`s
604 *
605 * This function is identical to `{@link #sprintf}` except that
606 * its arguments are passed via a `VaList` (a "varargs list").
607 *
608 * This function will treat each argument as though it was widened to be
609 * of type `IArg` prior to being passed to the `vsprintf` function
610 *
611 * @see #vsprintf
612 */
613 Int avsprintf(Char buf[], CString fmt, VaList va);
614
615 /*!
616 * ======== snprintf ========
617 * Write formated output to a character buffer
618 *
619 * This function is identical to `{@link #sprintf}` except that at most
620 * `n` characters are copied to the specified character buffer `buf`.
621 * If n is zero, nothing is written to character buffer. Otherwise,
622 * output characters beyond the `n` - 1 are discarded rather than
623 * being written to the character buf, and a null character is written
624 * at the end of the characters written into the buffer.
625 *
626 * @param(buf) a character output buffer
627 * @param(n) the maximum number of characters, including '\0', written to
628 * the output buffer `buf`
629 * @param(fmt) a 'printf-style' format string
630 *
631 * @a(returns)
632 * `snprintf` returns the number of characters that would have been
633 * written had `n` been sufficiently large, not counting the terminating
634 * '\0' character.
635 */
636 Int snprintf(Char buf[], SizeT n, CString fmt, ...);
637
638 /*!
639 * ======== vsnprintf ========
640 * A `VaList` snprintf
641 *
642 * This function is identical to `{@link #snprintf}` except that
643 * its arguments are passed via a `VaList` (a "varargs list").
644 *
645 * @param(buf) a character output buffer
646 * @param(n) at most number of characters including '\0' written to
647 * output buffer
648 * @param(fmt) a standard '`printf`-style' format string.
649 * @param(va) an arguments list that points to the arguments referenced
650 * by the `fmt` string
651 *
652 * @a(returns)
653 * `vsnprintf` returns the number of characters that would have been
654 * written had `n` been sufficiently large, not counting the terminating
655 * '\0' character.
656 */
657 Int vsnprintf(Char buf[], SizeT n, CString fmt, VaList va);
658
659 internal:
660
661 /*! struct used to keep track of state during doPrint */
662 struct ParseData {
663 Int width;
664 Bool lFlag;
665 Bool lJust;
666 Int precis;
667 Int len;
668 Int zpad;
669 Char *end;
670 Bool aFlag;
671 Char *ptr;
672 };
673
674 /*! typedef for generated functions to process extended formats */
675 typedef Int (*ExtendFxn)(Char **, CString *, VaList *, ParseData *);
676
677 /*! config parameter used to call generated function */
678 readonly config ExtendFxn extendFxn = '&xdc_runtime_System_printfExtend__I';
679
680 681 682 683 684 685 686 687 688 689
690 Int printfExtend (Char **bufp, CString *fmt, VaList *va, ParseData *parse);
691
692 /*!
693 * ======== exitFxns ========
694 * @_nodoc
695 * List of functions statically plugged to be called at exit
696 *
697 */
698 metaonly config AtexitHandler exitFxns[];
699
700 /*!
701 * ======== mprintf ========
702 * @_nodoc
703 */
704 function mprintf(fmt, args);
705
706 /*!
707 * ======== doPrint ========
708 * @_nodoc
709 */
710 Int doPrint(Char buf[], SizeT n, CString fmt, VaList *pva, Bool aFlag);
711
712 /*!
713 * ======== lastFxn ========
714 * @_nodoc
715 *
716 * Calls atexit() after all other modules have been initialized
717 * This used to be done in System_Module_startup() but this caused
718 * problems since atexit() uses a heap which isn't necessarily
719 * initialized.
720 */
721 Void lastFxn();
722
723 /*!
724 * ======== putchar ========
725 * @_nodoc
726 *
727 * Write character ch to the buffer and, if the buffer pointer is
728 * non-`NULL`, update the buffer pointer.
729 *
730 * Keeps track of the number of characters written into the buffer by
731 * modifying bufsize `n`. Atmost, `n` - 1 characters are written.
732 */
733 Void putchar(Char **bufp, Char ch, SizeT *n);
734
735 /*!
736 * ======== rtsExit ========
737 * @_nodoc
738 */
739 Void rtsExit();
740
741 /*!
742 * ======== atexitDone ========
743 * @_nodoc
744 */
745 Bool atexitDone();
746
747 /*!
748 * ======== Module_State ========
749 * @_nodoc
750 */
751 struct Module_State {
752 AtexitHandler atexitHandlers[];
753 Int numAtexitHandlers;
754 };
755 }
756 757 758
759