Update demo apps to use new HIL proc APIs
[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         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;
48 extern const struct remote_resource_table resources;
50 /* External functions */
51 extern void init_system();
52 extern void cleanup_system();
53 extern struct hil_proc *platform_create_proc(int proc_index);
55 /* Application entry point */
56 int main()
57 {
58         int status = 0;
59         int shutdown_msg = SHUTDOWN_MSG;
60         int i;
61         int size;
62         int expect_rnum = 0;
63         struct hil_proc *hproc;
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         /* Create HIL proc */
83         hproc = platform_create_proc(0);
84         if (!hproc) {
85                 LPERROR("Failed to create hil proc.\n");
86                 return -1;
87         }
88         /* Initialize RPMSG framework */
89         status =
90             remoteproc_resource_init(&rsc_info, hproc,
91                                      rpmsg_channel_created,
92                                      rpmsg_channel_deleted, rpmsg_read_cb,
93                                      &proc, 1);
95         if (status) {
96                 LPERROR("Failed to initialize remoteproc resource.\n");
97                 return -1;
98         }
100         LPRINTF("Remote proc resource initialized.\n");
101         while (!app_rp_chnl) {
102                 hil_poll(proc->proc, 0);
103         }
105         LPRINTF("RPMSG channel has created.\n");
106         for (i = 0, size = PAYLOAD_MIN_SIZE; i < (int)NUM_PAYLOADS; i++, size++) {
107                 i_payload->num = i;
108                 i_payload->size = size;
110                 /* Mark the data buffer. */
111                 memset(&(i_payload->data[0]), 0xA5, size);
113                 LPRINTF("sending payload number %lu of size %d\n",
114                         i_payload->num, (2 * sizeof(unsigned long)) + size);
116                 status = rpmsg_send(app_rp_chnl, i_payload,
117                         (2 * sizeof(unsigned long)) + size);
119                 if (status) {
120                         LPRINTF("Error sending data...\n");
121                         break;
122                 }
123                 LPRINTF("echo test: sent : %d\n",
124                 (2 * sizeof(unsigned long)) + size);
126                 expect_rnum++;
127                 do {
128                         hil_poll(proc->proc, 0);
129                 } while ((rnum < expect_rnum) && !err_cnt && app_rp_chnl);
131         }
133         LPRINTF("**********************************\n");
134         LPRINTF(" Test Results: Error count = %d \n", err_cnt);
135         LPRINTF("**********************************\n");
136         /* Send shutdown message to remote */
137         rpmsg_send(app_rp_chnl, &shutdown_msg, sizeof(int));
138         sleep(1);
139         LPRINTF("Quitting application .. Echo test end\n");
141         remoteproc_resource_deinit(proc);
142         cleanup_system();
143         metal_free_memory(i_payload);
144         return 0;
147 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
149         app_rp_chnl = rp_chnl;
150         rp_ept = rpmsg_create_ept(rp_chnl, rpmsg_read_cb, RPMSG_NULL,
151                                   RPMSG_ADDR_ANY);
154 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
156         (void)rp_chnl;
157         rpmsg_destroy_ept(rp_ept);
158         LPRINTF("%s\n", __func__);
159         app_rp_chnl = NULL;
160         rp_ept = NULL;
163 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
164                           void *priv, unsigned long src)
166         (void)rp_chnl;
167         (void)src;
168         (void)priv;
169         int i;
170         struct _payload *r_payload = (struct _payload *)data;
172         LPRINTF(" received payload number %lu of size %d \r\n",
173                 r_payload->num, len);
175         if (r_payload->size == 0) {
176                 LPERROR(" Invalid size of package is received.\n");
177                 err_cnt++;
178                 return;
179         }
180         /* Validate data buffer integrity. */
181         for (i = 0; i < (int)r_payload->size; i++) {
182                 if (r_payload->data[i] != 0xA5) {
183                         LPRINTF("Data corruption at index %d \n", i);
184                         err_cnt++;
185                         break;
186                 }
187         }
188         rnum = r_payload->num + 1;