1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32
33 34 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
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
218
219
220
221
222
223
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 * TransportType defines what the underlying transport will be used. In
283 * a multi-core topology, this parameter is only relevant for the
284 * {@link #masterProcId} core. The masterProcId core uses the TransportType
285 * to determine how to get the data off the target.
286 *
287 * @p(blist)
288 * -TransportType_ETHERNET: Use the Ethernet transport. On a SYS/BIOS
289 * system, this uses the NDK. The application is responsible for
290 * adding the NDK into the application and initializing it.
291 * -TransportType_FILE: Use the File transport.
292 * On a SYS/BIOS system, this transport requires a JTAG connection.
293 * -TransportType_USER: This allows the application to specify their
294 * own transport functions.
295 * -TransportType_NULL: No transport functions are needed. This should
296 * only be used on the non-masterProcId cores.
297 * @p
298 */
299 metaonly enum TransportType {
300 TransportType_ETHERNET,
301 TransportType_FILE,
302 TransportType_USER,
303 TransportType_NULL
304 };
305
306 /*!
307 * ======== ProcessCallback ========
308 * Function prototype for the processMsg callback
309 *
310 * A ProcessCallback function must be supplied by every service.
311 * The function is provided in the {@link #register} function.
312 *
313 * For a description of the ServiceMgr_Reason parameter, please refer
314 * to {@link #Reason}.
315 *
316 * The UIPacket_Hdr field is only used in the {@link #Reason_INCOMINGMSG}
317 * case. For any other reason, this value is NULL.
318 */
319 typedef Void (*ProcessCallback)(Reason, UIAPacket.Hdr *);
320
321 /*!
322 * ======== WAIT_FOREVER ========
323 * Wait forever constant that can be used in ServiceMgr_getFreePacket.
324 */
325 const UInt WAIT_FOREVER = ~(0);
326
327 /*! @_nodoc */
328 metaonly struct ServiceIdDesc { Bits16 val; };
329
330 /*!
331 * ======== ServiceId ========
332 * Used by services to generate a serviceId
333 *
334 * Services needs to define a ServiceId in their xdc file.
335 * Then the ServiceMgr module will assign a unique value to it during
336 * build time.
337 *
338 * For example in ti.uia.service.Rta.xdc there is the following line:
339 * @p(code)
340 * readonly config ServiceMgr.ServiceId SERVICEID;
341 * @p
342 */
343 @Encoded typedef ServiceIdDesc ServiceId; /*! Control command type */
344
345 /*!
346 * Assert raised when calling API with invalid ServiceId
347 */
348 config Assert.Id A_invalidServiceId = {
349 msg: "A_invalidServiceId: ServiceId out of range"
350 };
351
352 /*!
353 * Assert raised invalid processCallbackFxn is supplied
354 */
355 config Assert.Id A_invalidProcessCallbackFxn = {
356 msg: "A_invalidProcessCallbackFxn: Callback cannot be NULL"
357 };
358
359 /*!
360 * ======== customTransportType ========
361 * Custom transport used to send the records to an instrumentation host
362 */
363 metaonly config String customTransportType = null;
364
365 /*!
366 * ======== transportFxns ========
367 * Transport functions used to communicate to the instrumentation host
368 *
369 * These functions are setup by default based on the device.
370 * The user can explicitly set this parameter if the default is not
371 * appropriate.
372 */
373 config Transport.FxnSet transportFxns;
374
375 /*!
376 * ======== topology ========
377 * Used to define UIA topology.
378 *
379 * If `Topology_MULTICORE` is chosen, the ServiceMgr will use Ipc to
380 * discover the core configuration and to communicate between the cores.
381 * UIA will route the outbound packets from each core through the master
382 * core. UIA will also route messages received by the master core to
383 * their intended recipient.
384 *
385 * If UIA is configured for Topology_SINGLECORE, each core on the device
386 * communicates with the instrumentation host directly.
387 *
388 * The default is Topology_SINGLECORE.
389 */
390 config Topology topology = Topology_SINGLECORE;
391
392 /*!
393 * ======== transportType ========
394 * Determines the transport that UIA will be configured for.
395 *
396 * For a given transport type, UIA picks an appropriate transport
397 * implementation to use based on your device. This is specified by the
398 * ti.uia.family.Settings module. Refer to the examples for configuring
399 * the actual transport implementation.
400 *
401 * If someone writes an new transport (e.g. RapidIO),
402 * they can be plugged in by setting the TransportType
403 * to `TransportType_USER` and then plugging
404 * the transportFxns manually. It must also set up the following parameters
405 * as directed by the new transport developer.
406 * @p(blist)
407 * -ServiceMgr.supportControl: does the transport support receiving
408 * messages from the host. For example TransportFile does not.
409 * -ServiceMgr.maxEventPacketSize: Max size of an outgoing event packet. For
410 * example TransportNdk uses 1472 (emac size minus headers)
411 * -ServiceMgr.maxCtrlPacketSize: Max size of the message packets. This can
412 * be zero if supportControl is false.
413 * @p
414 *
415 * Here is an example of plugging the transport XYZ into the ServiceMgr:
416 * @p(code)
417 * var ServiceMgr = xdc.useModule('ti.uia.runtime.ServiceMgr');
418 * ServiceMgr.transportType = ServiceMgr.TransportType_USER;
419 * var xyzTransport = {
420 * initFxn: '&TransportXYZ_init',
421 * startFxn: '&TransportXYZ_start',
422 * recvFxn: '&TransportXYZ_recv',
423 * sendFxn: '&TransportXYZ_send',
424 * stopFxn: '&TransportXYZ_stop',
425 * exitFxn: '&TransportXYZ_exit'
426 * };
427 * ServiceMgr.transportFxns = xyzTransport;
428 *
429 * ServiceMgr.maxEventPacketSize = 1024
430 * ServiceMgr.maxCtrlPacketSize = 1024;
431 * ServiceMgr.supportControl = true;
432 * @p
433 */
434 metaonly config TransportType transportType;
435
436 /*!
437 * ======== periodInMs ========
438 * Period in miliseconds of ServiceMgr's transfer agent
439 *
440 * The transfer agent runs at the configured period. It checks to see
441 * if a service's period has expired. If it has expired, the service's
442 * {@link #ProcessCallback} is called with the
443 * {@link #Reason_PERIODEXPIRED} reason.
444 *
445 * A service should not set it's period to a value less than the ServiceMgr
446 * module'speriod. A service's period should be a multiple of the
447 * ServiceMgr module's period. If it is not, it will called at the rounded
448 * up period. For example, if ServiceMgr.periodInMs = 100 and a service
449 * sets its period to 250. That service will be called every 300
450 * milliseconds.
451 *
452 * This value does not guarantee that the transfer agent will run at this
453 * rate. Even if the period has expired, the transfer agent will not run
454 * until the current running Task has yielded and there are no other higher
455 * priority Tasks ready.
456 *
457 * Default is 100ms.
458 */
459 config Int periodInMs = 100;
460
461 /*!
462 * ======== maxEventPacketSize ========
463 * Size of Event packets in bytes
464 *
465 * This size includes the UIAPacket header. This value's default
466 * depends on the device.
467 */
468 config SizeT maxEventPacketSize;
469
470 /*!
471 * ======== numEventPacketBufs ========
472 * Number of UIAPacket events on the processor
473 */
474 config Int numEventPacketBufs = 2;
475
476 /*!
477 * ======== maxCtrlPacketSize ========
478 * Size of control message packets in bytes
479 *
480 * This size includes the UIAPacket header. This value's default
481 * depends on the device.
482 */
483 config SizeT maxCtrlPacketSize;
484
485 /*!
486 * ======== numOutgoingCtrlPacketBufs ========
487 * Number of outgoing Ctrl buffers on the processor
488 */
489 config Int numOutgoingCtrlPacketBufs = 2;
490
491 /*!
492 * ======== numIncomingCtrlPacketBufs ========
493 * Number of incoming Ctrl buffers on the master processor
494 */
495 config Int numIncomingCtrlPacketBufs = 2;
496
497 /*!
498 * ======== supportControl ========
499 * Configure whether control messages are supported.
500 *
501 * Default is determined based on the device and transport type.
502 *
503 * The application should only set this if {@link #transportType}
504 * is TransportType_USER and it is plugging in a new set
505 * of transport functions. The transport function package should
506 * specify how to set this parameter.
507 */
508 config Bool supportControl;
509
510 /*!
511 * ======== transferAgentPriority ========
512 * Priority of the Transfer Agent Task.
513 *
514 * Default is 1, the lowest priority.
515 */
516 config Int transferAgentPriority = 1;
517
518 /*!
519 * ======== transferAgentStackSize ========
520 * Transfer Agent Task stack size in MAUs.
521 *
522 * The recommended size is 2048 bytes.
523 */
524 config SizeT transferAgentStackSize = 2048;
525
526 /*!
527 * ======== transferAgentStackSection ========
528 * Memory section for Transfer Agent Task's stack.
529 *
530 * If this parameter is not set then the Task.defaultStackSection is used.
531 * See the Task module for instructions on creating a stack section in
532 * a different memory segment.
533 */
534 metaonly config String transferAgentStackSection = null;
535
536 /*!
537 * ======== rxTaskPriority ========
538 * Priority of the Transfer Agent Task.
539 *
540 * Default is 1, the lowest priority.
541 */
542 config Int rxTaskPriority = 1;
543
544 /*!
545 * ======== rxTaskStackSize ========
546 * Transfer Agent Task stack size in MAUs.
547 *
548 * The recommended size is 2048 bytes.
549 */
550 config SizeT rxTaskStackSize = 2048;
551
552 /*!
553 * ======== rxTaskStackSection ========
554 * Memory section for Receiving Task's stack.
555 *
556 * If this parameter is not set then the Task.defaultStackSection is used.
557 * See the Task module for instructions on creating a stack section in
558 * a different memory segment.
559 */
560 metaonly config String rxTaskStackSection = null;
561
562 /*!
563 * @_nodoc
564 * ======== SupportProxy ========
565 * The implementation module of the low-level ServiceMgr functions
566 */
567 proxy SupportProxy inherits IServiceMgrSupport;
568
569 /*!
570 * ======== masterProcId ========
571 * Processor that communicates to the instrumentation host
572 *
573 * This value denotes which core in a multiple core topology is
574 * the master core. All routing of UIA data to the instrumentation
575 * host is done via this core.
576 *
577 * The procId corresponds to Ipc's MultiProc value.
578 *
579 * For single processor systems, or where there is no routing of
580 * data via an intermediate core, this value is ignored.
581 */
582 config UInt16 masterProcId = 0;
583
584 /*!
585 * ======== freePacket ========
586 * Function to return an unused packet back to the ServiceMgr module
587 *
588 * This function can be used to return an unused packet back to the
589 * ServiceMgr module. It must only return packets that were obtained via
590 * the {@link #getFreePacket} function.
591 *
592 * @param(packet) Pointer to a UIAPacket
593 */
594 Void freePacket(UIAPacket.Hdr *packet);
595
596 /*!
597 * ======== getFreePacket ========
598 * Function to obtain a free UIA packet
599 *
600 * The service can specify what type of packet it wants with the
601 * first parameter. Currently only UIAPacket_HdrType_Msg and
602 * UIAPacket_HdrType_EventPkt are supported.
603 *
604 * The function fills in the HdrType field of the packet automatically
605 * for the service. All other fields are un-initialized.
606 *
607 * @param(type) Requested type of packet
608 * @param(timeout) Return after this many system time units
609 *
610 * @b(returns) Pointer to a packet if successful. NULL if timeout.
611 */
612 UIAPacket.Hdr *getFreePacket(UIAPacket.HdrType type, UInt timeout);
613
614 /*!
615 * ======== getNumServices ========
616 * Returns the number of services present in the system
617 *
618 * @b(returns) Number of services
619 */
620 Int getNumServices();
621
622 /*!
623 * @_nodoc
624 * ======== processCallback ========
625 * Callback function called by the support proxy
626 *
627 * This function is called by the support proxy when it needs to
628 * call a service's ProcessCallback function.
629 *
630 * This function should not be called by a service.
631 *
632 * @param(id) Service id of the service
633 * @param(reason) Reason for calling the service's ProcessCallback
634 * function
635 * @param(packet) If the reason is {@link #Reason_INCOMINGMSG}, this
636 * parameter points to the incoming msg. Otherwise it is
637 * NULL. The service does not own this packet. It should
638 * NOT re-use it. Internally the ServiceMgr module will
639 * return it to an internal queue after the
640 * processCallback returns.
641 */
642 Void processCallback(ServiceId id, Reason reason, UIAPacket.Hdr *packet);
643
644 /*!
645 * ======== register ========
646 * Register a services with the ServiceMgr module
647 *
648 * All service's must register with the ServiceMgr module statically.
649 *
650 * Refer to {@link #periodInMs} for a description of the period parameter.
651 *
652 * @param(id) Service id of the service (refer to
653 * {@link #ServiceId}).
654 *
655 * @param(processCallbackFxn) Service's callback function.
656 *
657 * @param(periodInMs) Period of the service.
658 */
659 metaonly Int register(ServiceId id, ProcessCallback processCallbackFxn,
660 UInt32 periodInMs);
661
662 /*!
663 * ======== requestEnergy ========
664 * Function to request energy for a service
665 *
666 * Generally services do not maintain an active thread.
667 * They may request the ServiceMgr module to call the
668 * {@link #ProcessCallback} in the context of the transfer agent.
669 * This can be accomplished via this function.
670 *
671 * @param(id) Service id of the service
672 */
673 Void requestEnergy(ServiceId id);
674
675 /*!
676 * ======== sendPacket ========
677 * Send a UIAPacket to the instrumentation host
678 *
679 * All UIAPacket fields except for SenderAdrs must be filled in.
680 *
681 * The caller loses ownership of the packet once it is successfully sent.
682 * If this function fails, the caller still owns the packet. It can re-use
683 * it or free it via the {@link #freePacket} function.
684 *
685 * @param(packet) UIAPacket to be sent
686 *
687 * @b(returns) TRUE denotes success and the packet is
688 * no longer owned by the caller. FALSE denotes
689 * failure and the packet is still owned by the caller.
690 */
691 Bool sendPacket(UIAPacket.Hdr *packet);
692
693 /*!
694 * ======== setPeriod ========
695 * Allows services to set their event collection period
696 *
697 * ServiceMgr's period should be a multiple of the ServiceMgr's period
698 * ({@link #periodInMs}). If it is not, they will called at the rounded
699 * up period. For example, if ServiceMgr.periodInMs = 100 and a service sets
700 * its period to 250. That service will be called every 300 milliseconds.
701 *
702 * @param(id) Service id of the service
703 *
704 * @param(periodInMs) Requested period in milliseconds
705 */
706 Void setPeriod(ServiceId id, UInt32 periodInMs);
707
708 internal:
709
710 /*!
711 * ======== ServiceMgr Information ========
712 * The following arrays contain information about each service
713 */
714 config ProcessCallback processCallbackFxn[];
715
716 struct Module_State {
717 Int runCount;
718 Int numServices;
719 };
720 }