1 /*
2 * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
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 * @file Msgq100.c
34 *
35 * @brief Bug validation test: ####
36 *
37 * ============================================================================
38 */
40 /* standard headers */
41 #include <stdio.h>
42 #include <stdlib.h>
44 /* ipc headers */
45 #include <ti/ipc/Std.h>
46 #include <ti/ipc/Ipc.h>
47 #include <ti/ipc/MessageQ.h>
48 #include <ti/ipc/transports/TransportRpmsg.h>
50 #define HEAPID 0 /* not actually used */
51 #define SLAVE_MSGQNAME "SLAVE"
52 #define MPU_MESSAGEQNAME "HOST"
53 #define Main_MAXQUE 10
54 #define NUM_LOOPS_DFLT 4
56 #define Main_USAGE "\
57 Usage:\n\
58 Msgq100 [options] procId ...\n\
59 \n\
60 Arguments:\n\
61 procId: remote processor id\n\
62 \n\
63 Options:\n\
64 h : print this help message\n\
65 l : list the available remote processors\n\
66 \n\
67 Examples:\n\
68 Msgq100 1\n\
69 Msgq100 1 4\n\
70 Msgq100 -h\n\
71 \n"
73 typedef struct SyncMsg {
74 MessageQ_MsgHeader header;
75 UInt32 numLoops;
76 UInt32 print;
77 } SyncMsg;
79 /* private functions */
80 static int Main_main(Void);
82 static int Main_procCount = 0;
83 static UInt16 Main_procAry[Main_MAXQUE];
84 static MessageQ_QueueId Main_msgQueAry[Main_MAXQUE];
87 /*
88 * ======== main ========
89 */
90 int main(int argc, char *argv[])
91 {
92 Int32 status = 0;
93 int arg, opt;
94 int p;
95 UInt16 procId;
96 UInt16 numProcs;
97 String name;
99 /* configure the transport factory */
100 Ipc_transportConfig(&TransportRpmsg_Factory);
102 /* parse the command line options (e.g. -h) */
103 for (arg = 1; (arg < argc) && (argv[arg][0] == '-'); arg++) {
105 /* convert option into numeric value */
106 opt = (int)argv[arg][1];
108 switch (opt) {
109 case 'h': /* -h */
110 printf("%s", Main_USAGE);
111 exit(0);
112 break;
114 case 'l': /* -l */
115 printf("Processor List\n");
116 status = Ipc_start();
117 if (status >= 0) {
118 numProcs = MultiProc_getNumProcessors();
119 for (p = 0; p < numProcs; p++) {
120 name = MultiProc_getName(p);
121 printf(" procId=%d, procName=%s\n", p, name);
122 }
123 Ipc_stop();
124 }
125 else {
126 printf(
127 "Error: %s, line %d: Ipc_start failed\n",
128 __FILE__, __LINE__);
129 goto leave;
130 }
131 exit(0);
132 break;
134 default:
135 printf(
136 "Error: %s, line %d: invalid option, %c\n",
137 __FILE__, __LINE__, (Char)opt);
138 printf("%s", Main_USAGE);
139 status = -1;
140 goto leave;
141 }
142 }
144 /* parse the command line arguments */
145 while (arg < argc) {
147 if (Main_procCount == Main_MAXQUE) {
148 printf("Error: too many procIds (max=%d)\n", Main_MAXQUE);
149 status = -1;
150 goto leave;
151 }
153 /* remaining arguments is a list of procId's */
154 Main_procAry[Main_procCount++] = atoi(argv[arg]);
156 arg++;
157 }
159 /* ipc initialization */
160 status = Ipc_start();
162 if (status < 0) {
163 printf("Error: Ipc_start failed: status = %d\n", status);
164 status = -1;
165 goto leave;
166 }
168 /* validate procId list, must do this after Ipc_start() */
169 for (p = 0; p < Main_procCount; p++) {
170 procId = Main_procAry[p];
172 if (procId >= MultiProc_getNumProcessors()) {
173 printf("Error: procId must be less than %d\n",
174 MultiProc_getNumProcessors());
175 status = -1;
176 goto stop;
177 }
178 }
180 /* execute main body of test */
181 status = Main_main();
183 if (status == 0) {
184 printf("Test PASSED\n");
185 }
187 stop:
188 /* ipc finalization */
189 Ipc_stop();
191 leave:
192 return(status);
193 }
195 /*
196 * ======== Main_main ========
197 */
198 int Main_main(Void)
199 {
200 int status = 0;
201 MessageQ_Msg msg = NULL;
202 MessageQ_Params msgParams;
203 int p, j;
204 UInt16 procId;
205 MessageQ_Handle hostQ;
206 char queueName[64];
207 String procName;
209 printf("Entered Main_main\n");
211 /* create local message queue for receiving messages */
212 MessageQ_Params_init(&msgParams);
214 hostQ = MessageQ_create(MPU_MESSAGEQNAME, &msgParams);
216 if (hostQ == NULL) {
217 printf("Error: MessageQ_create() failed\n");
218 goto leave;
219 }
220 printf("HOST MessageQId: 0x%x\n", MessageQ_getQueueId(hostQ));
222 /* open remote message queues */
223 for (p = 0; p < Main_procCount; p++) {
225 /* compute remote queue name */
226 procId = Main_procAry[p];
227 procName = MultiProc_getName(procId);
228 sprintf(queueName, "%s_%s", SLAVE_MSGQNAME, procName);
230 /* open the remote message queue, loop until queue is available */
231 do {
232 status = MessageQ_open(queueName, &Main_msgQueAry[p]);
234 if (status == MessageQ_E_NOTFOUND) {
235 sleep(1);
236 }
237 } while (status == MessageQ_E_NOTFOUND);
239 if (status < 0) {
240 printf("Error: MessageQ_open(\"%s\") failed, status=%d\n",
241 queueName, status);
242 status = -1;
243 goto cleanup;
244 }
245 printf("Remote queueId[%d]=0x%x\n", p, Main_msgQueAry[p]);
246 }
248 /* allocate handshake message */
249 msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg));
251 if (msg == NULL) {
252 printf("Error: MessageQ_alloc() failed\n");
253 status = -1;
254 goto cleanup;
255 }
257 /* handshake with each remote processor to set the number of loops */
258 for (p = 0; p < Main_procCount; p++) {
259 MessageQ_setReplyQueue(hostQ, msg);
260 ((SyncMsg *)msg)->numLoops = NUM_LOOPS_DFLT;
261 ((SyncMsg *)msg)->print = TRUE;
262 MessageQ_put(Main_msgQueAry[p], msg);
263 MessageQ_get(hostQ, &msg, MessageQ_FOREVER);
265 procId = Main_procAry[p];
266 procName = MultiProc_getName(procId);
267 printf("Exchanging %d messages with remote processor %s...\n",
268 NUM_LOOPS_DFLT, procName);
269 }
271 /* free handshake message */
272 MessageQ_free(msg);
274 /* allocate and send all messages */
275 for (p = 0; p < Main_procCount; p++) {
276 for (j = 1; j <= NUM_LOOPS_DFLT; j++) {
278 /* allocate message */
279 msg = MessageQ_alloc(HEAPID, sizeof(SyncMsg));
281 if (msg == NULL) {
282 printf("Error: MessageQ_alloc() failed\n");
283 status = -1;
284 goto cleanup;
285 }
287 /* fill in message */
288 MessageQ_setReplyQueue(hostQ, msg);
289 ((SyncMsg *)msg)->numLoops = j;
291 /* send the messages */
292 status = MessageQ_put(Main_msgQueAry[p], msg);
294 if (status < 0) {
295 printf("Error: MessageQ_put() failed, procId=%d, status=%d\n",
296 Main_procAry[p], status);
297 status = -1;
298 goto cleanup;
299 }
300 }
301 }
303 /* delay here to allow for return message deliver */
304 printf("Waiting...");
305 sleep(3);
306 printf("done.\n");
308 /* receive and free all messages */
309 for (p = 0; p < Main_procCount; p++) {
310 for (j = 1; j <= NUM_LOOPS_DFLT; j++) {
312 /* receive message, timeout 2 sec */
313 status = MessageQ_get(hostQ, &msg, 2000);
315 if (status == MessageQ_E_TIMEOUT) {
316 printf("Error: detected dropped message\n");
317 status = -1;
318 goto cleanup;
319 }
320 else if (status < 0) {
321 printf("Error: MessageQ_get() failed, status=%d\n", status);
322 status = -1;
323 goto cleanup;
324 }
325 }
327 procId = Main_procAry[p];
328 printf("ProcId %d, received %d messages\n", procId, NUM_LOOPS_DFLT);
329 }
331 /* getting here implies success */
332 printf("All messages received\n");
334 cleanup:
335 /* close remote message queues */
336 for (p = 0; p < Main_procCount; p++) {
337 MessageQ_close(&Main_msgQueAry[p]);
338 }
340 /* delete local message queue */
341 MessageQ_delete(&hostQ);
343 leave:
344 printf("Leaving Main_main(), status=%d\n", status);
346 return(status);
347 }