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 /* Turn on/off printf's */
62 #define CHATTER 1
64 #define RPC_MGR_PORT 59
66 /* Legacy function to allow Linux side rpmsg sample tests to work: */
67 extern void start_rpc_task();
69 /*
70 * OMX packet expected to have its data payload start with a payload of
71 * this value. Need to export this properly in a meaningful header file on
72 * both HLOS and RTOS sides
73 */
74 typedef enum {
75 RPC_OMX_MAP_INFO_NONE = 0,
76 RPC_OMX_MAP_INFO_ONE_BUF = 1,
77 RPC_OMX_MAP_INFO_TWO_BUF = 2,
78 RPC_OMX_MAP_INFO_THREE_BUF = 3,
79 RPC_OMX_MAP_INFO_MAX = 0x7FFFFFFF
80 } map_info_type;
82 /*
83 * ======== fxnTriple used by omx_benchmark test app ========
84 */
85 typedef struct {
86 Int size_a;
87 Int a;
88 } FxnTripleArgs;
90 typedef struct {
91 Int size_a;
92 Int a;
93 Int size_b;
94 Int b;
95 } FxnAddArgs;
97 #define H264_DECODER_NAME "H264_decoder"
99 #define OMX_VIDEO_THREAD_PRIORITY 5
101 typedef UInt32 OMX_HANDLETYPE;
103 static Int32 RPC_SKEL_Init(Void *, UInt32 size, UInt32 *data);
104 static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data);
105 static Int32 RPC_SKEL_SetParameter(UInt32 size, UInt32 *data);
106 static Int32 RPC_SKEL_GetParameter(UInt32 size, UInt32 *data);
107 static Int32 fxnTriple(UInt32 size, UInt32 *data);
108 static Int32 fxnAdd(UInt32 size, UInt32 *data);
110 #if 0
111 /* RcmServer static function table */
112 static RcmServer_FxnDesc RPCServerFxnAry[] = {
113 {"RPC_SKEL_Init", NULL}, /* filled in dynamically */
114 {"RPC_SKEL_SetParameter", RPC_SKEL_SetParameter},
115 {"RPC_SKEL_GetParameter", RPC_SKEL_GetParameter},
116 {"fxnTriple", fxnTriple },
117 };
119 #define RPCServerFxnAryLen (sizeof RPCServerFxnAry / sizeof RPCServerFxnAry[0])
121 static const RcmServer_FxnDescAry RPCServer_fxnTab = {
122 RPCServerFxnAryLen,
123 RPCServerFxnAry
124 };
125 #endif
127 #define RPC_SVR_NUM_FXNS 3
128 OmapRpc_FuncDeclaration RPCServerFxns[RPC_SVR_NUM_FXNS] =
129 {
130 { RPC_SKEL_Init2,
131 { "RPC_SKEL_Init2", 3,
132 {
133 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
134 {OmapRpc_Direction_In, OmapRpc_Param_U32, 1},
135 {OmapRpc_Direction_In, OmapRpc_PtrType(OmapRpc_Param_U32), 1}
136 }
137 }
138 },
139 { fxnTriple,
140 { "fxnTriple", 2,
141 {
142 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
143 {OmapRpc_Direction_In, OmapRpc_Param_U32, 1}
144 },
145 },
146 },
147 { fxnAdd,
148 { "fxnAdd", 3,
149 {
150 {OmapRpc_Direction_Out, OmapRpc_Param_S32, 1}, // return
151 {OmapRpc_Direction_In, OmapRpc_Param_S32, 1},
152 {OmapRpc_Direction_In, OmapRpc_Param_S32, 1}
153 }
154 }
155 }
156 };
158 static Int32 RPC_SKEL_SetParameter(UInt32 size, UInt32 *data)
159 {
160 #if CHATTER
161 System_printf("RPC_SKEL_SetParameter: Called\n");
162 #endif
164 return(0);
165 }
167 static Int32 RPC_SKEL_GetParameter(UInt32 size, UInt32 *data)
168 {
169 #if CHATTER
170 System_printf("RPC_SKEL_GetParameter: Called\n");
171 #endif
173 return(0);
174 }
176 Void RPC_SKEL_SrvDelNotification()
177 {
178 System_printf("RPC_SKEL_SrvDelNotification: Nothing to cleanup\n");
179 }
181 #define CALLBACK_DATA "OMX_Callback"
182 #define PAYLOAD_SIZE sizeof(CALLBACK_DATA)
183 #define CALLBACK_DATA_SIZE (HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE)
185 static Int32 RPC_SKEL_Init(Void *srvc, UInt32 size, UInt32 *data)
186 {
187 char cComponentName[128] = {0};
188 OMX_HANDLETYPE hComp;
189 Char cb_data[HDRSIZE + OMXPACKETSIZE + PAYLOAD_SIZE] = {0};
191 /*
192 * Note: Currently, rpmsg_omx linux driver expects an omx_msg_hdr in front
193 * of the omx_packet data, so we allow space for this:
194 */
195 struct omx_msg_hdr * hdr = (struct omx_msg_hdr *)cb_data;
196 struct omx_packet * packet = (struct omx_packet *)hdr->data;
199 //Marshalled:[>offset(cParameterName)|>pAppData|>offset(RcmServerName)|>pid|
200 //>--cComponentName--|>--CallingCorercmServerName--|
201 //<hComp]
203 strcpy(cComponentName, (char *)data + sizeof(map_info_type));
205 #if CHATTER
206 System_printf("RPC_SKEL_GetHandle: Component Name received: %s\n",
207 cComponentName);
208 #endif
210 /* Simulate sending an async OMX callback message, passing an omx_packet
211 * structure.
212 */
213 packet->msg_id = 99; // Set to indicate callback instance, buffer id, etc.
214 packet->fxn_idx = 5; // Set to indicate callback fxn
215 packet->data_size = PAYLOAD_SIZE;
216 strcpy((char *)packet->data, CALLBACK_DATA);
218 #if CHATTER
219 System_printf("RPC_SKEL_GetHandle: Sending callback message id: %d, "
220 "fxn_id: %d, data: %s\n",
221 packet->msg_id, packet->fxn_idx, packet->data);
222 #endif
223 ServiceMgr_send(srvc, cb_data, CALLBACK_DATA_SIZE);
225 /* Call OMX_Get_Handle() and return handle for future calls. */
226 //eCompReturn = OMX_GetHandle(&hComp, (OMX_STRING)&cComponentName[0], pAppData,&rpcCallBackInfo);
227 hComp = 0x5C0FFEE5;
228 data[0] = hComp;
230 #if CHATTER
231 System_printf("RPC_SKEL_GetHandle: returning hComp: 0x%x\n", hComp);
232 #endif
234 return(0);
235 }
237 static Int32 RPC_SKEL_Init2(UInt32 size, UInt32 *data)
238 {
239 System_printf("RPC_SKEL_Init2: size = 0x%x data = 0x%x\n", size,
240 (UInt32)data);
241 return 0;
242 }
244 /*
245 * ======== fxnTriple ========
246 */
247 Int32 fxnTriple(UInt32 size, UInt32 *data)
248 {
249 FxnTripleArgs *args;
250 Int a;
252 // args = (FxnTripleArgs *)((UInt32)data + sizeof(map_info_type));
253 args = (FxnTripleArgs *)data;
254 a = args->a;
256 #if CHATTER
257 System_printf("fxnTriple: a=%d\n", a);
258 #endif
260 return(a * 3);
261 }
263 /*
264 * ======== fxnAdd ========
265 */
266 Int32 fxnAdd(UInt32 size, UInt32 *data)
267 {
268 FxnAddArgs *args;
269 Int a, b;
271 args = (FxnAddArgs *)data;
272 a = args->a;
273 b = args->b;
275 #if CHATTER
276 System_printf("fxnAdd: a=%d, b=%d\n", a, b);
277 #endif
279 return(a + b);
280 }
282 Void start_rpc_task()
283 {
284 /* Init service manager */
285 System_printf("%s initializing OMAPRPC based service manager endpoint\n",
286 MultiProc_getName(MultiProc_self()));
288 OmapRpc_createChannel("rpc_example", MultiProc_getId("HOST"),
289 RPC_MGR_PORT, RPC_SVR_NUM_FXNS, RPCServerFxns,
290 (OmapRpc_SrvDelNotifyFxn)RPC_SKEL_SrvDelNotification);
291 }