1    /* 
     2     * Copyright (c) 2009
     3     * Texas Instruments
     4     *
     5     *  All rights reserved.  Property of Texas Instruments
     6     *  Restricted rights to use, duplicate or disclose this code are
     7     *  granted through contract.
     8     * 
     9     * */
    10    /*
    11     *  ======== Clock.xdc ========
    12     *
    13     *
    14     */
    15    
    16    package ti.sysbios.knl;
    17    
    18    import xdc.rov.ViewInfo;
    19    
    20    import xdc.runtime.Assert;
    21    import xdc.runtime.Diags;
    22    import xdc.runtime.Log;
    23    
    24    import ti.sysbios.hal.Timer;
    25    import ti.sysbios.misc.Queue;
    26    
    27    /*!
    28     *  ======== Clock ========
    29     *  System Clock Manager.
    30     *
    31     *  The System Clock manager is responsible for all timing services in BIOS.
    32     *  It generates the periodic system tick. The tick period is configurable.
    33     *  The timeout and period for all Clock Instances and timeout values in 
    34     *  other BIOS modules are specified in terms of Clock ticks.
    35     *
    36     *  Clock Instances are functions that can be scheduled to run after a 
    37     *  certain number of Clock ticks.
    38     *  Clock instances are either one-shot or periodic. Instances are started 
    39     *  when created or they are started later using the Clock_start()function. 
    40     *  Instances can be stopped using the Clock_stop() function. All Clock 
    41     *  Instances are executed when they expire in the context of a software 
    42     *  interrupt.
    43     *
    44     *  Clock objects are placed in the Clock object service list when 
    45     *  created/constructed and remain there until deleted/destructed.
    46     *  To minimize processing overhead, unused or expired Clock objects 
    47     *  should be deleted or destructed.
    48     *
    49     *  The getTicks() function returns number of clock ticks since startup.
    50     *
    51     *  @p(html)
    52     *  <h3> Calling Context </h3>
    53     *  <table border="1" cellpadding="3">
    54     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    55     *
    56     *    <tr><th> Function                </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    57     *    <!--                                                                                                                -->
    58     *    <tr><td> {@link #getTicks}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    59     *    <tr><td> {@link #getTimerHandle} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    60     *    <tr><td> {@link #Params_init}    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    61     *    <tr><td> {@link #tick}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    62     *    <tr><td> {@link #tickReconfig}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    63     *    <tr><td> {@link #tickStart}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    64     *    <tr><td> {@link #tickStop}       </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    65     *    <tr><td> {@link #construct}      </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    66     *    <tr><td> {@link #create}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    67     *    <tr><td> {@link #delete}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    68     *    <tr><td> {@link #destruct}       </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    69     *    <tr><td> {@link #getTimeout}     </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    70     *    <tr><td> {@link #setFunc}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    71     *    <tr><td> {@link #setPeriod}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    72     *    <tr><td> {@link #setTimeout}     </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    73     *    <tr><td> {@link #start}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    74     *    <tr><td> {@link #stop}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    75     *    <tr><td colspan="6"> Definitions: <br />
    76     *       <ul>
    77     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    78     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    79     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    80     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    81     *           <ul>
    82     *             <li> In your module startup after this module is started (e.g. Clock_Module_startupDone() returns TRUE). </li>
    83     *             <li> During {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}. </li>
    84     *             <li> During main().</li>
    85     *             <li> During {@link ti.sysbios.BIOS#startupFxns BIOS.startupFxns}.</li>
    86     *           </ul>
    87     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
    88     *           <ul>
    89     *             <li> During {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}.</li>
    90     *             <li> In your module startup before this module is started (e.g. Clock_Module_startupDone() returns FALSE).</li>
    91     *           </ul>
    92     *       </ul>
    93     *    </td></tr>
    94     *
    95     *  </table>
    96     *  @p
    97     */
    98    
    99    @ModuleStartup
   100    @InstanceFinalize   /* generate call to Clock_Instance_finalize on delete */
   101    @Template("./Clock.xdt")
   102    
   103    module Clock
   104    {
   105        /*! Clock Tick Source. */
   106        enum  TickSource {
   107            TickSource_TIMER,       /*! Timer Instance used to generate tick */
   108            TickSource_USER,        /*! Clock_tick() run in user's ISR */
   109            TickSource_NULL         /*! No clock tick */
   110        };
   111    
   112        metaonly struct BasicView {
   113            String          label;
   114            UInt32          timeout;
   115            UInt            period;
   116            String          fxn[];
   117            UArg            arg;
   118            Bool            started;        /* Instance running? */
   119            UInt32          tRemaining;     /* Remaining timeout */
   120            Bool            periodic;       /* Periodic? (vs. one-shot) */
   121        }
   122        
   123        metaonly struct ModuleView {
   124            volatile UInt32         ticks;
   125            String                  tickSource;
   126            String                  timerHandle;
   127            UInt                    timerId;
   128            UInt                    swiPriority;
   129            UInt32                  tickPeriod;
   130        }
   131    
   132        /*! @_nodoc */
   133        @Facet
   134        metaonly config ViewInfo.Instance rovViewInfo = 
   135            ViewInfo.create({
   136                viewMap: [
   137                  ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',  structName: 'BasicView'}],
   138                  ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
   139                ]
   140            });
   141            
   142        /*! Instance function prototype. */
   143        typedef Void (*FuncPtr)(UArg);
   144    
   145        /*! Logged if Clock swi delayed by >= 1 tick */
   146        config Log.Event LW_delayed = {
   147            mask: Diags.USER3,
   148            msg: "LW_delayed: delay: %d"
   149        };
   150    
   151        /*! Logged in every Clock tick interrupt */
   152        config Log.Event LM_tick = {
   153            mask: Diags.USER1 | Diags.USER2,
   154            msg: "LM_tick: tick: %d"
   155        };
   156    
   157        /*! Logged just prior to calling each Clock function */
   158        config Log.Event LM_begin = {
   159            mask: Diags.USER1 | Diags.USER2,
   160            msg: "LM_begin: clk: 0x%x, func: 0x%x"
   161        };
   162    
   163        /*! Asserted in Clock_create() */
   164        config Assert.Id A_clockDisabled = {
   165            msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
   166        };
   167    
   168        /*! Asserted in Clock_create and Clock_delete */
   169        config Assert.Id A_badThreadType = {
   170            msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
   171        };
   172    
   173        /*!
   174         *  ======== tickSource ========
   175         *  Default is TickSource_TIMER.
   176         */
   177        config TickSource tickSource = TickSource_TIMER;
   178    
   179        /*!
   180         *  ======== timerId ========
   181         *  Timer Id for Timer Instance created by Clock. 
   182         *  The default value is Timer.ANY (~0).
   183         *  The maximum timerId possible is family specific.
   184         */
   185        config UInt timerId = ~0;
   186    
   187        /*!
   188         *  ======== swiPriority ========
   189         *  Set the priority of swi used by Clock module to process its instances.
   190         *
   191         *  Default is Swi.numPriorities - 1;
   192         */
   193        metaonly config UInt swiPriority;
   194    
   195        /*!
   196         *  ======== tickPeriod ========
   197         *  Tick period specified in microseconds.
   198         *  
   199         *  Default value is family dependent. For example, linux86 supports a 
   200         *  minimum of 10000us and supports only multiples of 10000us. TI 
   201         *  targets have a default of 1000 microseconds.
   202         */
   203        config UInt32 tickPeriod;
   204    
   205        /*!
   206         *  ======== getTicks ========
   207         *  Time in Clock ticks
   208         *
   209         *  The value returned will wrap back to zero after it reaches the max
   210         *  value that can be stored in 32 bits.
   211         *
   212         *  @b(returns)     time in clock ticks
   213         */
   214        UInt32 getTicks();
   215    
   216        /*!
   217         *  ======== getTimerHandle ========
   218         *  Get timer Handle. 
   219         *
   220         *  Used when is it necessary to change family 
   221         *  specific options for the timer and its Hwi Object.
   222         *
   223         *  @b(returns)     Timer Handle
   224         */
   225        ti.sysbios.hal.Timer.Handle getTimerHandle();
   226    
   227        /*!
   228         *  ======== tickStop ========
   229         *  Stop clock for reconfiguration.
   230         *
   231         *  This function is used to stop the timer used for generation of
   232         *  clock ticks. It is used along with Clock_tickStart() and 
   233         *  Clock_tickReconfig() to allow reconfiguration of timer at runtime.
   234         *
   235         *  @a(constraints)
   236         *  This function is non-reentrant and appropriate locks must be used to
   237         *  protect against  re-entrancy.
   238         */
   239        Void tickStop();
   240    
   241        /*!
   242         *  ======== tickReconfig ========
   243         *  Reconfigure clock for new cpu frequency.
   244         *  
   245         *  This function uses the new cpu frequency to reconfigure the timer used 
   246         *  for generation of clock ticks such that tick period is 
   247         *  accurate.  This function is used along with Clock_tickStop() and 
   248         *  Clock_tickStart() to allow reconfiguration of timer at runtime.
   249         *
   250         *  When calling Clock_tickReconfig outside of main(), you must also call
   251         *  Clock_tickStop and Clock_tickStart to stop and restart the timer. 
   252         *  Use the following call sequence:
   253         *
   254         *  @p(code)
   255         *  // disable interrupts if an interrupt could lead to
   256         *  // another call to Clock_tickReconfig or if interrupt
   257         *  // processing relies on having a running timer
   258         *  Hwi_disable() or Swi_disable();
   259         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   260         *  Clock_tickStop();
   261         *  Clock_tickReconfig();
   262         *  Clock_tickStart();
   263         *  Hwi_restore() or Swi_enable()
   264         *  @p
   265         *
   266         *  When calling Clock_tickReconfig from main(), the timer has not yet
   267         *  been started because the timer is started as part of BIOS_start().
   268         *  As a result, you can use the following simplified call sequence 
   269         *  in main():
   270         *
   271         *  @p(code)
   272         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   273         *  Clock_tickReconfig(Void);
   274         *  @p
   275         *
   276         *  The return value is false if the timer cannot support the new 
   277         *  frequency
   278         *
   279         *  @b(returns)     true if successful
   280         *
   281         *  @a(constraints)
   282         *  This function is non-reentrant and appropriate locks must be used to
   283         *  protect against  re-entrancy.
   284         */
   285        Bool tickReconfig();
   286    
   287        /*!
   288         *  ======== tickStart ========
   289         *  Start clock after reconfiguration.
   290         *
   291         *  This function starts the timer used for generation of clock ticks
   292         *  It is used along with Clock_tickStop() and Clock_tickReconfig() to allow
   293         *  reconfiguration of timer at runtime. The new timer configuration 
   294         *  reflects changes caused by a call to reconfig().
   295         *
   296         *  @a(constraints)
   297         *  This function is non-reentrant and appropriate locks must be used to
   298         *  protect against  re-entrancy.
   299         */
   300        Void tickStart();
   301    
   302        /*!
   303         *  ======== tick ========
   304         *  Function called by the timer isr when {@link #tickSource} is
   305         *  {@link #TickSource_TIMER}. 
   306         *
   307         *  When {@link #tickSource} is set to
   308         *  {@link #TickSource_USER}, Clock_tick() is called by a user isr, 
   309         *  Swi or Task. Note that this function is not re-entrant and 
   310         *  appropriate locks should be used.
   311         *
   312         *  This function posts a swi that processes the clock instances.
   313         */
   314        Void tick();
   315    
   316        /*! @_nodoc 
   317         *  ======== workFunc ========
   318         *  Clock Q service routine
   319         *  
   320         *  @param(arg0)    Unused. required to match Swi.FuncPtr
   321         *  @param(arg1)    Unused. required to match Swi.FuncPtr
   322         */
   323        Void workFunc(UArg arg0, UArg arg1);
   324    
   325        /*!
   326         *  @_nodoc
   327         *  ======= logTock ========
   328         *  Log the LD_tick from within Clock module scope
   329         */
   330        Void logTick();
   331    
   332    instance:
   333    
   334        /*!
   335         *  ======== create ========
   336         *  Creates a Clock Instance. 
   337         *
   338         *  The first parameter is the function that gets called when the timeout 
   339         *  expires. 
   340         *
   341         *  The timeout parameter is used to specify the initial timeout 
   342         *  for both one-shot and periodic Clock instances (in Clock ticks).
   343         *
   344         *  The {@link #period} parameter is used to set the subsequent timeout
   345         *  interval (in Clock ticks) for periodic instances. 
   346         *
   347         *  For one-shot instances, the period parameter must be set to zero.
   348         *
   349         *  @param(clockFxn)        function that runs upon timeout
   350         *  @param(timeout)         timeout in clock ticks
   351         */
   352        create(FuncPtr clockFxn, UInt timeout);
   353    
   354        /*!
   355         *  ======== startFlag ========
   356         *  Set if instance needs to be started. Default is false.
   357         *
   358         *  When this flag is set the instance created will be started 
   359         *  and the instance function will get called after an interval
   360         *  equal to its timeout. When set to false, the user has to call
   361         *  Clock_start() to start the instance.
   362         */
   363        config Bool startFlag = false;
   364    
   365        /*!
   366         *  ======== period ========
   367         *  Instance period. Default is 0.
   368         *
   369         *  For periodic Clock instances this parameter specifies the periodic
   370         *  timeout interval (in Clock ticks).
   371         * 
   372         *  For one-shot Clock instances this parameter must be set to zero.
   373         */
   374        config UInt period = 0;
   375    
   376        /*!
   377         *  ======== arg ========
   378         *  UArg for Clock Instance function. Default is null.
   379         */
   380        config UArg arg = null;
   381    
   382        /*!
   383         *  ======== start ========
   384         *  Start instance.
   385         *
   386         *  The {@link #timeout} and {@link #period} values set during create() 
   387         *  or by calling Clock_setTimeout() and Clock_setPeriod() are used and 
   388         *  the expiry is recomputed. 
   389         *  Note that for periodic instances, the first expiry is 
   390         *  computed using the timeout specified. All subsequent expiries use the 
   391         *  period value. 
   392         *
   393         *  @a(constraints)
   394         *  Timeout of instance cannot be zero
   395         */
   396        Void start();
   397    
   398        /*!
   399         *  @_nodoc
   400         *  ======== startI ========
   401         *  Internal start function which assumes Hwis disabled.
   402         */
   403        Void startI();
   404    
   405        /*!
   406         *  ======== stop ========
   407         *  Stop instance.
   408         */
   409        Void stop();
   410    
   411        /*!
   412         *  ======== setPeriod ========
   413         *  Set periodic interval.
   414         * 
   415         *  @param(period)          periodic interval in Clock ticks
   416         * 
   417         *  @a(constraints)
   418         *  Cannot change period of instance that has been started.
   419         */
   420        Void setPeriod(UInt period);
   421    
   422        /*!
   423         *  ======== setTimeout ========
   424         *  Set the initial timeout.
   425         *
   426         *  @param(timeout)         initial timeout in Clock ticks
   427         *
   428         *  @a(constraints)
   429         *  Cannot change the initial timeout of instance that has been started.
   430         */
   431        Void setTimeout(UInt timeout);
   432    
   433        /*!
   434         *  ======== setFunc ========
   435         *  Overwrite Clock function and arg.
   436         *
   437         *  Replaces a Clock object's clockFxn function originally
   438         *  provided in {@link #create}.
   439         *
   440         *  @param(clockFxn)        function of type FuncPtr
   441         *  @param(arg)             argument to clockFxn
   442         *
   443         *  @a(constraints)
   444         *  Cannot change function and arg of Clock object that has been started.
   445         */
   446        Void setFunc(FuncPtr fxn, UArg arg);
   447    
   448        /*!
   449         *  ======== getTimeout ========
   450         *  Get timeout of instance. 
   451         *
   452         *  Returns the remaining time if instance has been started.
   453         *
   454         *  @b(returns)             returns timeout in clock ticks
   455         */
   456        UInt getTimeout();
   457    
   458    internal:
   459    
   460        /*!
   461         *  ======== doTick ========
   462         *  Function called by the timer interrupt handler. 
   463         *
   464         *  @param(arg)     Unused. Required to match signature of Hwi.FuncPtr
   465         */
   466        Void doTick(UArg arg);
   467    
   468        struct Instance_State {
   469            Queue.Elem      elem;           // required for clock queue
   470            UInt32          timeout;        // in clock ticks
   471            UInt32          currTimeout;    // working timeout
   472            UInt32          period;         // periodic instance if > 0
   473            volatile Bool   active;         // active/idle flag
   474            FuncPtr         fxn;            // instance function
   475            UArg            arg;            // function arg
   476        };
   477    
   478        struct Module_State {
   479            volatile UInt32 ticks;          // ticks
   480            UInt            swiCount;       // num swi posts before swi runs
   481            Timer.Handle    timer;          // timer used
   482            Void            (*doTickFunc)(UArg); 
   483                                            // points to generated Clock_doTick()
   484            Queue.Object    clockQ;         // clock que
   485            Swi.Handle      swi;            // clock swi
   486        };
   487    }
   488    /*
   489     *  @(#) ti.sysbios.knl; 2, 0, 0, 0,322; 8-25-2009 22:47:14; /db/vtree/library/trees/avala/avala-l10x/src/
   490     */
   491