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