1    /* --COPYRIGHT--,BSD
     2     * Copyright (c) $(CPYYEAR), Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     * --/COPYRIGHT--*/
    32    
    33    /*
    34     *  ======== ServiceMgr.xdc ======== 
    35     */
    36     
    37    import xdc.runtime.Assert;
    38    import xdc.rov.ViewInfo;
    39    
    40    /*!
    41     *  ======== ServiceMgr ========
    42     *  Module that manages UIA Services
    43     *
    44     *  The ServiceMgr module manages all the UIA Services. The ServiceMgr module 
    45     *  itself can be plugged with different low level transport functions to 
    46     *  support different methods for getting information between the target
    47     *  and instrumentation host. Some of these methods (e.g. File) only support
    48     *  sending information from the target to the host. They do not support 
    49     *  sending information from the host to the target.
    50     *
    51     *  The ServiceMgr module also supports two different topologies. 
    52     *  @p(blist)
    53     *      - Topology_SINGLECORE: Each core on the device communicates
    54     *        directly the instrumentation host.
    55     *      - Topology_MULTICORE: Only one core (i.e. master) 
    56     *        communicates with the instrumentation host. Communication
    57     *        with other cores are routed to the via the master core.
    58     *        The master core is determined by the {@link #masterProcId}
    59     *        parameter. The routing is done via Ipc's MessageQ module.
    60     *        Note: ServiceMgr is a user of Ipc and depends on the 
    61     *        application to configure and initialize Ipc.
    62     *  @p
    63     *
    64     *  There are two different uses of the ServiceMgr module:
    65     *  @p(blist)
    66     *      - Applications (configuration only)
    67     *      - Services  
    68     *  @p
    69     *
    70     *  @p(html)
    71     *  <B>Applications</B>
    72     *  @p 
    73     *  The ServiceMgr module contains the generic configuration. 
    74     *  Many of these configuration values change
    75     *  depending on the device. The ServiceMgr module uses the 
    76     *  ti.uia.family.Settings module to fill in values if they are not set by 
    77     *  the application.
    78     *
    79     *  The ServiceMgr does expose many configuration parameters to allow users
    80     *  to modify the default behavior.
    81     *
    82     *  @p(blist)
    83     *      - Topology: UIA is shipped with support for two different topologies:
    84     *  @p(blist)
    85     *          - Topology_SINGLECORE: Each core on the device communicates
    86     *               directly the instrumentation host.
    87     *          - Topology_MULTICORE: Only one core (i.e. master) 
    88     *               communicates with the instrumentation host. Communication
    89     *               with other cores are routed to the via the master core.
    90     *               The master core is determined by the {@link #masterProcId}
    91     *               parameter. The routing is done via Ipc's MessageQ module.
    92     *               Note: ServiceMgr is a user of Ipc and depends on the 
    93     *               application to configure and initialize Ipc.
    94     *  @p
    95     *
    96     *      - Transport: The ServiceMgr has  pluggable transport functions. The 
    97     *               determination of the transport is accomplished via the 
    98     *               {@link #transportType} parameter. The parameter is defaulted
    99     *               based on the device is not explicitly set.
   100     *
   101     *      - Packets: UIA makes a distinction between event and messages packets.
   102     *                 Events packets are generally bigger to hold many event 
   103     *                 records. The size and number of these packets are defaulted
   104     *                 by UIA based on the transport and device. However the number
   105     *                 of event packets might need to be increased on a multicore
   106     *                 device with heavy event record load. 
   107     *                 {@link #numEventPacketBufs} can be increased in this case.
   108     *             
   109     *      - Tasks: The ServiceMgr module might have up to two tasks:  
   110     *               transfer agent task and receive task. The receive task only 
   111     *               recieves control messages from the instrumentation host and 
   112     *               forwards it on the the transfer agent task. 
   113     *               The transfer agent task is responsible for everything else 
   114     *               (e.g. period management, event collection, communicating with 
   115     *               remote cores in a multicore configuration, sending UIA Packets
   116     *               to the instrumentation host, etc.).
   117     *  
   118     *               The application can specify the stack sizes and placement of
   119     *               these task via the ServiceMgr.
   120     *  
   121     *               If there is only one task needed, the parameters for the 
   122     *               receive task is ignored.
   123     *  @p
   124     * 
   125     *  @p(html)
   126     *  <B>Services</B>
   127     *  @p
   128     *  All services must register with the ServiceMgr module via the 
   129     *  {@link #register} function. Each service
   130     *  must have a unique service id (the first 3 are reserved). The service id
   131     *  is obtained via the encoded type ServiceIdDesc. 
   132     *
   133     *  From the service's standpoint, the ServiceMgr module manages all the 
   134     *  buffers for sending and receive messages and events. The services need
   135     *  to obtain packets from the ServiceMgr via the {@link #getFreePacket} 
   136     *  function. To send a packet, the service must call the 
   137     *  {@link #sendPacket} function.
   138     *
   139     *  All data send and received by a service must be contained in a 
   140     *  {@link UIAPacket} header. Refer to this module for more details. 
   141     *
   142     *  From the service's standpoint, the ServiceMgr module also manages the
   143     *  the period of service. Each service can request the interval at which
   144     *  the ServiceMgr calls the service's {@link #ProcessCallback} to send out 
   145     *  events. This interval can be set by the service via the {@link #register}
   146     *  function. If during runtime the service wants to change it period, it
   147     *  can call {@link #setPeriod}.
   148     */
   149    @CustomHeader
   150    module ServiceMgr
   151    {    
   152        /*!
   153         *  @_nodoc
   154         *  ======== ModuleView ========
   155         */
   156        metaonly struct ModuleView {                
   157            Int        periodInMs;
   158            Bool       supportControl;
   159            String     topology;
   160            Int        numServices;        
   161            Int        masterProcId;
   162            Int        runCount;        
   163            //string     masterRunning; //TODO SDOCM00077324 
   164        }
   165        
   166        /*!
   167         *  @_nodoc
   168         *  ======== PacketView ========
   169         */
   170        metaonly struct PacketView {                
   171            SizeT      maxEventPacketSize;
   172            Int        numEventPacketBufs;
   173            SizeT      maxCtrlPacketSize;
   174            Int        numOutgoingCtrlPacketBufs;
   175            Int        numIncomingCtrlPacketBufs;        
   176        }
   177        
   178        /*!
   179         *  @_nodoc
   180         *  ======== TransportView ========
   181         */
   182        metaonly struct TransportView {
   183            String     initFxn;
   184            String     startFxn;
   185            String     recvFxn;
   186            String     sendFxn;
   187            String     stopFxn;
   188            String     exitFxn;
   189        }
   190        
   191        /*!
   192         *  @_nodoc
   193         *  ======== StatisticsView ========
   194         */
   195        metaonly struct StatisticsView {
   196            Int     numEventPacketsSent;
   197            Int     numEventPacketsFailed;
   198            Int     numMsgPacketsSent;
   199            Int     numMsgPacketsFailed;        
   200        }
   201        
   202        /*!
   203         *  @_nodoc
   204         *  ======== rovViewInfo ========
   205         */    
   206        @Facet
   207        metaonly config ViewInfo.Instance rovViewInfo =
   208            ViewInfo.create({
   209                viewMap: [
   210                    ['Module',   
   211                        {
   212                            type: ViewInfo.MODULE,   
   213                            viewInitFxn: 'viewInitModule', 
   214                            structName: 'ModuleView'
   215                        }
   216                    ],
   217                    // SDOCM00077324 
   218                    // ServiceMgr's ROV should obtain information from proxies 
   219                    //['Statistics',
   220                    //    {
   221                    //        type: ViewInfo.MODULE,
   222                    //        viewInitFxn: 'viewInitStats',
   223                    //        structName: 'StatisticsView'
   224                    //    }
   225                    //],
   226                    ['Transport',
   227                        {
   228                            type: ViewInfo.MODULE,
   229                            viewInitFxn: 'viewInitTransport',
   230                            structName: 'TransportView'
   231                        }
   232                    ],
   233                    ['Packet',   
   234                        {
   235                            type: ViewInfo.MODULE,   
   236                            viewInitFxn: 'viewInitPacket', 
   237                            structName: 'PacketView'
   238                        }
   239                    ],                                
   240                ]
   241            });
   242            
   243        /*!
   244         *  ======== Reason ========
   245         *  Used in the ProcessCallback to denote the reason
   246         *
   247         *  ServiceMgr_Reason_PERIODEXPIRED: the {@link #ProcessCallback} is being 
   248         *  called because it is time to collect events and send them.
   249         *
   250         *  ServiceMgr_Reason_REQUESTENERGY: the {@link #ProcessCallback} is being
   251         *  called because the service requested energy to perform some action.
   252         *
   253         *  ServiceMgr_Reason_INCOMINGMSG: the {@link #ProcessCallback} is being 
   254         *  called because there is an incoming message for the service.
   255         */
   256        enum Reason {
   257            Reason_PERIODEXPIRED,
   258            Reason_REQUESTENERGY,
   259            Reason_INCOMINGMSG
   260        };
   261    
   262        /*!
   263         *  ======== Topology ========
   264         *  Used to define UIA topology.
   265         *
   266         *  If UIA is configured for multicore, all events and messages are routed
   267         *  via the master core to the non-master cores. Choosing multicore requires 
   268         *  setting the {@link #master} config.
   269         *
   270         *  If UIA is configured for Topology_SINGLECORE, each core on the device 
   271         *  communicates with the instrumentation host directly.
   272         */
   273        enum Topology {
   274            Topology_SINGLECORE,
   275            Topology_MULTICORE
   276        };
   277        
   278        /*!
   279         *  ======== TransportType ========
   280         *  Used to specify the type of transport for UIA to use.
   281         *
   282         *  
   283         *  @p(blist)
   284         *  -TransportType_ETHERNET: Use the Ethernet transport. On a SYS/BIOS
   285         *      system, this uses the NDK. The application is responsible for 
   286         *      adding the NDK into the application and initializing it.     
   287         *  -TransportType_FILE: Use the File transport. 
   288         *      On a SYS/BIOS system, this transport requires a JTAG connection.     
   289         *  -TransportType_USER: This allows the application to specify their
   290         *      own transport functions.
   291         *  @p 
   292         */
   293        metaonly enum TransportType {
   294            TransportType_ETHERNET,
   295            TransportType_FILE,
   296            TransportType_USER
   297        };
   298        
   299        /*!
   300         *  ======== ProcessCallback ========
   301         *  Function prototype for the processMsg callback
   302         *
   303         *  A ProcessCallback function must be supplied by every service.
   304         *  The function is provided in the {@link #register} function.
   305         *
   306         *  For a description of the ServiceMgr_Reason parameter, please refer 
   307         *  to {@link #Reason}. 
   308         *
   309         *  The UIPacket_Hdr field is only used in the {@link #Reason_INCOMINGMSG}
   310         *  case. For any other reason, this value is NULL.
   311         */
   312        typedef Void (*ProcessCallback)(Reason, UIAPacket.Hdr *);
   313    
   314        /*!
   315         *  ======== WAIT_FOREVER ========
   316         *  Wait forever constant that can be used in ServiceMgr_getFreePacket.
   317         */
   318        const UInt WAIT_FOREVER = ~(0);
   319    
   320        /*! @_nodoc */
   321        metaonly struct ServiceIdDesc { Bits16 val; };
   322        
   323        /*!
   324         *  ======== ServiceId ========
   325         *  Used by services to generate a serviceId
   326         *
   327         *  Services needs to define a ServiceId in their xdc file.
   328         *  Then the ServiceMgr module will assign a unique value to it during
   329         *  build time. 
   330         *  
   331         *  For example in ti.uia.service.Rta.xdc there is the following line:
   332         *  @p(code)
   333         *  readonly config ServiceMgr.ServiceId SERVICEID;
   334         *  @p
   335         */    
   336        @Encoded typedef ServiceIdDesc ServiceId;     /*! Control command type */
   337            
   338        /*!
   339         *  Assert raised when calling API with invalid ServiceId
   340         */
   341        config Assert.Id A_invalidServiceId  = {
   342            msg: "A_invalidServiceId: ServiceId out of range"
   343        };
   344    
   345        /*!
   346         *  Assert raised invalid processCallbackFxn is supplied
   347         */
   348        config Assert.Id A_invalidProcessCallbackFxn  = {
   349            msg: "A_invalidProcessCallbackFxn: Callback cannot be NULL"
   350        };
   351        
   352        
   353        /*!
   354         *  ======== transportFxns ========
   355         *  Transport functions used to communicate to the instrumentation host
   356         *
   357         *  These functions are setup by default based on the device.
   358         *  The user can explicitly set this parameter if the default is not
   359         *  appropriate.
   360         */
   361        config Transport.FxnSet transportFxns;
   362        
   363        /*!
   364         *  ======== topology ========
   365         *  Used to define UIA topology.
   366         *
   367         *  If `Topology_MULTICORE` is chosen, the ServiceMgr will use Ipc to
   368         *  discover the core configuration and to communicate between the cores.
   369         *  UIA will route the outbound packets from each core through the master
   370         *  core. UIA will also route messages received by the master core to
   371         *  their intended recipient.
   372         *
   373         *  If UIA is configured for Topology_SINGLECORE, each core on the device 
   374         *  communicates with the instrumentation host directly.
   375         *
   376         *  The default is Topology_SINGLECORE.
   377         */
   378        config Topology topology = Topology_SINGLECORE;
   379        
   380        /*!
   381         *  ======== transportType ========
   382         *  Determines the transport that UIA will be configured for.
   383         *
   384         *  For a given transport type, UIA picks an appropriate transport 
   385         *  implementation to use based on your device. This is specified by the
   386         *  ti.uia.family.Settings module. Refer to the examples for configuring
   387         *  the actual transport implementation.
   388         *
   389         *  If someone writes an new transport (e.g. RapidIO), 
   390         *  they can be plugged in by setting the TransportType
   391         *  to `TransportType_USER` and then plugging
   392         *  the transportFxns manually. It must also set up the following parameters
   393         *  as directed by the new transport developer.
   394         *  @p(blist)
   395         *  -ServiceMgr.supportControl: does the transport support receiving 
   396         *               messages from the host. For example TransportFile does not.
   397         *  -ServiceMgr.maxEventPacketSize: Max size of an outgoing event packet. For
   398         *               example TransportNdk uses 1472 (emac size minus headers)
   399         *  -ServiceMgr.maxCtrlPacketSize: Max size of the message packets. This can
   400         *               be zero if supportControl is false.
   401         *  @p
   402         *
   403         *  Here is an example of plugging the transport XYZ into the ServiceMgr:
   404         *  @p(code)
   405         *  var ServiceMgr = xdc.useModule('ti.uia.runtime.ServiceMgr');
   406         *  ServiceMgr.transportType = ServiceMgr.TransportType_USER;
   407         *  var xyzTransport = {
   408         *      initFxn: '&TransportXYZ_init',
   409         *      startFxn: '&TransportXYZ_start',
   410         *      recvFxn: '&TransportXYZ_recv',
   411         *      sendFxn: '&TransportXYZ_send',
   412         *      stopFxn: '&TransportXYZ_stop',
   413         *      exitFxn: '&TransportXYZ_exit',
   414         *  };
   415         *  ServiceMgr.transportFxns = xyzTransport;
   416         *
   417         *  ServiceMgr.maxEventPacketSize = 1024
   418         *  ServiceMgr.maxCtrlPacketSize  = 1024;
   419         *  ServiceMgr.supportControl     = true;
   420         *  @p
   421         */
   422        metaonly config TransportType transportType;
   423         
   424        /*!
   425         *  ======== periodInMs ========
   426         *  Period in miliseconds of ServiceMgr's transfer agent 
   427         *
   428         *  The transfer agent runs at the configured period. It checks to see
   429         *  if a service's period has expired. If it has expired, the service's 
   430         *  {@link #ProcessCallback} is called with the 
   431         *  {@link #Reason_PERIODEXPIRED} reason.
   432         *
   433         *  A service should not set it's period to a value less than the ServiceMgr
   434         *  module'speriod. A service's period should be a multiple of the 
   435         *  ServiceMgr module's period. If it is not, it will called at the rounded
   436         *  up period. For example, if ServiceMgr.periodInMs = 100 and a service 
   437         *  sets its period to 250. That service will be called every 300 
   438         *  milliseconds.
   439         *
   440         *  This value does not guarantee that the transfer agent will run at this
   441         *  rate. Even if the period has expired, the transfer agent will not run
   442         *  until the current running Task has yielded and there are no other higher
   443         *  priority Tasks ready.
   444         *
   445         *  Default is 100ms.
   446         */
   447        config Int periodInMs = 100;
   448    
   449        /*!
   450         *  ======== maxEventPacketSize  ========
   451         *  Size of Event packets in bytes
   452         *
   453         *  This size includes the UIAPacket header. This value's default 
   454         *  depends on the device.
   455         */
   456        config SizeT maxEventPacketSize;
   457    
   458        /*!
   459         *  ======== numEventPacketBufs  ========
   460         *  Number of UIAPacket events on the processor
   461         */
   462        config Int numEventPacketBufs  = 2;
   463    
   464        /*!
   465         *  ======== maxCtrlPacketSize  ========
   466         *  Size of control message packets in bytes
   467         *
   468         *  This size includes the UIAPacket header. This value's default 
   469         *  depends on the device.
   470         */
   471        config SizeT maxCtrlPacketSize;
   472    
   473        /*!
   474         *  ======== numOutgoingCtrlPacketBufs  ========
   475         *  Number of outgoing Ctrl buffers on the processor
   476         */
   477        config Int numOutgoingCtrlPacketBufs  = 2;
   478    
   479        /*!
   480         *  ======== numIncomingCtrlPacketBufs  ========
   481         *  Number of incoming Ctrl buffers on the master processor
   482         */
   483        config Int numIncomingCtrlPacketBufs  = 2;
   484        
   485        /*!
   486         *  ======== supportControl ========
   487         *  Configure whether control messages are supported.
   488         *
   489         *  Default is determined based on the device and transport type.
   490         *
   491         *  The application should only set this if {@link #transportType}
   492         *  is TransportType_USER and it is plugging in a new set
   493         *  of transport functions. The transport function package should
   494         *  specify how to set this parameter.
   495         */
   496        config Bool supportControl;
   497    
   498        /*!
   499         *  ======== transferAgentPriority ========
   500         *  Priority of the Transfer Agent Task.
   501         *
   502         *  Default is 1, the lowest priority.
   503         */
   504        config Int transferAgentPriority = 1;
   505    
   506        /*!
   507         *  ======== transferAgentStackSize ========
   508         *  Transfer Agent Task stack size in MAUs.
   509         *
   510         *  The recommended size is 2048 bytes.
   511         */
   512        config SizeT transferAgentStackSize = 2048;
   513    
   514        /*!
   515         *  ======== transferAgentStackSection ========
   516         *  Memory section for Transfer Agent Task's stack.
   517         *
   518         *  If this parameter is not set then the Task.defaultStackSection is used.
   519         *  See the Task module for instructions on creating a stack section in
   520         *  a different memory segment.
   521         */
   522        metaonly config String transferAgentStackSection = null;
   523        
   524        /*!
   525         *  ======== rxTaskPriority ========
   526         *  Priority of the Transfer Agent Task.
   527         *
   528         *  Default is 1, the lowest priority.
   529         */
   530        config Int rxTaskPriority = 1;
   531        
   532        /*!
   533         *  ======== rxTaskStackSize ========
   534         *  Transfer Agent Task stack size in MAUs.
   535         *
   536         *  The recommended size is 2048 bytes.
   537         */
   538        config SizeT rxTaskStackSize = 2048;
   539    
   540        /*!
   541         *  ======== rxTaskStackSection ========
   542         *  Memory section for Receiving Task's stack.
   543         *
   544         *  If this parameter is not set then the Task.defaultStackSection is used.
   545         *  See the Task module for instructions on creating a stack section in
   546         *  a different memory segment.
   547         */
   548        metaonly config String rxTaskStackSection = null;
   549        
   550        /*!     
   551         *  @_nodoc
   552         *  ======== SupportProxy ========
   553         *  The implementation module of the low-level ServiceMgr functions
   554         */
   555        proxy SupportProxy inherits IServiceMgrSupport;
   556    
   557        /*!
   558         *  ======== masterProcId ========
   559         *  Processor that communicates to the instrumentation host
   560         *
   561         *  This value denotes which core in a multiple core topology is 
   562         *  the master core. All routing of UIA data to the instrumentation
   563         *  host is done via this core.
   564         *
   565         *  The procId corresponds to Ipc's MultiProc value.
   566         *
   567         *  For single processor systems, or where there is no routing of 
   568         *  data via an intermediate core, this value is ignored.
   569         */
   570        config UInt16 masterProcId = 0;
   571    
   572        /*!
   573         *  ======== freePacket ========
   574         *  Function to return an unused packet back to the ServiceMgr module
   575         *
   576         *  This function can be used to return an unused packet back to the
   577         *  ServiceMgr module. It must only return packets that were obtained via
   578         *  the {@link #getFreePacket} function.
   579         *
   580         *  @param(packet)  Pointer to a UIAPacket
   581         */
   582        Void freePacket(UIAPacket.Hdr *packet);
   583    
   584        /*!
   585         *  ======== getFreePacket ========
   586         *  Function to obtain a free UIA packet
   587         *
   588         *  The service can specify what type of packet it wants with the 
   589         *  first parameter. Currently only UIAPacket_HdrType_Msg and 
   590         *  UIAPacket_HdrType_EventPkt are supported.
   591         *  
   592         *  The function fills in the HdrType field of the packet automatically
   593         *  for the service. All other fields are un-initialized.
   594         *
   595         *  @param(type)    Requested type of packet
   596         *  @param(timeout) Return after this many system time units
   597         *
   598         *  @b(returns)     Pointer to a packet if successful. NULL if timeout.
   599         */
   600        UIAPacket.Hdr *getFreePacket(UIAPacket.HdrType type, UInt timeout);
   601    
   602        /*!
   603         *  ======== getNumServices ========
   604         *  Returns the number of services present in the system
   605         *
   606         *  @b(returns)     Number of services
   607         */
   608        Int getNumServices();
   609        
   610        /*!
   611         *  @_nodoc
   612         *  ======== processCallback ========
   613         *  Callback function called by the support proxy
   614         *
   615         *  This function is called by the support proxy when it needs to 
   616         *  call a service's ProcessCallback function.
   617         *
   618         *  This function should not be called by a service.
   619         *
   620         *  @param(id)      Service id of the service
   621         *  @param(reason)  Reason for calling the service's ProcessCallback 
   622         *                  function
   623         *  @param(packet)  If the reason is {@link #Reason_INCOMINGMSG}, this
   624         *                  parameter points to the incoming msg. Otherwise it is 
   625         *                  NULL. The service does not own this packet. It should
   626         *                  NOT re-use it. Internally the ServiceMgr module will
   627         *                  return it to an internal queue after the 
   628         *                  processCallback returns.
   629         */
   630        Void processCallback(ServiceId id, Reason reason, UIAPacket.Hdr *packet);
   631    
   632        /*!
   633         *  ======== register ========
   634         *  Register a services with the ServiceMgr module
   635         *
   636         *  All service's must register with the ServiceMgr module statically.
   637         *
   638         *  Refer to {@link #periodInMs} for a description of the period parameter.
   639         *
   640         *  @param(id)      Service id of the service (refer to 
   641         *                  {@link #ServiceId}).
   642         *
   643         *  @param(processCallbackFxn)  Service's callback function.
   644         *
   645         *  @param(periodInMs) Period of the service.
   646         */
   647        metaonly Int register(ServiceId id, ProcessCallback processCallbackFxn,
   648                              UInt32 periodInMs);
   649    
   650        /*!
   651         *  ======== requestEnergy ========
   652         *  Function to request energy for a service
   653         *
   654         *  Generally services do not maintain an active thread. 
   655         *  They may request the ServiceMgr module to call the 
   656         *  {@link #ProcessCallback} in the context of the transfer agent. 
   657         *  This can be accomplished via this function.
   658         *
   659         *  @param(id)     Service id of the service
   660         */
   661        Void requestEnergy(ServiceId id);
   662    
   663        /*!
   664         *  ======== sendPacket ========
   665         *  Send a UIAPacket to the instrumentation host
   666         *
   667         *  All UIAPacket fields except for SenderAdrs must be filled in.
   668         * 
   669         *  The caller loses ownership of the packet once it is successfully sent.
   670         *  If this function fails, the caller still owns the packet. It can re-use
   671         *  it or free it via the {@link #freePacket} function.
   672         *
   673         *  @param(packet)  UIAPacket to be sent
   674         *
   675         *  @b(returns)     TRUE denotes success and the packet is
   676         *                  no longer owned by the caller. FALSE denotes
   677         *                  failure and the packet is still owned by the caller. 
   678         */
   679        Bool sendPacket(UIAPacket.Hdr *packet);
   680    
   681        /*!
   682         *  ======== setPeriod ========
   683         *  Allows services to set their event collection period
   684         *
   685         *  ServiceMgr's period should be a multiple of the ServiceMgr's period 
   686         *  ({@link #periodInMs}). If it is not, they will called at the rounded
   687         *  up period. For example, if ServiceMgr.periodInMs = 100 and a service sets
   688         *  its period to 250. That service will be called every 300 milliseconds.
   689         *
   690         *  @param(id)         Service id of the service
   691         *
   692         *  @param(periodInMs) Requested period in milliseconds
   693         */
   694        Void setPeriod(ServiceId id, UInt32 periodInMs);
   695       
   696    internal:
   697    
   698        /*!
   699         *  ======== ServiceMgr Information ========
   700         *  The following arrays contain information about each service
   701         */
   702        config ProcessCallback processCallbackFxn[];
   703    
   704        struct Module_State {
   705            Int runCount;
   706            Int numServices;
   707        };
   708    }
   709    
   710    /*
   711     *! Revision History
   712     *! ================
   713     *! 03-Mar-2010 toddm   Created
   714     */