1 2 3 4 5 6 7 8 9 10 11 12
13 14 15
16
17 /*!
18 * ======== SysCBuf ========
19 *
20 * Implementation of `{@link ISystemSupport}` with circular buffer for
21 * output.
22 *
23 * This implementation provides a fully functional implementation of
24 * all methods specified by `ISystemSupport`.
25 *
26 * This module maintains a circular buffer where data is written on
27 * SysCBuf_putch(). When the buffer is full, data is overwritten, and
28 * SysCBuf internally keeps track of the number of characters lost
29 * due to overwrite. The output buffer can be statically configured
30 * or dynamically bound to a buffer using SysCBuf_bind().
31 *
32 * When `System_flush()` is called the characters in the internal buffer
33 * are "output" using the user configuratble `{@link #outputFxn}`. There is
34 * also a user configurable "get" function that can be used to copy out a
35 * given amount from the circular buffer.
36 *
37 * The difference between SysCBuf and the xdc.runtime.SysMin module, are
38 * the following additional features:
39 * - SysCBuf_bind() for dynamic binding of the circular output buffer.
40 * - SysCBuf_get() for copying a given amount of data from the output
41 * buffer to another buffer.
42 * - Maintaining the number of characters lost due to overrite, and the
43 * number of characters available for reading with SysCBuf_get().
44 *
45 * As with all `ISystemSupport` modules, this module is the back-end for the
46 * `{@link System}` module; application code does not directly call these
47 * functions.
48 */
49
50 @Template("./SysCBuf.xdt")
51 @ModuleStartup
52 module SysCBuf inherits xdc.runtime.ISystemSupport {
53
54 /*!
55 * ======== bufSize ========
56 * Size (in MAUs) of the output.
57 *
58 * An internal buffer of this size is allocated. All output is stored
59 * in this internal buffer.
60 *
61 * If 0 is specified for the size, no buffer is created.
62 */
63 config SizeT bufSize = 0;
64
65 /*!
66 * ======== flushAtExit ========
67 * Flush the internal buffer during `{@link #exit}` or `{@link #abort}`.
68 *
69 * If the application's target is a TI target, the internal buffer is
70 * flushed via the `HOSTwrite` function in the TI C Run Time Support
71 * (RTS) library.
72 *
73 * If the application's target is not a TI target, the internal buffer
74 * is flushed to `stdout` via `fwrite(..., stdout)`.
75 *
76 * Setting this parameter to `false` reduces the footprint of the
77 * application at the expense of not getting output when the application
78 * ends via a `System_exit()`, `System_abort()`, `exit()` or `abort()`.
79 */
80 config Bool flushAtExit = true;
81
82 /*!
83 * ======== sectionName ========
84 * Section where the internal character output buffer is placed
85 *
86 * The default is to have no explicit placement; i.e., the linker is
87 * free to place it anywhere in the memory map.
88 */
89 metaonly config String sectionName = null;
90
91 /*!
92 * ======== OutputFxn ========
93 * Output characters in the specified buffer
94 *
95 * The first parameter is a pointer to a buffer of characters to be
96 * output. The second parameter is the number of characters in the
97 * buffer to output.
98 *
99 * This function may be called with 0 as the second parameter. In this
100 * case, the function should simply return.
101 *
102 */
103 typedef Void (*OutputFxn)(Char *, UInt);
104
105 /*!
106 * ======== outputFxn ========
107 * User suplied character output function
108 *
109 * If this parameter is set to a non-`null` value, the specified
110 * function will be called by to output characters buffered within
111 * `SysCBuf`.
112 *
113 * For example, if you define a function named `myOutputFxn`, the
114 * following configuration fragment will cause `SysCBuf` to call
115 * `myOutputFxn` whenever the character buffer is flushed.
116 * @p(code)
117 * var SysCBuf = xdc.useModule("xdc.runtime.SysCBuf");
118 * SysCBuf.outputFxn = "&myOutputFxn";
119 * @p
120 *
121 * If this parameter is not set, a default function will be used which
122 * uses the ANSI C Standard Library function `fwrite()` (or `HOSTwrite`
123 * in the TI C Run Time Support library) to output
124 * accumulated output characters.
125 *
126 * @see #OutputFxn
127 */
128 config OutputFxn outputFxn = null;
129
130 /*!
131 * ======== abort ========
132 * Backend for `{@link System#abort()}`
133 *
134 * This abort function writes the string to the internal
135 * output buffer and then gives all internal output to the
136 * `{@link #outputFxn}` function if the `{@link #flushAtExit}`
137 * configuration parameter is true.
138 *
139 * @param(str) message to output just prior to aborting
140 *
141 * If non-`NULL`, this string should be output just prior to
142 * terminating.
143 *
144 * @see ISystemSupport#abort
145 */
146 override Void abort(String str);
147
148 /*!
149 * ======== exit ========
150 * Backend for `{@link System#exit()}`
151 *
152 * This exit function gives all internal output to the
153 * `{@link #outputFxn}` function if the `{@link #flushAtExit}`
154 * configuration parameter is true.
155 *
156 * @see ISystemSupport#exit
157 */
158 override Void exit(Int stat);
159
160 /*!
161 * ======== flush ========
162 * Backend for `{@link System#flush()}`
163 *
164 * The `flush` writes the contents of the internal character buffer
165 * via the `{@link #outputFxn}` function.
166 *
167 * @a(Warning)
168 * The `{@link System}` gate is used for thread safety during the
169 * entire flush operation, so care must be taken when flushing with
170 * this `ISystemSupport` module. Depending on the nature of the
171 * `System` gate, your application's interrupt latency
172 * may become a function of the `bufSize` parameter!
173 *
174 * @see ISystemSupport#flush
175 */
176 override Void flush();
177
178 /*!
179 * ======== putch ========
180 * Backend for `{@link System#printf()}` and `{@link System#putch()}`
181 *
182 * Places the character into an internal buffer. The `{@link #flush}`
183 * sends the internal buffer to the `{@link #outputFxn}` function.
184 * The internal buffer is also sent to the `SysCBuf_outputFxn`
185 * function by `{@link #exit}` and `{@link #abort}` if the
186 * `{@link #flushAtExit}` configuration parameter is true.
187 *
188 * @see ISystemSupport#putch
189 */
190 override Void putch(Char ch);
191
192 /*!
193 * ======== ready ========
194 * Test if character output can proceed
195 *
196 * This function returns true if the internal buffer is non-zero.
197 *
198 * @see ISystemSupport#ready
199 */
200 override Bool ready();
201
202 /*!
203 * ======== bind ========
204 * Bind the buffer 'buf' of size 'size' bytes to the SysCBuf trace buffer.
205 *
206 * Return 0 if successful, -1 otherwise.
207 */
208 Int bind(Char *buf, UInt32 size);
209
210 /*!
211 * ======== get ========
212 * Copy contents of the trace buffer. Return the number of characters
213 * remaining in 'avail'. Return the number of characters lost due to
214 * wrapping in 'lost'.
215 *
216 * Return the number of characters copied.
217 *
218 */
219 UInt32 get(Char *buf, UInt32 size, UInt32 *avail, UInt32 *lost);
220
221 /*!
222 * ======== getSize ========
223 * Return the size of the trace buffer.
224 */
225 UInt32 getSize();
226
227 internal:
228
229 230 231 232 233 234 235 236 237 238 239 240 241 242
243 Void output(Char *buf, UInt size);
244 readonly config OutputFxn outputFunc = '&ti_sdo_ce_utils_syscbuf_SysCBuf_output__I';
245
246 struct Module_State {
247 Char outbuf[];
248 UInt outidx;
249 Bool wrapped;
250 UInt32 bufSize;
251 }
252 }
253
254 255 256 257
258