1 /*
2 * Copyright (c) 2012-2017, 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 * ======== messageq_single.c ========
34 *
35 * Single threaded test of messageq over rpmsg.
36 *
37 * See:
38 * MessageQApp in Linux user space
39 *
40 */
41 #include <xdc/std.h>
42 #include <xdc/runtime/Assert.h>
43 #include <xdc/runtime/System.h>
45 #include <ti/sysbios/BIOS.h>
46 #include <ti/sysbios/knl/Task.h>
47 #include <ti/sysbios/knl/Clock.h>
49 #include <ti/ipc/MessageQ.h>
51 #define SLAVE_MESSAGEQNAME "SLAVE"
53 #define MessageQ_payload(m) ((void *)((char *)(m) + sizeof(MessageQ_MsgHeader)))
55 Int32 fxnFault(UInt32 faultId)
56 {
57 Int32 a;
58 Void (*fxn)(void) = (Void (*)())0x96000000;
59 volatile Int dummy = 0;
61 switch (faultId) {
62 case 0: /* no fault */
63 return 0;
64 case 1:
65 System_printf("Generating read MMU Fault...\n");
66 a = *(volatile int *)(0x96000000);
67 break;
68 case 2:
69 System_printf("Generating write MMU Fault...\n");
70 *(volatile int *)(0x96000000) = 0x1;
71 break;
72 case 3:
73 System_printf("Generating program MMU Fault...\n");
74 fxn();
75 break;
76 case 4:
77 System_printf("Generating exception (w/ divide-by-zero...)\n");
78 dummy = dummy / dummy;
79 break;
80 case 5:
81 System_printf("Forcing Watchdog interrupt (w/ spin)...\n");
82 dummy = 1;
83 while(dummy);
84 break;
85 default:
86 System_printf("Invalid fxnFault test\n");
87 break;
88 }
90 /* don't really need to return 'a', but shuts up compiler warning */
91 return(a);
92 }
94 /*
95 * ======== tsk1Fxn ========
96 * Receive and return messages
97 */
98 Void tsk1Fxn(UArg arg0, UArg arg1)
99 {
100 MessageQ_Msg msg;
101 MessageQ_Handle messageQ;
102 MessageQ_QueueId remoteQueueId;
103 Char localQueueName[64];
104 UInt16 procId;
105 Int status;
106 UInt32 i;
107 UInt32 msgId;
108 UInt32 start;
109 UInt32 end;
110 UInt32 numLoops;
111 UInt32 print;
112 UInt32 *params;
113 Int32 faultId;
115 /* Construct a MessageQ name adorned with core name: */
116 System_sprintf(localQueueName, "%s_%s", SLAVE_MESSAGEQNAME,
117 MultiProc_getName(MultiProc_self()));
119 messageQ = MessageQ_create(localQueueName, NULL);
120 if (messageQ == NULL) {
121 System_abort("MessageQ_create failed\n");
122 }
124 System_printf("tsk1Fxn: created MessageQ: %s; QueueID: 0x%x\n",
125 localQueueName, MessageQ_getQueueId(messageQ));
127 while (1) {
128 /* handshake with host to get starting parameters */
129 System_printf("Awaiting sync message from host...\n");
130 MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
132 params = MessageQ_payload(msg);
133 numLoops = params[0];
134 print = params[1];
136 remoteQueueId = MessageQ_getReplyQueue(msg);
137 procId = MessageQ_getProcId(remoteQueueId);
139 System_printf("Received msg from (procId:remoteQueueId): 0x%x:0x%x\n"
140 "\tpayload: %d bytes; loops: %d %s printing.\n",
141 procId, remoteQueueId,
142 (MessageQ_getMsgSize(msg) - sizeof(MessageQ_MsgHeader)),
143 numLoops, print ? "with" : "without");
145 MessageQ_put(remoteQueueId, msg);
147 start = Clock_getTicks();
149 for (i = 1; i <= numLoops; i++) {
150 status = MessageQ_get(messageQ, &msg, MessageQ_FOREVER);
151 Assert_isTrue(status == MessageQ_S_SUCCESS, NULL);
153 params = MessageQ_payload(msg);
154 msgId = params[0];
155 faultId = params[2];
157 if (print) {
158 System_printf("Got msg #%d (%d bytes) from procId %d\n",
159 msgId, MessageQ_getMsgSize(msg), procId);
160 }
162 Assert_isTrue(msgId == i, NULL);
164 if (faultId < 0) {
165 System_printf("Generating fault %d before MessageQ_put()...\n",
166 -faultId);
167 fxnFault(-faultId);
168 }
170 if (print) {
171 System_printf("Sending msg Id #%d to procId %d\n", i, procId);
172 }
174 status = MessageQ_put(remoteQueueId, msg);
175 Assert_isTrue(status == MessageQ_S_SUCCESS, NULL);
177 if (faultId > 0) {
178 System_printf("Generating fault %d after MessageQ_put()...\n",
179 faultId);
180 fxnFault(faultId);
181 }
182 }
184 end = Clock_getTicks();
186 if (!print) {
187 System_printf("%d iterations took %d ticks or %d usecs/msg\n",
188 numLoops, end - start,
189 ((end - start) * Clock_tickPeriod) / numLoops);
190 }
191 }
192 }
194 /*
195 * ======== main ========
196 */
197 Int main(Int argc, Char* argv[])
198 {
199 System_printf("%s:main: MultiProc id = %d\n", __FILE__, MultiProc_self());
201 Task_create(tsk1Fxn, NULL, NULL);
203 BIOS_start();
205 return (0);
206 }