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