]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - linux/src/tests/Msgq100.c
Linux: tests - Clear Fault Request After Processing
[ipc/ipcdev.git] / linux / src / tests / Msgq100.c
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);
195 /*
196  *  ======== Main_main ========
197  */
198 int Main_main(Void)
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);