Add echo_test client demo applicaiton
[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"
12 #include "platform_info.h"
14 #define SHUTDOWN_MSG    0xEF56A55A
15 #define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
16 #define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
18 struct _payload {
19         unsigned long num;
20         unsigned long size;
21         char data[];
22 };
24 static int err_cnt;
26 #define RPMSG_GET_KFIFO_SIZE 1
27 #define RPMSG_GET_AVAIL_DATA_SIZE 2
28 #define RPMSG_GET_FREE_SPACE 3
30 #define RPMSG_HEADER_LEN sizeof(struct rpmsg_hdr)
31 #define MAX_RPMSG_BUFF_SIZE (RPMSG_BUFFER_SIZE - RPMSG_HEADER_LEN)
32 #define PAYLOAD_MIN_SIZE        1
33 #define PAYLOAD_MAX_SIZE        (MAX_RPMSG_BUFF_SIZE - 24)
34 #define NUM_PAYLOADS            (PAYLOAD_MAX_SIZE/PAYLOAD_MIN_SIZE)
36 /* Internal functions */
37 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
38 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
39 static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
40                           unsigned long);
41 /* Globals */
42 static struct rpmsg_channel *app_rp_chnl;
43 static struct rpmsg_endpoint *rp_ept;
44 static struct remote_proc *proc = NULL;
45 static struct rsc_table_info rsc_info;
46 static struct _payload *i_payload;
47 static int rnum = 0;
48 static int err_cnt = 0;
49 extern const struct remote_resource_table resources;
50 extern struct rproc_info_plat_local proc_table;
52 /* External functions */
53 extern void init_system();
54 extern void cleanup_system();
56 /* Application entry point */
57 int main()
58 {
59         int status = 0;
60         int shutdown_msg = SHUTDOWN_MSG;
61         int i;
62         int size;
63         int expect_rnum = 0;
65         LPRINTF(" 1 - Send data to remote core, retrieve the echo");
66         LPRINTF(" and validate its integrity ..\n");
67         /* Initialize HW system components */
68         init_system();
70         rsc_info.rsc_tab = (struct resource_table *)&resources;
71         rsc_info.size = sizeof(resources);
73         i_payload =
74             (struct _payload *)metal_allocate_memory(2 * sizeof(unsigned long) +
75                                       PAYLOAD_MAX_SIZE);
77         if (!i_payload) {
78                 LPERROR("memory allocation failed.\n");
79                 return -1;
80         }
82         /* Initialize RPMSG framework */
83         status =
84             remoteproc_resource_init(&rsc_info, &proc_table,
85                                      rpmsg_channel_created,
86                                      rpmsg_channel_deleted, rpmsg_read_cb,
87                                      &proc, 1);
89         if (status) {
90                 LPERROR("Failed  to initialize remoteproc resource.\n");
91                 return -1;
92         }
94         LPRINTF("Remote proc resource initialized.\n");
95         while (!app_rp_chnl) {
96                 hil_poll(proc->proc, 0);
97         }
99         LPRINTF("RPMSG channel has created.\n");
100         for (i = 0, size = PAYLOAD_MIN_SIZE; i < (int)NUM_PAYLOADS; i++, size++) {
101                 i_payload->num = i;
102                 i_payload->size = size;
104                 /* Mark the data buffer. */
105                 memset(&(i_payload->data[0]), 0xA5, size);
107                 LPRINTF("sending payload number %lu of size %d\n",
108                         i_payload->num, (2 * sizeof(unsigned long)) + size);
110                 status = rpmsg_send(app_rp_chnl, i_payload,
111                         (2 * sizeof(unsigned long)) + size);
113                 if (status) {
114                         LPRINTF("Error sending data...\n");
115                         break;
116                 }
117                 LPRINTF("echo test: sent : %d\n",
118                 (2 * sizeof(unsigned long)) + size);
120                 expect_rnum++;
121                 do {
122                         hil_poll(proc->proc, 0);
123                 } while ((rnum < expect_rnum) && !err_cnt && app_rp_chnl);
125         }
127         LPRINTF("**********************************\n");
128         LPRINTF(" Test Results: Error count = %d \n", err_cnt);
129         LPRINTF("**********************************\n");
130         /* Send shutdown message to remote */
131         rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
132         sleep(1);
133         LPRINTF("Quitting application .. Echo test end\n");
135         remoteproc_resource_deinit(proc);
136         cleanup_system();
137         metal_free_memory(i_payload);
138         return 0;
141 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
143         app_rp_chnl = rp_chnl;
144         rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
145                                   RPMSG_ADDR_ANY);
148 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
150         (void)rp_chnl;
151         rpmsg_destroy_ept(rp_ept);
152         LPRINTF("%s\n", __func__);
153         app_rp_chnl = NULL;
154         rp_ept = NULL;
157 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
158                           void *priv, unsigned long src)
160         (void)rp_chnl;
161         (void)src;
162         (void)priv;
163         int i;
164         struct _payload *r_payload = (struct _payload *)data;
166         LPRINTF(" received payload number %lu of size %d \r\n",
167                 r_payload->num, len);
169         if (r_payload->size == 0) {
170                 LPERROR(" Invalid size of package is received.\n");
171                 err_cnt++;
172                 return;
173         }
174         /* Validate data buffer integrity. */
175         for (i = 0; i < (int)r_payload->size; i++) {
176                 if (r_payload->data[i] != 0xA5) {
177                         LPRINTF("Data corruption at index %d \n", i);
178                         err_cnt++;
179                         break;
180                 }
181         }
182         rnum = r_payload->num + 1;