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 * ======== LoggerBuf.xdc ========
15 */
16
17 /*!
18 * ======== LoggerBuf ========
19 * A logger which stores `Log` events in a buffer.
20 *
21 * This module provides a logger which captures `{@link Log}` events to a
22 * buffer in realtime. The `Log` events stored in the buffer are
23 * unformatted; `Log` event formatting is deferred until some client reads
24 * the raw event data from the buffer. You can use
25 * `{@link #flush LoggerBuf_flush()}` to process the `Log` events stored
26 * in the buffer and stream the formatted output to stdout
27 * (via `{@link System#printf}`). Alternatively, you can read a raw event
28 * (via `{@link #getNextEntry}`) and send it to another client that
29 * has the resources to format the event for display.
30 *
31 * The implementation of this logger is fast with minimal stack usage
32 * making it appropriate for a realtime application.
33 * This logger writes all `Log` events to a circular buffer. As a
34 * result, the execution time of all `Log` methods bound to this type
35 * of logger are deterministic (and quite short) because there are no
36 * additional memory allocation calls after the circular buffer was
37 * allocated.
38 *
39 * If this logger is used in a preemptive environment, then an appropriate
40 * gate must be assigned to the module. For example, if events are generated
41 * from an interrupt context, then a gate that disables interrupts
42 * must be used.
43 *
44 * @p(code) 45 * var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
46 * LoggerBuf.common$.gate = ...some gate instance...
47 * @p 48 *
49 * If the buffer type is circular, the log buffer of size
50 * `{@link #numEntries}` contains the last `numEntries` of `Log` events. If
51 * the buffer type is fixed, the log buffer contains the first
52 * `numEntries` events.
53 *
54 * LoggerBuf supports routing of 'STATUS' events (errors and warnings) to a
55 * separate ILogger instance. This is helpful in preserving these critical
56 * events, which may otherwise be overwritten by lower priority events. This
57 * feature is disabled by default. See {@link #statusLogger}.
58 *
59 * LoggerBuf implements the {@link IFilterLogger} interface and
60 * optionally supports filtering of events based on their detail level. This
61 * feature is disabled by default. See {@link IFilterLogger}.
62 *
63 * @a(Examples) 64 * Configuration example: The following XDC configuration statements
65 * create a logger instance, assign it as the default logger for all
66 * modules, and enable `USER1` logging in all modules of the package
67 * `my.pkg`. See the `{@link Diags#setMaskMeta Diags.setMaskMeta()}` function
68 * for details on specifying the module names.
69 *
70 * @p(code) 71 * var Defaults = xdc.useModule('xdc.runtime.Defaults');
72 * var Diags = xdc.useModule('xdc.runtime.Diags');
73 * var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
74 *
75 * LoggerBuf.enableFlush = true;
76 * var LoggerBufParams = new LoggerBuf.Params();
77 * LoggerBufParams.exitFlush = true;
78 * Defaults.common$.logger = LoggerBuf.create(LoggerBufParams);
79 * Diags.setMaskMeta("my.pkg.%", Diags.USER1, Diags.RUNTIME_ON);
80 * @p 81 */
82
83 @ModuleStartup /* Initialize static instances */
84 @InstanceFinalize /* this mod has cleanup fxn when instances are deleted */
85 @InstanceInitError /* instance create can fail */
86 @Gated
87
88 module LoggerBuf inherits IFilterLogger {
89
90 /*!
91 * ======== BufType ========
92 * Type of log buffer
93 */
94 enum BufType {
95 BufType_CIRCULAR, /*! The log buffer wraps, overwriting old entries */
96 BufType_FIXED /*! The log buffer halts collection when full */
97 };
98
99 metaonlystruct BasicView {
100 String label;
101 Int lastSerial;
102 Int numEntries;
103 String type;
104 Bool enabledFlag;
105 };
106
107 metaonlystruct RecordView {
108 Int serial;
109 Long timestampRaw;
110 String modName;
111 String text;
112 Int eventId;
113 String eventName;
114 IArg arg0;
115 IArg arg1;
116 IArg arg2;
117 IArg arg3;
118 IArg arg4;
119 IArg arg5;
120 IArg arg6;
121 IArg arg7;
122 }
123
124 /*!
125 * ======== rovViewInfo ========
126 * @_nodoc 127 */
128 @Facet
129 metaonlyconfig xdc.rov.ViewInfo.Instance rovViewInfo =
130 xdc.rov.ViewInfo.create({
131 viewMap: [
132 ['Basic',
133 {
134 type: xdc.rov.ViewInfo.INSTANCE,
135 viewInitFxn: 'viewInitBasic',
136 structName: 'BasicView'
137 }
138 ],
139 ['Records',
140 {
141 type: xdc.rov.ViewInfo.INSTANCE_DATA,
142 viewInitFxn: 'viewInitRecords',
143 structName: 'RecordView'
144 }
145 ]
146 ]
147 });
148
149 /*!
150 * ======== StopModeData ========
151 * This data is added to the RTA MetaData file to support stop mode RTA.
152 */
153 @XmlDtd metaonlystruct StopModeData {
154 String bufferSymbol;
155 Int bufferSize;
156 }
157
158 /*! Error raised if get or setFilterLevel receive a bad level value */
159 config Error.Id E_badLevel =
160 {msg: "E_badLevel: Bad filter level value: %d"};
161
162 /*!
163 * ======== TimestampProxy ========
164 * User supplied time-stamp proxy
165 *
166 * This proxy allows `LoggerBuf` to use a timestamp server different
167 * from the server used by `{@link xdc.runtime.Timestamp}`. However, if
168 * not supplied by a user, this proxy defaults to whichever timestamp
169 * server is used by `Timestamp`.
170 */
171 proxy TimestampProxy inherits ITimestampClient;
172
173 /*!
174 * ======== enableFlush ========
175 * Flush all logs at system exit
176 */
177 config Bool enableFlush = false;
178
179 /*!
180 * ======== statusLogger ========
181 * Route all 'STATUS' (error and warning) events to this logger.
182 *
183 * If a statusLogger is specified, all LoggerBuf instances will check to
184 * determine if any of the events they receive are errors or warnings (if
185 * their diags mask includes the STATUS category), and will log these
186 * events to the statusLogger.
187 *
188 * Error events are infrequent, but it's generally critical that they be
189 * seen. In a typical system, non-error events easily outnumber any error
190 * events, and the logger is likely to wrap, overwriting any error events.
191 * To protect these events from being overwritten and lost, they can be
192 * sent to their own separate logger to preserve them.
193 *
194 * The default value is null, indicating that the STATUS events will just
195 * be logged by the logger they were sent to.
196 */
197 config ILogger.Handle statusLogger = null;
198
199 /*!
200 * ======== level1Mask ========
201 * Mask of diags categories whose initial filtering level is Diags.LEVEL1
202 *
203 * See '{@link #level4Mask}' for details.
204 */
205 config Diags.Mask level1Mask = 0;
206
207 /*!
208 * ======== level2Mask ========
209 * Mask of diags categories whose initial filtering level is Diags.LEVEL2
210 *
211 * See '{@link #level4Mask}' for details.
212 */
213 config Diags.Mask level2Mask = 0;
214
215 /*!
216 * ======== level3Mask ========
217 * Mask of diags categories whose initial filtering level is Diags.LEVEL3
218 *
219 * See '{@link #level4Mask}' for details.
220 */
221 config Diags.Mask level3Mask = 0;
222
223 /*!
224 * ======== level4Mask ========
225 * Mask of diags categories whose initial filtering level is Diags.LEVEL4
226 *
227 * If 'filterByLevel' is true, then all LoggerBuf instances will filter
228 * incoming events based on their event level.
229 *
230 * The LoggerBuf module allows for specifying a different filter level for
231 * every Diags bit. These filtering levels are module wide; LoggerBuf does
232 * not support specifying the levels on a per-instance basis.
233 *
234 * The setFilterLevel API can be used to change the filtering levels at
235 * runtime.
236 *
237 * The default filtering levels are assigned using the 'level1Mask' -
238 * 'level4Mask' config parameters. These are used to specify, for each of
239 * the four event levels, the set of bits which should filter at that
240 * level by default.
241 *
242 * The default filtering configuration sets the filter level to
243 * Diags.LEVEL4 for all logging-related diags bits so that all events are
244 * logged by default.
245 */
246 config Diags.Mask level4Mask = Diags.ALL_LOGGING;
247
248 /*!
249 * ======== flushAll ========
250 * Flush logs of all instances of `LoggerBuf` which set exitFlush to true.
251 *
252 * The user is responsible for making sure that no `LoggerBuf` instances
253 * are created or deleted while in this API, by using an appropriate gate.
254 */
255 Void flushAll();
256
257 /*!
258 * ======== flushAllInternal ========
259 * @_nodoc 260 */
261 Void flushAllInternal(Int stat);
262
263 /*!
264 * @_nodoc 265 * ======== initDecoder ========
266 * Initialize the LoggerBufDecoder for use in the LoggerBuf 'Records' ROV
267 * view.
268 */
269 function initDecoder();
270
271 instance:
272 /*!
273 * ======== create ========
274 * Create a `LoggerBuf` logger
275 *
276 * @see LoggerBuf#Params
277 */
278 create();
279
280 /*!
281 * ======== numEntries ========
282 * Number of entries in buffer
283 *
284 * Each entry is large enough to store one `Log` event containing up to
285 * 4 optional arguments. Events containing more than 4 arguments (such
286 * as those from `{@link Log#write5}`) use 2 entries.
287 *
288 * `numEntries` must be a power of 2.
289 */
290 config Int numEntries = 64;
291
292 /*!
293 * ======== bufType ========
294 * Log buffer type
295 */
296 config BufType bufType = BufType_CIRCULAR;
297
298 /*!
299 * ======== exitFlush ========
300 * Flush log at system exit
301 *
302 * Only used when module parameter `{@link #enableFlush}` is `true`.
303 */
304 config Bool exitFlush = false;
305
306 /*!
307 * ======== bufSection ========
308 * Section name for the buffer managed by the static instance.
309 *
310 * The default section is the 'dataSection' in the platform.
311 */
312 metaonlyconfig String bufSection = null;
313
314 /*!
315 * ======== bufHeap ========
316 * The heap that contains the `Log` buffer for dynamic instances.
317 *
318 * The default value `null` means the buffer will be allocated from
319 * the `{@link Memory#defaultHeapInstance}` heap.
320 */
321 config IHeap.Handle bufHeap = null;
322
323 /*!
324 * ======== reset ========
325 * Reset a log to empty state and enable it
326 *
327 * @a(WARNING) This method is not synchronized with other instance
328 * methods and, as a result, it must never be called when there is a
329 * chance that another instance method is currently in operation or
330 * when another method on this instance may preempt this call.
331 */
332 Void reset();
333
334 /*!
335 * ======== flush ========
336 * Read, clear, and output the contents of the log
337 *
338 * This method reads, clears, and "prints" each `Log` event (via
339 * `{@link System#printf}`) in the log.
340 */
341 Void flush();
342
343 /*!
344 * ======== getNextEntry ========
345 * Fills the passed `{@link Log#EventRec}` with the next entry in the log.
346 *
347 * This function is used to read and clear `Log` events from the
348 * buffer maintained by the `LoggerBuf` instance. The `Log` event can
349 * then be transmitted and displayed on a host.
350 *
351 * A read pointer is maintained in the `LoggerBuf` instance and
352 * points to the next record to read. Entries are not necessarily
353 * returned in chronological order, since buffers of type
354 * `{@link #BufType_CIRCULAR}` can wrap.
355 *
356 * @param(evtRec) pointer to a supplied `EventRec` object where the next
357 * entry in the log is copied to
358 *
359 * @a(returns) 360 * This function reports the number of entries actually read. The only
361 * values that can be returned are:
362 * @p(blist) 363 * - 0 no more entries to read
364 * - 1 or 2 read a complete entry written by `write4` or `write8`
365 * - -1 cleared an incomplete/overwritten entry, more entries to read
366 */
367 Int getNextEntry(Log.EventRec *evtRec);
368
369 internal:
370
371 Bool filterOutEvent(Diags.Mask mask);
372
373 const Int8 FULL = -1;
374 const Int8 WRAP = 0;
375
376 const Int8 NEXT = 1;
377
378 struct Entry {
379 Types.Timestamp64 tstamp;
380 Bits32 serial;
381 Types.Event evt;
382 IArg arg1;
383 IArg arg2;
384 IArg arg3;
385 IArg arg4;
386 };
387
388 struct Module_State {
389 Diags.Mask level1;
390 Diags.Mask level2;
391 Diags.Mask level3;
392 };
393
394 struct Instance_State {
395 IHeap.Handle bufHeap;
396 Entry entryArr[];
397 Entry *curEntry;
398 Entry *endEntry;
399 Entry *readEntry;
400 Bits32 serial;
401 Int16 numEntries;
402 Int8 advance;
403 Bool enabled;
404 Bool flush;
405 };
406
407 }
408 /*
409 * @(#) xdc.runtime; 2, 1, 0,298; 1-12-2011 10:12:28; /db/ztree/library/trees/xdc/xdc-v55x/src/packages/
410 */
411