]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - packages/ti/ipc/tests/messageq_multicore.c
Rename: git mv src packages to complete application of ipc-j patches to ipcdev.
[ipc/ipcdev.git] / packages / ti / ipc / tests / messageq_multicore.c
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  *  ======== message_multicore.c ========
34  *  Multiprocessor MessageQ example
35  *
36  *  This is an example program that uses MessageQ to pass a message
37  *  from one processor to another.
38  *
39  *  Each processor creates its own MessageQ first and then will try to open
40  *  a remote processor's MessageQ.
41  *
42  *  See message_multicore.k file for expected output.
43  */
45 #include <xdc/std.h>
46 #include <string.h>
48 /*  -----------------------------------XDC.RUNTIME module Headers    */
49 #include <xdc/runtime/System.h>
50 #include <xdc/runtime/IHeap.h>
52 /*  ----------------------------------- IPC module Headers           */
53 #include <ti/ipc/Ipc.h>
54 #include <ti/ipc/MessageQ.h>
55 #include <ti/ipc/HeapBufMP.h>
56 #include <ti/ipc/MultiProc.h>
58 /*  ----------------------------------- BIOS6 module Headers         */
59 #include <ti/sysbios/BIOS.h>
60 #include <ti/sysbios/knl/Task.h>
61 #include <ti/sysbios/knl/Clock.h>
62 #include <ti/sysbios/family/c66/Cache.h>
64 /*  ----------------------------------- To get globals from .cfg Header */
65 #include <xdc/cfg/global.h>
67 /* Define this to eliminate VIRTIO DEV and VRINGS from rsc_table: */
68 #define  TRACE_RESOURCE_ONLY 1
69 extern char * xdc_runtime_SysMin_Module_State_0_outbuf__A;
70 #if defined(TCI6614)
71 #include <ti/ipc/remoteproc/rsc_table_tci6614.h>
72 #elif defined(TCI6614_v33)
73 #include <ti/ipc/remoteproc/rsc_table_tci6614_v3.3.h>
74 #elif defined(TCI6638)
75 #include <ti/ipc/remoteproc/rsc_table_tci6638.h>
76 #endif
78 #define HEAP_NAME   "myHeapBuf"
79 #define HEAPID      0
80 #define NUMLOOPS    10
82 Char localQueueName[10];
83 Char nextQueueName[10];
84 UInt16 nextProcId;
86 /*
87  *  ======== tsk0_func ========
88  *  Allocates a message and ping-pongs the message around the processors.
89  *  A local message queue is created and a remote message queue is opened.
90  *  Messages are sent to the remote message queue and retrieved from the
91  *  local MessageQ.
92  */
93 Void tsk0_func(UArg arg0, UArg arg1)
94 {
95     MessageQ_Msg     msg;
96     MessageQ_Handle  messageQ;
97     MessageQ_QueueId remoteQueueId;
98     Int              status;
99     UInt16           msgId = 0;
100     HeapBufMP_Handle              heapHandle;
101     HeapBufMP_Params              heapBufParams;
103     if (MultiProc_self() == 0) {
104         /*
105          *  Create the heap that will be used to allocate messages.
106          */
107         HeapBufMP_Params_init(&heapBufParams);
108         heapBufParams.regionId       = 0;
109         heapBufParams.name           = HEAP_NAME;
110         heapBufParams.numBlocks      = 1;
111         heapBufParams.blockSize      = sizeof(MessageQ_MsgHeader);
112         heapHandle = HeapBufMP_create(&heapBufParams);
113         if (heapHandle == NULL) {
114             System_abort("HeapBufMP_create failed\n" );
115         }
116     }
117     else {
118         /* Open the heap created by the other processor. Loop until opened. */
119         do {
120             status = HeapBufMP_open(HEAP_NAME, &heapHandle);
121             /*
122              *  Sleep for 1 clock tick to avoid inundating remote processor
123              *  with interrupts if open failed
124              */
125             if (status < 0) {
126                 Task_sleep(1);
127             }
128         } while (status < 0);
129     }
131     /* Register this heap with MessageQ */
132     MessageQ_registerHeap((IHeap_Handle)heapHandle, HEAPID);
134     /* Create the local message queue */
135     messageQ = MessageQ_create(localQueueName, NULL);
136     if (messageQ == NULL) {
137         System_abort("MessageQ_create failed\n" );
138     }
140     /* Open the remote message queue. Spin until it is ready. */
141     do {
142         status = MessageQ_open(nextQueueName, &remoteQueueId);
143         /*
144          *  Sleep for 1 clock tick to avoid inundating remote processor
145          *  with interrupts if open failed
146          */
147         if (status < 0) {
148             Task_sleep(1);
149         }
150     } while (status < 0);
152     if (MultiProc_self() == 0) {
153         /* Allocate a message to be ping-ponged around the processors */
154         msg = MessageQ_alloc(HEAPID, sizeof(MessageQ_MsgHeader));
155         if (msg == NULL) {
156            System_abort("MessageQ_alloc failed\n" );
157         }
159         /*
160          *  Send the message to the next processor and wait for a message
161          *  from the previous processor.
162          */
163         System_printf("Start the main loop\n");
164         while (msgId < NUMLOOPS) {
165             /* Increment...the remote side will check this */
166             msgId++;
167             MessageQ_setMsgId(msg, msgId);
169             System_printf("Sending a message #%d to %s\n", msgId, nextQueueName);
171             /* send the message to the remote processor */
172             status = MessageQ_put(remoteQueueId, msg);
173             if (status < 0) {
174                System_abort("MessageQ_put had a failure/error\n");
175             }
177             /* Get a message */
178             status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
179             if (status < 0) {
180                System_abort("This should not happen since timeout is forever\n");
181             }
182         }
183     }
184     else {
185         /*
186          *  Wait for a message from the previous processor and
187          *  send it to the next processor
188          */
189         System_printf("Start the main loop\n");
190         while (TRUE) {
191             /* Get a message */
192             status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
193             if (status < 0) {
194                System_abort("This should not happen since timeout is forever\n");
195             }
197             System_printf("Sending a message #%d to %s\n", MessageQ_getMsgId(msg),
198                 nextQueueName);
200             /* Get the message id */
201             msgId = MessageQ_getMsgId(msg);
203             /* send the message to the remote processor */
204             status = MessageQ_put(remoteQueueId, msg);
205             if (status < 0) {
206                System_abort("MessageQ_put had a failure/error\n");
207             }
209             /* test done */
210             if (msgId >= NUMLOOPS) {
211                 break;
212             }
213         }
214     }
216     System_printf("The test is complete\n");
217     BIOS_exit(0);
220 #define CACHE_WB_TICK_PERIOD    5
222 /*
223  * ======== VirtQueue_cacheWb ========
224  *
225  * Used for flushing SysMin trace buffer.
226  */
227 Void traceBuf_cacheWb()
229     static UInt32 oldticks = 0;
230     UInt32 newticks;
232     newticks = Clock_getTicks();
233     if (newticks - oldticks < (UInt32)CACHE_WB_TICK_PERIOD) {
234         /* Don't keep flushing cache */
235         return;
236     }
238     oldticks = newticks;
240     Cache_wbAll();
244 /*
245  *  ======== main ========
246  *  Synchronizes all processors (in Ipc_start) and calls BIOS_start
247  */
248 Int main(Int argc, Char* argv[])
250     Int status;
252 #if defined(TCI6614_v33)
253     /* Reference resource table, until IpcMemory.xdt is enabled for TCI66xx */
254     System_printf("Resource Table: 0x%lx\n", resources);
255 #elif defined (TCI6614) || defined(TCI6638)
256     System_printf("%d Resource Table entries at 0x%x\n",
257                   ti_ipc_remoteproc_ResourceTable.num,
258                   &ti_ipc_remoteproc_ResourceTable);
259 #endif
261     nextProcId = (MultiProc_self() + 1) % MultiProc_getNumProcessors();
263     /* Generate queue names based on own proc ID and total number of procs */
264     System_sprintf(localQueueName, "%s", MultiProc_getName(MultiProc_self()));
265     System_sprintf(nextQueueName, "%s",  MultiProc_getName(nextProcId));
267     /*
268      *  Ipc_start() calls Ipc_attach() to synchronize all remote processors
269      *  because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg
270      */
271     status = Ipc_start();
272     if (status < 0) {
273         System_abort("Ipc_start failed\n");
274     }
276     BIOS_start();
278     return (0);
280 /*
281  *  @(#) ti.sdo.ipc.examples.multicore.evm667x; 1, 0, 0, 0,2; 10-19-2011 10:53:19; /db/vtree/library/trees/ipc/ipc.git/src/ null
282  */