Update applications RPMsg between processes
[processor-sdk/open-amp.git] / apps / echo_test / echo_test.c
1 /* This is a sample demonstration application that showcases usage of rpmsg 
2 This application is meant to run on the remote CPU running baremetal code. 
3 This application echoes back data that was sent to it by the master core. */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include "openamp/open_amp.h"
10 #include "metal/alloc.h"
11 #include "rsc_table.h"
13 #define SHUTDOWN_MSG    0xEF56A55A
14 #define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
15 #define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
17 struct _payload {
18         unsigned long num;
19         unsigned long size;
20         unsigned char data[];
21 };
23 static int err_cnt;
25 #define RPMSG_GET_KFIFO_SIZE 1
26 #define RPMSG_GET_AVAIL_DATA_SIZE 2
27 #define RPMSG_GET_FREE_SPACE 3
29 #define RPMSG_HEADER_LEN sizeof(struct rpmsg_hdr)
30 #define MAX_RPMSG_BUFF_SIZE (RPMSG_BUFFER_SIZE - RPMSG_HEADER_LEN)
31 #define PAYLOAD_MIN_SIZE        1
32 #define PAYLOAD_MAX_SIZE        (MAX_RPMSG_BUFF_SIZE - 24)
33 #define NUM_PAYLOADS            (PAYLOAD_MAX_SIZE/PAYLOAD_MIN_SIZE)
35 /* Internal functions */
36 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
37 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
38 static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
39                           unsigned long);
40 /* Globals */
41 static struct rpmsg_channel *app_rp_chnl;
42 static struct rpmsg_endpoint *rp_ept;
43 static struct remote_proc *proc = NULL;
44 static struct rsc_table_info rsc_info;
45 static struct _payload *i_payload;
46 static int rnum = 0;
47 static int err_cnt = 0;
49 /* External functions */
50 extern void init_system();
51 extern void cleanup_system();
52 extern struct hil_proc *platform_create_proc(int proc_index);
53 extern void *get_resource_table (int rsc_id, int *len);
55 /* Application entry point */
56 int app (struct hil_proc *hproc)
57 {
58         int status = 0;
59         int shutdown_msg = SHUTDOWN_MSG;
60         int i;
61         int size;
62         int expect_rnum = 0;
64         LPRINTF(" 1 - Send data to remote core, retrieve the echo");
65         LPRINTF(" and validate its integrity ..\n");
67         i_payload =
68             (struct _payload *)metal_allocate_memory(2 * sizeof(unsigned long) +
69                                       PAYLOAD_MAX_SIZE);
71         if (!i_payload) {
72                 LPERROR("memory allocation failed.\n");
73                 return -1;
74         }
76         /* Initialize RPMSG framework */
77         status =
78             remoteproc_resource_init(&rsc_info, hproc,
79                                      rpmsg_channel_created,
80                                      rpmsg_channel_deleted, rpmsg_read_cb,
81                                      &proc, 1);
83         if (status) {
84                 LPERROR("Failed to initialize remoteproc resource.\n");
85                 return -1;
86         }
88         LPRINTF("Remote proc resource initialized.\n");
89         while (!app_rp_chnl) {
90                 hil_poll(proc->proc, 0);
91         }
93         LPRINTF("RPMSG channel has created.\n");
94         for (i = 0, size = PAYLOAD_MIN_SIZE; i < (int)NUM_PAYLOADS; i++, size++) {
95                 i_payload->num = i;
96                 i_payload->size = size;
98                 /* Mark the data buffer. */
99                 memset(&(i_payload->data[0]), 0xA5, size);
101                 LPRINTF("sending payload number %lu of size %d\n",
102                         i_payload->num, (2 * sizeof(unsigned long)) + size);
104                 status = rpmsg_send(app_rp_chnl, i_payload,
105                         (2 * sizeof(unsigned long)) + size);
107                 if (status) {
108                         LPRINTF("Error sending data...\n");
109                         break;
110                 }
111                 LPRINTF("echo test: sent : %d\n",
112                 (2 * sizeof(unsigned long)) + size);
114                 expect_rnum++;
115                 do {
116                         hil_poll(proc->proc, 0);
117                 } while ((rnum < expect_rnum) && !err_cnt && app_rp_chnl);
119         }
121         LPRINTF("**********************************\n");
122         LPRINTF(" Test Results: Error count = %d \n", err_cnt);
123         LPRINTF("**********************************\n");
124         /* Send shutdown message to remote */
125         rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
126         sleep(1);
127         LPRINTF("Quitting application .. Echo test end\n");
129         remoteproc_resource_deinit(proc);
130         cleanup_system();
131         metal_free_memory(i_payload);
132         return 0;
135 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
137         app_rp_chnl = rp_chnl;
138         rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
139                                   RPMSG_ADDR_ANY);
142 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
144         (void)rp_chnl;
145         rpmsg_destroy_ept(rp_ept);
146         LPRINTF("%s\n", __func__);
147         app_rp_chnl = NULL;
148         rp_ept = NULL;
151 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
152                           void *priv, unsigned long src)
154         (void)rp_chnl;
155         (void)src;
156         (void)priv;
157         int i;
158         struct _payload *r_payload = (struct _payload *)data;
160         LPRINTF(" received payload number %lu of size %d \r\n",
161                 r_payload->num, len);
163         if (r_payload->size == 0) {
164                 LPERROR(" Invalid size of package is received.\n");
165                 err_cnt++;
166                 return;
167         }
168         /* Validate data buffer integrity. */
169         for (i = 0; i < (int)r_payload->size; i++) {
170                 if (r_payload->data[i] != 0xA5) {
171                         LPRINTF("Data corruption at index %d\n", i);
172                         err_cnt++;
173                         break;
174                 }
175         }
176         rnum = r_payload->num + 1;
179 int main(int argc, char *argv[])
181         unsigned long proc_id = 0;
182         unsigned long rsc_id = 0;
183         struct hil_proc *hproc;
185         /* Initialize HW system components */
186         init_system();
188         if (argc >= 2) {
189                 proc_id = strtoul(argv[1], NULL, 0);
190         }
192         if (argc >= 3) {
193                 rsc_id = strtoul(argv[2], NULL, 0);
194         }
196         /* Create HIL proc */
197         hproc = platform_create_proc(proc_id);
198         if (!hproc) {
199                 LPERROR("Failed to create hil proc.\n");
200                 return -1;
201         }
202         rsc_info.rsc_tab = get_resource_table(
203                 (int)rsc_id, &rsc_info.size);
204         if (!rsc_info.rsc_tab) {
205                 LPRINTF("Failed to get resource table data.\n");
206                 return -1;
207         }
208         return app(hproc);