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