1 /*
2 * Copyright (c) 2011-2013, 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 */
34 /*
35 * ======== RcmServer.h ========
36 *
37 */
39 /*!
40 * @file ti/grcm/RcmServer.h
41 *
42 * @brief Remote Command Message Server Module. An RcmServer processes
43 * inbound messages received from an RcmClient.
44 *
45 * The RcmServer processes inbound messages received from an RcmClient.
46 * After processing a message, the server will return the message to
47 * the client.
48 *
49 * @sa RcmClient.h <br>
50 * @ref ti_grcm "RCM Overview"
51 */
53 /*!
54 * @defgroup ti_grcm_RcmServer RcmServer
55 *
56 * @brief Remote Command Message Server Module. An RcmServer processes
57 * inbound messages received from an RcmClient.
58 *
59 * The RcmServer module is used to create an server instance. RcmClients
60 * send their messages to only one RcmServer instance for processing. The
61 * server instance can be created with a function dispatch table and
62 * additional tables can be added as requested by the clients.
63 *
64 * Diagnostics
65 *
66 * Diags_INFO - full detail log events
67 * Diags_USER1 - message processing
68 *
69 * @sa ti_grcm_RcmClient <br>
70 * @ref ti_grcm "RCM Overview"
71 */
73 #ifndef ti_grcm_RcmServer__include
74 #define ti_grcm_RcmServer__include
76 #include <xdc/runtime/knl/GateThread.h>
77 #include <xdc/runtime/knl/Thread.h>
79 /* For USE_MESSAGEQCOPY setting */
80 #include <ti/grcm/RcmTypes.h>
83 /** @ingroup ti_grcm_RcmServer */
84 /*@{*/
86 #if defined (__cplusplus)
87 extern "C" {
88 #endif
91 // -------- success and failure codes --------
93 /*!
94 * @brief Success return code
95 */
96 #define RcmServer_S_SUCCESS (0)
98 /*!
99 * @brief General failure return code
100 */
101 #define RcmServer_E_FAIL (-1)
103 /*!
104 * @brief The was insufficient memory left on the heap
105 */
106 #define RcmServer_E_NOMEMORY (-2)
108 /*!
109 * @brief The given symbol was not found in the server's symbol table
110 *
111 * This error could occur if the symbol spelling is incorrect or
112 * if the RcmServer is still loading its symbol table.
113 */
114 #define RcmServer_E_SYMBOLNOTFOUND (-3)
116 /*!
117 * @brief The given symbols is in the static table, it cannot be removed
118 *
119 * All symbols installed at instance create time are added to the
120 * static symbol table. They cannot be removed. The statis symbol
121 * table must remain intact for the lifespan of the server instance.
122 */
123 #define RcmServer_E_SYMBOLSTATIC (-4)
125 /*!
126 * @brief The server's symbol table is full
127 *
128 * The symbol table is full. You must remove some symbols before
129 * any new symbols can be added.
130 */
131 #define RcmServer_E_SYMBOLTABLEFULL (-5)
134 // -------- constants and types --------
136 /*!
137 * @brief Remote function type
138 *
139 * All functions executed by the RcmServer must be of this
140 * type. Typically, these functions are simply wrappers to the vendor
141 * function. The server invokes this remote function by passing in
142 * the RcmClient_Message.dataSize field and the address of the
143 * RcmClient_Message.data array.
144 *
145 * @code
146 * RcmServer_MsgFxn fxn = ...;
147 * RcmClient_Message *msg = ...;
148 * msg->result = (*fxn)(msg->dataSize, msg->data);
149 * @endcode
150 */
152 typedef Int32 (*RcmServer_MsgFxn)(UInt32, UInt32 *);
154 #if USE_MESSAGEQCOPY
155 /* This is a special function which gets the RcmServer handle as first parameter
156 * so that OMX_GetHandle() or other creation functions can store the RcmServer
157 * handle in their own context. This is needed to allow functions to send
158 * asynchrounous callbacks back to the RcmServer client.
159 */
160 typedef Int32 (*RcmServer_MsgCreateFxn)(Void *, UInt32, UInt32 *);
161 #endif
165 /*!
166 * @brief Function descriptor
167 *
168 * This function descriptor is used internally in the server. Its
169 * values are defined either at config time by the server's
170 * RcmServer_Params.fxns create parameter or at runtime through a call to
171 * RcmClient_addSymbol().
172 */
173 typedef struct {
174 /*!
175 * @brief The name of the function
176 *
177 * The name is used for table lookup, it does not search the
178 * actual symbol table. You can provide any string as long as it
179 * is unique and the client uses the same name for lookup.
180 */
181 String name;
183 /*!
184 * @brief The function address in the server's address space.
185 *
186 * The server will ultimately branch to this address.
187 */
188 #if USE_MESSAGEQCOPY
189 union {
190 RcmServer_MsgFxn fxn;
191 RcmServer_MsgCreateFxn createFxn;
192 }addr;
193 #else
194 RcmServer_MsgFxn addr;
195 #endif
197 } RcmServer_FxnDesc;
199 /*!
200 * @brief Function descriptor array
201 */
202 typedef struct {
203 /*!
204 * @brief The length of the array
205 */
206 Int length;
208 /*!
209 * @brief Pointer to the array
210 */
211 RcmServer_FxnDesc *elem;
213 } RcmServer_FxnDescAry;
215 /*!
216 * @brief Worker pool descriptor
217 *
218 * Use this data structure to define a worker pool to be created either
219 * at the server create time or dynamically at runtime.
220 */
221 typedef struct {
222 /*!
223 * @brief The name of the worker pool.
224 */
225 String name;
227 /*!
228 * @brief The number of worker threads in the pool.
229 */
230 UInt count;
232 /*!
233 * @brief The priority of all threads in the worker pool.
234 *
235 * This value is Operating System independent. It determines the
236 * execution priority of all the worker threads in the pool.
237 */
238 Thread_Priority priority;
240 /*!
241 * @brief The priority (OS-specific) of all threads in the worker pool
242 *
243 * This value is Operating System specific. It determines the execution
244 * priority of all the worker threads in the pool. If this property is
245 * set, it takes precedence over the priority property above.
246 */
247 Int osPriority;
249 /*!
250 * @brief The stack size in bytes of a worker thread.
251 */
252 SizeT stackSize;
254 /*!
255 * @brief The worker thread stack placement.
256 */
257 String stackSeg;
259 } RcmServer_ThreadPoolDesc;
261 /*!
262 * @brief Worker pool descriptor array
263 */
264 typedef struct {
265 /*!
266 * @brief The length of the array
267 */
268 Int length;
270 /*!
271 * @brief Pointer to the array
272 */
273 RcmServer_ThreadPoolDesc *elem;
275 } RcmServer_ThreadPoolDescAry;
278 /*!
279 * @brief RcmServer instance object handle
280 */
281 typedef struct RcmServer_Object_tag *RcmServer_Handle;
283 /*!
284 * @brief RcmServer Instance create parameters
285 */
286 typedef struct {
287 /*!
288 * @brief Server thread priority.
289 *
290 * This value is Operating System independent. It determines the execution
291 * priority of the server thread. The server thread reads the incoming
292 * message and then either executes the message function (in-band
293 * execution) or dispatches the message to a thread pool (out-of-band
294 * execution). The server thread then wait on the next message.
295 */
296 Thread_Priority priority;
298 /*!
299 * @brief Server thread priority (OS-specific).
300 *
301 * This value is Operating System specific. It determines the execution
302 * priority of the server thread. If this attribute is set, it takes
303 * precedence over the priority attribute below. The server thread reads
304 * the incoming message and then either executes the message function
305 * (in-band execution) or dispatches the message to a thread pool
306 * (out-of-band execution). The server thread then wait on the next
307 * message.
308 */
309 Int osPriority;
311 /*!
312 * @brief The stack size in bytes of the server thread.
313 */
314 SizeT stackSize;
316 /*!
317 * @brief The server thread stack placement.
318 */
319 String stackSeg;
321 /*!
322 * @brief The default thread pool used for anonymous messages.
323 */
324 RcmServer_ThreadPoolDesc defaultPool;
326 /*!
327 * @brief Array of thread pool descriptors
328 *
329 * The worker pools declared with this instance parameter are statically
330 * bound to the server, they persist for the life of the server. They
331 * cannot be removed with a call to RcmServer_deletePool(). However,
332 * worker threads may be created or deleted at runtime.
333 *
334 */
335 RcmServer_ThreadPoolDescAry workerPools;
337 /*!
338 * @brief Array of function names to install into the server
339 *
340 * The functions declared with this instance parameter are statically
341 * bound to the server, they persist for the life of the server. They
342 * cannot be removed with a call to RcmServer_removeSymbol().
343 *
344 * To specify a function address, use the & character in the string
345 * as in the following example.
346 *
347 * @code
348 * RcmServer_FxnDesc serverFxnAry[] = {
349 * { "LED_on", LED_on },
350 * { "LED_off", LED_off }
351 * };
352 *
353 * #define serverFxnAryLen (sizeof serverFxnAry / sizeof serverFxnAry[0])
354 *
355 * RcmServer_FxnDescAry Server_fxnTab = {
356 * serverFxnAryLen,
357 * serverFxnAry
358 * };
359 *
360 * RcmServer_Params rcmServerP;
361 * RcmServer_Params_init(&rcmServerP);
362 * rcmServerP.fxns.length = Server_fxnTab.length;
363 * rcmServerP.fxns.elem = Server_fxnTab.elem;
364 *
365 * RcmServer_Handle rcmServerH;
366 * rval = RcmServer_create("ServerA", &rcmServerP, &(rcmServerH));
367 * @endcode
368 */
369 RcmServer_FxnDescAry fxns;
371 } RcmServer_Params;
373 /*!
374 * @brief Opaque client structure large enough to hold an instance object
375 *
376 * Use this structure to define an embedded RcmServer object.
377 *
378 * @sa RcmServer_construct
379 */
380 typedef struct {
381 GateThread_Struct _f1;
382 Ptr _f2;
383 #if USE_MESSAGEQCOPY
384 Ptr _f3a;
385 UInt32 _f3b;
386 UInt32 _f3c;
387 UInt32 _f3d;
388 #else
389 Ptr _f3;
390 #endif
391 Ptr _f4;
392 struct {
393 Int _f1;
394 Ptr _f2;
395 } _f5;
396 Ptr _f6[9];
397 UInt16 _f7;
398 UInt16 _f8;
399 Bool _f9;
400 Int _f10;
401 Ptr _f11[4];
402 Ptr _f12;
403 } RcmServer_Struct;
406 // -------- functions --------
408 /*
409 * ======== RcmServer_addSymbol ========
410 */
411 /*!
412 * @brief Add a symbol to the server's function table
413 *
414 * This function adds a new symbol to the server's function table.
415 * This is useful for supporting Dynamic Load Libraries (DLLs).
416 *
417 * @param[in] handle Handle to an instance object.
418 *
419 * @param[in] name The function's name.
420 *
421 * @param[in] addr The function's address in the server's address space.
422 *
423 * @param[out] index The function's index value to be used in the
424 * RcmClient_Message.fxnIdx field.
425 *
426 * @retval RcmClient_S_SUCCESS
427 * @retval RcmServer_E_NOMEMORY
428 * @retval RcmServer_E_SYMBOLTABLEFULL
429 */
430 Int RcmServer_addSymbol(
431 RcmServer_Handle handle,
432 String name,
433 RcmServer_MsgFxn addr,
434 UInt32 * index
435 );
437 /*
438 * ======== RcmServer_construct ========
439 */
440 /*!
441 * @brief Initialize a new instance object inside the provided structure
442 *
443 * This function is the same as RcmServer_create() except that it does not
444 * allocate memory for the instance object. The instance object is
445 * constructed inside the provided structure. Call RcmServer_destruct()
446 * to finalize a constructed instance object.
447 *
448 * @param[in] structPtr A pointer to an allocated structure.
449 *
450 * @param[in] name The name of the server. The RcmClient will
451 * locate a server instance using this name. It must be unique to
452 * the system.
453 *
454 * @param[in] params The create params used to customize the instance object.
455 *
456 * @retval RcmClient_S_SUCCESS
457 * @retval RcmServer_E_FAIL
458 * @retval RcmServer_E_NOMEMORY
459 *
460 * @sa RcmServer_create
461 */
462 Int RcmServer_construct(
463 RcmServer_Struct * structPtr,
464 String name,
465 const RcmServer_Params *params
466 );
468 /*
469 * ======== RcmServer_create ========
470 */
471 /*!
472 * @brief Create an RcmServer instance
473 *
474 * A server instance is used to execute functions on behalf of an
475 * RcmClient instance. There can be multiple server instances
476 * on any given CPU. The servers typically reside on a remote CPU
477 * from the RcmClient instance.
478 *
479 * @param[in] name The name of the server. The RcmClient will
480 * locate a server instance using this name. It must be unique to
481 * the system.
482 *
483 * @param[in] params The create params used to customize the instance object.
484 *
485 * @param[out] handle An opaque handle to the created instance object.
486 *
487 * @retval RcmClient_S_SUCCESS
488 * @retval RcmServer_E_FAIL
489 * @retval RcmServer_E_NOMEMORY
490 */
491 Int RcmServer_create(
492 String name,
493 RcmServer_Params * params,
494 RcmServer_Handle * handle
495 );
497 /*
498 * ======== RcmServer_delete ========
499 */
500 /*!
501 * @brief Delete an RcmServer instance
502 *
503 * @param[in,out] handlePtr Handle to the instance object to delete.
504 */
505 Int RcmServer_delete(
506 RcmServer_Handle * handlePtr
507 );
509 /*
510 * ======== RcmServer_destruct ========
511 */
512 /*!
513 * @brief Finalize the instance object inside the provided structure
514 *
515 * @param[in] structPtr A pointer to the structure containing the
516 * instance object to finalize.
517 */
518 Int RcmServer_destruct(
519 RcmServer_Struct * structPtr
520 );
522 /*
523 * ======== RcmServer_exit ========
524 */
525 /*!
526 * @brief Finalize the RcmServer module
527 *
528 * This function is used to finalize the RcmServer module. Any resources
529 * acquired by RcmServer_init() will be released. Do not call any RcmServer
530 * functions after calling RcmServer_exit().
531 *
532 * This function must be serialized by the caller.
533 */
534 Void RcmServer_exit(Void);
536 /*
537 * ======== RcmServer_init ========
538 */
539 /*!
540 * @brief Initialize the RcmServer module
541 *
542 * This function is used to initialize the RcmServer module. Call this
543 * function before calling any other RcmServer function.
544 *
545 * This function must be serialized by the caller
546 */
547 Void RcmServer_init(Void);
549 /*
550 * ======== RcmServer_Params_init ========
551 */
552 /*!
553 * @brief Initialize the instance create params structure
554 */
555 Void RcmServer_Params_init(
556 RcmServer_Params * params
557 );
559 /*
560 * ======== RcmServer_removeSymbol ========
561 */
562 /*!
563 * @brief Remove a symbol and from the server's function table
564 *
565 * Useful when unloading a DLL from the server.
566 *
567 * @param[in] handle Handle to an instance object.
568 *
569 * @param[in] name The function's name.
570 *
571 * @retval RcmClient_S_SUCCESS
572 * @retval RcmServer_E_SYMBOLNOTFOUND
573 * @retval RcmServer_E_SYMBOLSTATIC
574 */
575 Int RcmServer_removeSymbol(
576 RcmServer_Handle handle,
577 String name
578 );
580 /*
581 * ======== RcmServer_start ========
582 */
583 /*!
584 * @brief Start the server
585 *
586 * The server is created in stop mode. It will not start
587 * processing messages until it has been started.
588 *
589 * @param[in] handle Handle to an instance object.
590 *
591 * @retval RcmClient_S_SUCCESS
592 * @retval RcmServer_E_FAIL
593 */
594 Int RcmServer_start(
595 RcmServer_Handle handle
596 );
599 #if USE_MESSAGEQCOPY
600 /*
601 * ======== RcmServer_getLocalAddress ========
602 */
603 /*!
604 * @brief Get the messageQ endpoint created for this server.
605 *
606 * @param[in] handle Handle to an instance object.
607 *
608 * @retval 32 bit address.
609 */
610 UInt32 RcmServer_getLocalAddress(
611 RcmServer_Handle handle
612 );
614 /*
615 * ======== RcmServer_getRemoteAddress ========
616 */
617 /*!
618 * @brief Get the remote messageQ endpoint for the client of this server.
619 *
620 * @param[in] handle Handle to an instance object.
621 *
622 * @retval 32 bit address.
623 */
624 UInt32 RcmServer_getRemoteAddress(
625 RcmServer_Handle handle
626 );
628 /*
629 * ======== RcmServer_getRemoteProc ========
630 */
631 /*!
632 * @brief Get the remote procId for the client of this server.
633 *
634 * @param[in] handle Handle to an instance object.
635 *
636 * @retval 32 bit address.
637 */
638 UInt16 RcmServer_getRemoteProc(
639 RcmServer_Handle handle
640 );
643 #endif
646 #if defined (__cplusplus)
647 }
648 #endif /* defined (__cplusplus) */
650 /*@}*/
651 #endif /* ti_grcm_RcmServer__include */