1 /*
2 * Copyright (c) 2013-2014, 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 */
33 /*
34 * ======== GateMPApp.c ========
35 *
36 */
38 /* host header files */
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
43 /* package header files */
44 #include <ti/ipc/Std.h>
45 #include <ti/ipc/MessageQ.h>
46 #include <ti/ipc/GateMP.h>
48 /* local header files */
49 #include "GateMPApp.h"
51 /* CMEM */
52 #include <ti/cmem.h>
54 #include <ti/ipc/tests/GateMPAppCommon.h>
56 /* module structure */
57 typedef struct {
58 MessageQ_Handle hostQue; /* created locally */
59 MessageQ_QueueId slaveQue; /* opened remotely */
60 UInt16 heapId; /* MessageQ heapId */
61 UInt32 msgSize; /* Size of messages */
62 volatile UInt32 * intPtr; /* Integer pointer */
63 UInt32 physAddr; /* Physical address of shared memory */
64 GateMP_Handle hostGateMPHandle; /* handle to host-created gate */
65 GateMP_Handle slaveGateMPHandle; /* handle to slave-created gate */
66 } GateMPApp_Module;
68 /* private data */
69 static GateMPApp_Module Module;
71 /* Global CMEM attrs */
72 CMEM_AllocParams cmemAttrs;
74 /*
75 * ======== GateMPApp_create ========
76 */
78 Int GateMPApp_create()
79 {
80 Int status =0;
81 MessageQ_Params msgqParams;
82 GateMP_Params gateParams;
84 printf("--> GateMPApp_create:\n");
86 /* setting default values */
87 Module.hostQue = NULL;
88 Module.slaveQue = MessageQ_INVALIDMESSAGEQ;
89 Module.heapId = GateMPApp_MsgHeapId;
90 Module.intPtr = NULL;
91 Module.physAddr = 0;
92 Module.hostGateMPHandle = NULL;
93 Module.slaveGateMPHandle = NULL;
94 Module.msgSize = sizeof(GateMPApp_Msg);
96 /* create local message queue (inbound messages) */
97 MessageQ_Params_init(&msgqParams);
99 Module.hostQue = MessageQ_create(GateMPApp_HostMsgQueName, &msgqParams);
101 if (Module.hostQue == NULL) {
102 printf("GateMPApp_create: Failed creating MessageQ\n");
103 status = GATEMPAPP_E_FAILURE;
104 goto leave;
105 }
107 /* open the remote message queue */
108 do {
109 status = MessageQ_open(GateMPApp_SlaveMsgQueName, &Module.slaveQue);
110 sleep(1);
111 } while (status == MessageQ_E_NOTFOUND);
113 if (status < 0) {
114 printf("GateMPApp_create: Failed opening MessageQ\n");
115 status = GATEMPAPP_E_FAILURE;
116 goto leave;
117 }
119 /* allocate space from shared memory for an integer */
120 cmemAttrs.type = CMEM_HEAP;
121 cmemAttrs.flags = CMEM_NONCACHED;
122 cmemAttrs.alignment = 0;
123 Module.intPtr = (UInt32 *)CMEM_alloc(sizeof(UInt32), &cmemAttrs);
124 if (Module.intPtr < 0) {
125 printf("GateMPApp_create: Could not allocate CMEM shared memory\n");
126 status = GATEMPAPP_E_FAILURE;
127 goto leave;
128 }
130 Module.physAddr = (UInt32)CMEM_getPhys((Void *)Module.intPtr);
132 if (Module.physAddr == 0) {
133 printf("GateMPApp_create: Failed to get physical buffer address\n");
134 status = GATEMPAPP_E_FAILURE;
135 goto leave;
136 }
138 /* create GateMP */
139 GateMP_Params_init(&gateParams);
141 gateParams.name = GATEMP_HOST_NAME;
142 gateParams.localProtect = GateMP_LocalProtect_PROCESS;
143 gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
145 Module.hostGateMPHandle = GateMP_create (&gateParams);
147 if (Module.hostGateMPHandle == NULL) {
148 status = GATEMPAPP_E_FAILURE;
149 printf("GateMPApp_create: Failed to create GateMP\n");
150 goto leave;
151 }
152 printf("GateMPApp_create: Host is ready\n");
154 leave:
155 printf("<-- GateMPApp_create:\n");
156 return(status);
157 }
160 /*
161 * ======== GateMPApp_delete ========
162 */
163 Int GateMPApp_delete(Void)
164 {
165 Int status;
166 GateMPApp_Msg * msg;
168 printf("--> GateMPApp_delete:\n");
170 /* allocate message */
171 msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
173 if (msg == NULL) {
174 status = GATEMPAPP_E_FAILURE;
175 goto leave;
176 }
178 /* set the return address in the message header */
179 MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
181 /* sending shutdown command */
182 msg->cmd = GATEMPAPP_CMD_SHUTDOWN;
183 MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
185 /* wait for acknowledgement message */
186 status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
187 MessageQ_FOREVER);
189 if (status < 0) {
190 status = GATEMPAPP_E_FAILURE;
191 goto leave;
192 }
194 if (msg->cmd != GATEMPAPP_CMD_SHUTDOWN_ACK) {
195 status = GATEMPAPP_E_UNEXPECTEDMSG;
196 goto leave;
197 }
199 /* free the message */
200 MessageQ_free((MessageQ_Msg)msg);
202 /* delete GateMP */
203 GateMP_delete(&Module.hostGateMPHandle);
205 /* free shared memory buffer */
206 status = CMEM_free((Ptr)Module.intPtr, &cmemAttrs);
207 if(status < 0) {
208 status = GATEMPAPP_E_FAILURE;
209 goto leave;
210 }
212 /* close remote resources */
213 status = MessageQ_close(&Module.slaveQue);
215 if (status < 0) {
216 status = GATEMPAPP_E_FAILURE;
217 goto leave;
218 }
220 /* delete the host message queue */
221 status = MessageQ_delete(&Module.hostQue);
223 if (status < 0) {
224 status = GATEMPAPP_E_FAILURE;
225 goto leave;
226 }
228 leave:
229 printf("<-- GateMPApp_delete:\n");
230 return(status);
231 }
234 /*
235 * ======== GateMPApp_exec ========
236 */
237 Int GateMPApp_exec(Void)
238 {
239 Int status;
240 Int i;
241 GateMPApp_Msg * msg;
242 IArg gateKey = 0;
243 UInt32 num;
244 UInt32 prevNum;
246 printf("--> GateMPApp_exec:\n");
248 /* set shared variable initial value */
249 *Module.intPtr = 500;
251 /* allocate message */
252 msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
253 if (msg == NULL) {
254 status = GATEMPAPP_E_FAILURE;
255 goto leave;
256 }
258 /* set the return address in the message header */
259 MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
261 /* fill in message payload */
262 msg->cmd = GATEMPAPP_CMD_SPTR_ADDR;
263 msg->payload = Module.physAddr;
265 /* send message */
266 MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
268 /* wait for return message */
269 status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
270 MessageQ_FOREVER);
271 if (status < 0) {
272 goto leave;
273 }
275 if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR_ACK)
276 {
277 status = GATEMPAPP_E_UNEXPECTEDMSG;
278 goto leave;
279 }
281 /* free the message */
282 MessageQ_free((MessageQ_Msg)msg);
284 /* open slave-created GateMP */
285 do {
286 status = GateMP_open(GATEMP_SLAVE_NAME, &Module.slaveGateMPHandle);
287 } while (status == GateMP_E_NOTFOUND);
289 if (status < 0) {
290 printf("GateMPApp_exec: Failed to open slave-created GateMP");
291 status = GATEMPAPP_E_FAILURE;
292 goto leave;
293 }
295 printf("GateMPApp_exec: Using host-created gate\n");
296 for (i = 0; i < LOOP_ITR; i++) {
297 /* read the shared variable as long as no one is currently modifying
298 * it
299 */
301 /* enter GateMP */
302 gateKey = GateMP_enter(Module.hostGateMPHandle);
304 /* read shared variable value */
305 prevNum = *Module.intPtr;
307 /* randomly modify the shared variable */
308 if (rand() % 2) {
309 *Module.intPtr -= 1;
310 }
311 else {
312 *Module.intPtr += 1;
313 }
315 /* read shared variable value again*/
316 num = *Module.intPtr;
318 if ((prevNum != num + 1) && (prevNum != num - 1)) {
319 printf("GateMPApp_exec: unexpected variable value." \
320 "Test failed.\n");
321 printf("GateMPApp_exec: Previous value: %d, " \
322 "current value=%d\n", prevNum, num);
324 status = GATEMPAPP_E_FAILURE;
325 goto leave;
326 }
328 /* exit GateMP */
329 GateMP_leave(Module.hostGateMPHandle, gateKey);
330 }
332 /* allocate message */
333 msg = (GateMPApp_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
334 if (msg == NULL) {
335 status = GATEMPAPP_E_FAILURE;
336 goto leave;
337 }
339 /* set the return address in the message header */
340 MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
342 /* fill in message payload */
343 msg->cmd = GATEMPAPP_CMD_SYNC;
345 /* send sync message */
346 MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
348 /* wait for return sync message before we switch gates */
349 status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
350 MessageQ_FOREVER);
351 if (status < 0) {
352 goto leave;
353 }
355 if (msg->cmd != GATEMPAPP_CMD_SYNC)
356 {
357 status = GATEMPAPP_E_UNEXPECTEDMSG;
358 goto leave;
359 }
361 /* free the message */
362 MessageQ_free((MessageQ_Msg)msg);
364 printf("GateMPApp_exec: Using slave-created gate\n");
365 for (i = 0; i < LOOP_ITR; i++) {
366 /* read the shared variable as long as no one is currently modifying
367 * it
368 */
370 /* enter GateMP */
371 gateKey = GateMP_enter(Module.slaveGateMPHandle);
373 /* read shared variable value */
374 prevNum = *Module.intPtr;
376 /* randomly modify the shared variable */
377 if (rand() % 2) {
378 *Module.intPtr -= 1;
379 }
380 else {
381 *Module.intPtr += 1;
382 }
384 /* read shared variable value again */
385 num = *Module.intPtr;
387 if ((prevNum != num + 1) && (prevNum != num - 1)) {
388 printf("GateMPApp_exec: unexpected variable value." \
389 "Test failed.\n");
390 printf("GateMPApp_exec: Previous value: %d, " \
391 "current value=%d\n", prevNum, num);
393 status = GATEMPAPP_E_FAILURE;
394 goto leave;
395 }
397 /* exit GateMP */
398 GateMP_leave(Module.slaveGateMPHandle, gateKey);
399 }
401 leave:
402 if (Module.slaveGateMPHandle) {
403 GateMP_close(&Module.slaveGateMPHandle);
404 }
406 printf("<-- GateMPApp_exec: %d\n", status);
407 return(status);
408 }