1 /*
2 * Copyright (c) 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 * ======== rpc_task.c ========
34 *
35 * Example of setting up a 'RPC' service with the ServiceMgr, allowing clients
36 * to instantiate the example RPC instance.
37 *
38 */
40 #include <xdc/std.h>
41 #include <xdc/cfg/global.h>
42 #include <xdc/runtime/System.h>
43 #include <xdc/runtime/Diags.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
49 #include <ti/ipc/MultiProc.h>
50 #include <ti/sysbios/BIOS.h>
51 #include <ti/sysbios/knl/Task.h>
53 #include <ti/grcm/RcmTypes.h>
54 #include <ti/grcm/RcmServer.h>
56 #include <ti/srvmgr/ServiceMgr.h>
57 #include <ti/srvmgr/omaprpc/OmapRpc.h>
58 #include <ti/srvmgr/rpmsg_omx.h>
59 #include <ti/srvmgr/omx_packet.h>
61 #include <ti/sysbios/hal/Cache.h>
63 /* Turn on/off printf's */
64 #define CHATTER 1
66 #define RPC_MGR_PORT 59
68 /* Legacy function to allow Linux side rpmsg sample tests to work: */
69 extern void start_rpc_task();
71 /*
72 * OMX packet expected to have its data payload start with a payload of
73 * this value. Need to export this properly in a meaningful header file on
74 * both HLOS and RTOS sides
75 */
76 typedef enum {
77 RPC_OMX_MAP_INFO_NONE = 0,
78 RPC_OMX_MAP_INFO_ONE_BUF = 1,
79 RPC_OMX_MAP_INFO_TWO_BUF = 2,
80 RPC_OMX_MAP_INFO_THREE_BUF = 3,
81 RPC_OMX_MAP_INFO_MAX = 0x7FFFFFFF
82 } map_info_type;
84 /*
85 * ======== fxnTriple used by omx_benchmark test app ========
86 */
87 typedef struct {
88 Int a;
89 } FxnTripleArgs;
91 typedef struct {
92 Int a;
93 Int b;
94 } FxnAddArgs;
96 typedef struct {
97 Int a;
98 Int b;
99 Int c;
100 } FxnAdd3Args;
102 typedef struct {
103 Int num;
104 Int *array;
105 } FxnAddXArgs;
107 #define H264_DECODER_NAME "H264_decoder"
109 #define OMX_VIDEO_THREAD_PRIORITY 5
111 typedef UInt32 OMX_HANDLETYPE;
113 static Int32 RPC_SKEL_Init(Void *, UInt32 size, UInt32 *data);
114 static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data);
115 static Int32 RPC_SKEL_SetParameter(UInt32 size, UInt32 *data);
116 static Int32 RPC_SKEL_GetParameter(UInt32 size, UInt32 *data);
117 static Int32 fxnTriple(UInt32 size, UInt32 *data);
118 static Int32 fxnAdd(UInt32 size, UInt32 *data);
119 static Int32 fxnAdd3(UInt32 size, UInt32 *data);
120 static Int32 fxnAddX(UInt32 size, UInt32 *data);
122 #if 0
123 /* RcmServer static function table */
124 static RcmServer_FxnDesc RPCServerFxnAry[] = {
125 {"RPC_SKEL_Init", NULL}, /* filled in dynamically */
126 {"RPC_SKEL_SetParameter", RPC_SKEL_SetParameter},
127 {"RPC_SKEL_GetParameter", RPC_SKEL_GetParameter},
128 {"fxnTriple", fxnTriple },
129 };
131 #define RPCServerFxnAryLen (sizeof RPCServerFxnAry / sizeof RPCServerFxnAry[0])
133 static const RcmServer_FxnDescAry RPCServer_fxnTab = {
134 RPCServerFxnAryLen,
135 RPCServerFxnAry
136 };
137 #endif
139 #define RPC_SVR_NUM_FXNS 5
140 OmapRpc_FuncDeclaration RPCServerFxns[RPC_SVR_NUM_FXNS] =
141 {
142 { RPC_SKEL_Init2,
143 { "RPC_SKEL_Init2", 3,
144 {
145 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
146 {OmapRpc_Direction_In, OmapRpc_Param_U32, 1},
147 {OmapRpc_Direction_In, OmapRpc_PtrType(OmapRpc_Param_U32), 1}
148 }
149 }
150 },
151 { fxnTriple,
152 { "fxnTriple", 2,
153 {
154 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
155 {OmapRpc_Direction_In, OmapRpc_Param_U32, 1}
156 },
157 },
158 },
159 { fxnAdd,
160 { "fxnAdd", 3,
161 {
162 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
163 {OmapRpc_Direction_In, OmapRpc_Param_S32, 1},
164 {OmapRpc_Direction_In, OmapRpc_Param_S32, 1}
165 }
166 }
167 },
168 { fxnAdd3,
169 { "fxnAdd3", 2,
170 {
171 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
172 {OmapRpc_Direction_In, OmapRpc_PtrType(OmapRpc_Param_U32), 1}
173 }
174 }
175 },
176 { fxnAddX,
177 { "fxnAddX", 2,
178 {
179 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
180 {OmapRpc_Direction_In, OmapRpc_PtrType(OmapRpc_Param_U32), 1}
181 }
182 }
183 }
184 };
186 static Int32 RPC_SKEL_SetParameter(UInt32 size, UInt32 *data)
187 {
188 #if CHATTER
189 System_printf("RPC_SKEL_SetParameter: Called\n");
190 #endif
192 return(0);
193 }
195 static Int32 RPC_SKEL_GetParameter(UInt32 size, UInt32 *data)
196 {
197 #if CHATTER
198 System_printf("RPC_SKEL_GetParameter: Called\n");
199 #endif
201 return(0);
202 }
204 Void RPC_SKEL_SrvDelNotification()
205 {
206 System_printf("RPC_SKEL_SrvDelNotification: Nothing to cleanup\n");
207 }
209 #define CALLBACK_DATA "OMX_Callback"
210 #define PAYLOAD_SIZE sizeof(CALLBACK_DATA)
211 #define CALLBACK_DATA_SIZE (HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE)
213 static Int32 RPC_SKEL_Init(Void *srvc, UInt32 size, UInt32 *data)
214 {
215 char cComponentName[128] = {0};
216 OMX_HANDLETYPE hComp;
217 Char cb_data[HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE] = {0};
219 /*
220 * Note: Currently, rpmsg_omx linux driver expects an omx_msg_hdr in front
221 * of the omx_packet data, so we allow space for this:
222 */
223 struct omx_msg_hdr * hdr = (struct omx_msg_hdr *)cb_data;
224 struct omx_packet * packet = (struct omx_packet *)hdr->data;
227 //Marshalled:[>offset(cParameterName)|>pAppData|>offset(RcmServerName)|>pid|
228 //>--cComponentName--|>--CallingCorercmServerName--|
229 //<hComp]
231 strcpy(cComponentName, (char *)data + sizeof(map_info_type));
233 #if CHATTER
234 System_printf("RPC_SKEL_GetHandle: Component Name received: %s\n",
235 cComponentName);
236 #endif
238 /* Simulate sending an async OMX callback message, passing an omx_packet
239 * structure.
240 */
241 packet->msg_id = 99; // Set to indicate callback instance, buffer id, etc.
242 packet->fxn_idx = 5; // Set to indicate callback fxn
243 packet->data_size = PAYLOAD_SIZE;
244 strcpy((char *)packet->data, CALLBACK_DATA);
246 #if CHATTER
247 System_printf("RPC_SKEL_GetHandle: Sending callback message id: %d, "
248 "fxn_id: %d, data: %s\n",
249 packet->msg_id, packet->fxn_idx, packet->data);
250 #endif
251 ServiceMgr_send(srvc, cb_data, CALLBACK_DATA_SIZE);
253 /* Call OMX_Get_Handle() and return handle for future calls. */
254 //eCompReturn = OMX_GetHandle(&hComp, (OMX_STRING)&cComponentName[0], pAppData,&rpcCallBackInfo);
255 hComp = 0x5C0FFEE5;
256 data[0] = hComp;
258 #if CHATTER
259 System_printf("RPC_SKEL_GetHandle: returning hComp: 0x%x\n", hComp);
260 #endif
262 return(0);
263 }
265 static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data)
266 {
267 System_printf("RPC_SKEL_Init2: size = 0x%x data = 0x%x\n", size,
268 (UInt32)data);
269 return 0;
270 }
272 /*
273 * ======== fxnTriple ========
274 */
275 Int32 fxnTriple(UInt32 size, UInt32 *data)
276 {
277 struct OmapRpc_Parameter *payload = (struct OmapRpc_Parameter *)data;
278 Int a;
280 a = (Int)payload[0].data;
282 #if CHATTER
283 System_printf("fxnTriple: a=%d\n", a);
284 #endif
286 return(a * 3);
287 }
289 /*
290 * ======== fxnAdd ========
291 */
292 Int32 fxnAdd(UInt32 size, UInt32 *data)
293 {
294 struct OmapRpc_Parameter *payload = (struct OmapRpc_Parameter *)data;
295 Int a, b;
297 a = (Int)payload[0].data;
298 b = (Int)payload[1].data;
300 #if CHATTER
301 System_printf("fxnAdd: a=%d, b=%d\n", a, b);
302 #endif
304 return(a + b);
305 }
307 /*
308 * ======== fxnAdd3 ========
309 */
310 Int32 fxnAdd3(UInt32 size, UInt32 *data)
311 {
312 struct OmapRpc_Parameter *payload = (struct OmapRpc_Parameter *)data;
313 FxnAdd3Args *args;
314 Int a, b, c;
316 args = (FxnAdd3Args *)payload[0].data;
318 Cache_inv (args, sizeof(FxnAdd3Args), Cache_Type_ALL, TRUE);
320 a = args->a;
321 b = args->b;
322 c = args->c;
324 #if CHATTER
325 System_printf("fxnAdd3: a=%d, b=%d, c=%d\n", a, b, c);
326 #endif
328 return(a + b + c);
329 }
331 /*
332 * ======== fxnAddX ========
333 */
334 Int32 fxnAddX(UInt32 size, UInt32 *data)
335 {
336 struct OmapRpc_Parameter *payload = (struct OmapRpc_Parameter *)data;
337 FxnAddXArgs *args;
338 Int num, i, sum = 0;
339 Int *array;
341 args = (FxnAddXArgs *)payload[0].data;
343 Cache_inv (args, sizeof(FxnAddXArgs), Cache_Type_ALL, TRUE);
345 num = args->num;
346 array = args->array;
348 Cache_inv (array, sizeof(Int) * num, Cache_Type_ALL, TRUE);
350 #if CHATTER
351 System_printf("fxnAddX: ");
352 #endif
353 for (i = 0; i < num; i++) {
354 #if CHATTER
355 System_printf(" a[%d]=%d,", i, array[i]);
356 #endif
357 sum += array[i];
358 }
360 #if CHATTER
361 System_printf(" sum=%d\n", sum);
362 #endif
364 return(sum);
365 }
367 Void start_rpc_task()
368 {
369 /* Init service manager */
370 System_printf("%s initializing OMAPRPC based service manager endpoint\n",
371 MultiProc_getName(MultiProc_self()));
373 OmapRpc_createChannel("rpc_example", MultiProc_getId("HOST"),
374 RPC_MGR_PORT, RPC_SVR_NUM_FXNS, RPCServerFxns,
375 (OmapRpc_SrvDelNotifyFxn)RPC_SKEL_SrvDelNotification);
376 }