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