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     *  ======== SysCBuf.xdc ========
    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         * ======== output ======== 
   231         *  System_output__I is generated based on bufSize.
   232         *
   233         *  This function is generated so that the code does not contain a call to
   234         *  HOSTwrite if bufSize is 0. Otherwise, if bufSize is 0, the compiler
   235         *  would optimize out the HOSTwrite function, leaving a 0-length symbol.
   236         *  If the a client later tried to pull in HOSTwrite, there would be a
   237         *  symbol error.
   238         *
   239         *  This generated function is accessed through an internal config so
   240         *  that it is an indirect call in the ROM case, but optimized to a direct
   241         *  call in the RAM case.
   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[];  /* the output buffer */
   248            UInt outidx;    /* index within outbuf to next Char to write */
   249            Bool wrapped;   /* has the index (outidx) wrapped */
   250            UInt32 bufSize; /* size of the trace buffer */
   251        }
   252    }
   253    
   254    /*
   255     *  @(#) ti.sdo.ce.utils.syscbuf; 1, 0, 0,1; 2-24-2012 19:31:42; /db/atree/library/trees/ce/ce-t06/src/ xlibrary
   256    
   257     */
   258