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 */
32 /*
33 * ======== test_omx.c ========
34 *
35 * Example of setting up an "OMX" service with the ServiceMgr, allowing clients
36 * to instantiate OMX instances.
37 *
38 * Works with the test_omx.c Linux user space application over the rpmsg_omx\
39 * driver.
40 */
42 #include <xdc/std.h>
43 #include <xdc/cfg/global.h>
44 #include <xdc/runtime/System.h>
45 #include <xdc/runtime/Diags.h>
47 #include <ti/ipc/MultiProc.h>
48 #include <ti/sysbios/BIOS.h>
49 #include <ti/sysbios/knl/Task.h>
51 #include <ti/grcm/RcmTypes.h>
52 #include <ti/grcm/RcmServer.h>
54 #include <stdio.h>
55 #include <string.h>
56 #include <stdlib.h>
58 #include <ti/srvmgr/ServiceMgr.h>
59 #include <ti/srvmgr/rpmsg_omx.h>
60 #include <ti/srvmgr/omx_packet.h>
62 /* Turn on/off printf's */
63 #define CHATTER 0
65 /* Legacy function to allow Linux side rpmsg sample tests to work: */
66 extern void start_ping_tasks();
67 extern void start_resmgr_task();
68 extern void start_hwSpinlock_task();
70 /*
71 * OMX packet expected to have its data payload start with a payload of
72 * this value. Need to export this properly in a meaningful header file on
73 * both HLOS and RTOS sides
74 */
75 typedef enum {
76 RPC_OMX_MAP_INFO_NONE = 0,
77 RPC_OMX_MAP_INFO_ONE_BUF = 1,
78 RPC_OMX_MAP_INFO_TWO_BUF = 2,
79 RPC_OMX_MAP_INFO_THREE_BUF = 3,
80 RPC_OMX_MAP_INFO_MAX = 0x7FFFFFFF
81 } map_info_type;
83 /*
84 * ======== fxnDouble used by omx_benchmark test app ========
85 */
86 typedef struct {
87 Int a;
88 } FxnDoubleArgs;
90 static Int32 fxnDouble(UInt32 size, UInt32 *data);
92 /* ==========================================================================
93 * OMX Fxns, adapted from rpc_omx_skel.c.
94 *
95 * These defines are to illustrate reuse of RPC_SKEL fxns with ServiceMgr.
96 *===========================================================================*/
98 #define H264_DECODER_NAME "H264_decoder"
100 #define OMX_VIDEO_THREAD_PRIORITY 5
102 typedef Int32 RPC_OMX_ERRORTYPE;
103 typedef UInt32 OMX_HANDLETYPE;
105 static RPC_OMX_ERRORTYPE RPC_SKEL_GetHandle(Void *, UInt32 size, UInt32 *data);
106 static RPC_OMX_ERRORTYPE RPC_SKEL_SetParameter(UInt32 size, UInt32 *data);
107 static RPC_OMX_ERRORTYPE RPC_SKEL_GetParameter(UInt32 size, UInt32 *data);
111 /* RcmServer static function table */
112 static RcmServer_FxnDesc OMXServerFxnAry[] = {
113 // {"RPC_SKEL_GetHandle" , RPC_SKEL_GetHandle}, // Set at runtime.
114 {"RPC_SKEL_GetHandle" , NULL},
115 {"RPC_SKEL_SetParameter", RPC_SKEL_SetParameter},
116 {"RPC_SKEL_GetParameter", RPC_SKEL_GetParameter},
117 {"fxnDouble", fxnDouble },
118 };
120 #define OMXServerFxnAryLen (sizeof OMXServerFxnAry / sizeof OMXServerFxnAry[0])
122 static const RcmServer_FxnDescAry OMXServer_fxnTab = {
123 OMXServerFxnAryLen,
124 OMXServerFxnAry
125 };
128 static RPC_OMX_ERRORTYPE RPC_SKEL_SetParameter(UInt32 size, UInt32 *data)
129 {
130 #if CHATTER
131 System_printf("RPC_SKEL_SetParameter: Called\n");
132 #endif
134 return(0);
135 }
137 static RPC_OMX_ERRORTYPE RPC_SKEL_GetParameter(UInt32 size, UInt32 *data)
138 {
139 #if CHATTER
140 System_printf("RPC_SKEL_GetParameter: Called\n");
141 #endif
143 return(0);
144 }
146 #define CALLBACK_DATA "OMX_Callback"
147 #define PAYLOAD_SIZE sizeof(CALLBACK_DATA)
148 #define CALLBACK_DATA_SIZE (HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE)
150 static RPC_OMX_ERRORTYPE RPC_SKEL_GetHandle(Void *srvc, UInt32 size,
151 UInt32 *data)
152 {
153 char cComponentName[128] = {0};
154 OMX_HANDLETYPE hComp;
155 Char cb_data[HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE] = {0};
157 /*
158 * Note: Currently, rpmsg_omx linux driver expects an omx_msg_hdr in front
159 * of the omx_packet data, so we allow space for this:
160 */
161 struct omx_msg_hdr * hdr = (struct omx_msg_hdr *)cb_data;
162 struct omx_packet * packet = (struct omx_packet *)hdr->data;
165 //Marshalled:[>offset(cParameterName)|>pAppData|>offset(RcmServerName)|>pid|
166 //>--cComponentName--|>--CallingCorercmServerName--|
167 //<hComp]
169 strcpy(cComponentName, (char *)data + sizeof(map_info_type));
171 #if CHATTER
172 System_printf("RPC_SKEL_GetHandle: Component Name received: %s\n",
173 cComponentName);
174 #endif
176 /* Simulate sending an async OMX callback message, passing an omx_packet
177 * structure.
178 */
179 packet->msg_id = 99; // Set to indicate callback instance, buffer id, etc.
180 packet->fxn_idx = 5; // Set to indicate callback fxn
181 packet->data_size = PAYLOAD_SIZE;
182 strcpy((char *)packet->data, CALLBACK_DATA);
184 #if CHATTER
185 System_printf("RPC_SKEL_GetHandle: Sending callback message id: %d, "
186 "fxn_id: %d, data: %s\n",
187 packet->msg_id, packet->fxn_idx, packet->data);
188 #endif
189 ServiceMgr_send(srvc, cb_data, CALLBACK_DATA_SIZE);
191 /* Call OMX_Get_Handle() and return handle for future calls. */
192 //eCompReturn = OMX_GetHandle(&hComp, (OMX_STRING)&cComponentName[0], pAppData,&rpcCallBackInfo);
193 hComp = 0x5C0FFEE5;
194 data[0] = hComp;
196 #if CHATTER
197 System_printf("RPC_SKEL_GetHandle: returning hComp: 0x%x\n", hComp);
198 #endif
200 return(0);
201 }
203 /*
204 * ======== fxnDouble ========
205 */
206 Int32 fxnDouble(UInt32 size, UInt32 *data)
207 {
208 FxnDoubleArgs *args;
209 Int a;
211 #if CHATTER
212 System_printf("fxnDouble: Executing fxnDouble \n");
213 #endif
215 args = (FxnDoubleArgs *)((UInt32)data + sizeof(map_info_type));
216 a = args->a;
218 return a * 2;
219 }
221 Int main(Int argc, char* argv[])
222 {
223 RcmServer_Params rcmServerParams;
225 System_printf("%s starting..\n", MultiProc_getName(MultiProc_self()));
227 /*
228 * Enable use of runtime Diags_setMask per module:
229 *
230 * Codes: E = ENTRY, X = EXIT, L = LIFECYCLE, F = INFO, S = STATUS
231 */
232 Diags_setMask("ti.ipc.rpmsg.MessageQCopy=EXLFS");
234 /* Setup the table of services, so clients can create and connect to
235 * new service instances:
236 */
237 ServiceMgr_init();
239 /* initialize RcmServer create params */
240 RcmServer_Params_init(&rcmServerParams);
242 /* The first function, at index 0, is a special create function, which
243 * gets passed a Service_Handle argument.
244 * We set this at run time as our C compiler is not allowing named union
245 * field initialization:
246 */
247 OMXServer_fxnTab.elem[0].addr.createFxn = RPC_SKEL_GetHandle;
249 rcmServerParams.priority = Thread_Priority_ABOVE_NORMAL;
250 rcmServerParams.stackSize = 0x1000;
251 rcmServerParams.fxns.length = OMXServer_fxnTab.length;
252 rcmServerParams.fxns.elem = OMXServer_fxnTab.elem;
254 /* Register an OMX service to create and call new OMX components: */
255 ServiceMgr_register("OMX", &rcmServerParams);
257 /* Some background ping testing tasks, used by rpmsg samples: */
258 start_ping_tasks();
260 #if 0 /* DSP or CORE0 or IPU */
261 /* Run a background task to test rpmsg_resmgr service */
262 start_resmgr_task();
263 #endif
265 #if 0 /* DSP or CORE0 or IPU */
266 /* Run a background task to test hwspinlock */
267 start_hwSpinlock_task();
268 #endif
270 /* Start the ServiceMgr services */
271 ServiceMgr_start(0);
273 BIOS_start();
275 return (0);
276 }