1 /* This is a sample demonstration application that showcases usage of proxy from the remote core.
2 This application is meant to run on the remote CPU running baremetal.
3 This applicationr can print to to master console and perform file I/O using proxy mechanism. */
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include "openamp/open_amp.h"
11 #include "rsc_table.h"
12 #include "openamp/rpmsg_retarget.h"
14 /* Internal functions */
15 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
16 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
17 static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *,
18 unsigned long);
19 static void shutdown_cb(struct rpmsg_channel *rp_chnl);
21 /* Globals */
22 static struct rpmsg_channel *app_rp_chnl;
23 static volatile int chnl_is_alive = 0;
24 static struct remote_proc *proc = NULL;
25 static struct rsc_table_info rsc_info;
26 extern const struct remote_resource_table resources;
28 /* External functions */
29 extern void init_system();
30 extern void cleanup_system();
31 extern struct hil_proc *platform_create_proc(int proc_index);
33 #define REDEF_O_CREAT 100
34 #define REDEF_O_EXCL 200
35 #define REDEF_O_RDONLY 0
36 #define REDEF_O_WRONLY 1
37 #define REDEF_O_RDWR 2
38 #define REDEF_O_APPEND 2000
39 #define REDEF_O_ACCMODE 3
41 #define RPC_CHANNEL_READY_TO_CLOSE "rpc_channel_ready_to_close"
43 /* Application entry point */
44 int main()
45 {
46 int fd, bytes_written, bytes_read;
47 char fname[] = "remote.file";
48 char wbuff[50];
49 char rbuff[1024];
50 char ubuff[50];
51 float fdata;
52 int idata;
53 int ret;
54 int status;
55 struct hil_proc *hproc;
57 /* Initialize HW system components */
58 init_system();
60 /* Resource table needs to be provided to remoteproc_resource_init() */
61 rsc_info.rsc_tab = (struct resource_table *)&resources;
62 rsc_info.size = sizeof(resources);
64 /* Create HIL proc */
65 hproc = platform_create_proc(0);
66 if (!hproc)
67 return -1;
69 /* Initialize RPMSG framework */
70 status = remoteproc_resource_init(&rsc_info, hproc,
71 rpmsg_channel_created,
72 rpmsg_channel_deleted, rpmsg_read_cb,
73 &proc, 0);
74 if (RPROC_SUCCESS != status) {
75 return -1;
76 }
78 while (!chnl_is_alive) {
79 hil_poll(proc->proc, 0);
80 }
82 /* redirect I/Os */
83 rpmsg_retarget_init(app_rp_chnl, shutdown_cb);
85 printf("\r\nRemote>Baremetal Remote Procedure Call (RPC) Demonstration\r\n");
86 printf("\r\nRemote>***************************************************\r\n");
88 printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");
90 /* Remote performing file IO on Master */
91 printf("\r\nRemote>FileIO demo ..\r\n");
93 printf("\r\nRemote>Creating a file on master and writing to it..\r\n");
94 fd = open(fname, REDEF_O_CREAT | REDEF_O_WRONLY | REDEF_O_APPEND,
95 S_IRUSR | S_IWUSR);
96 printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
98 sprintf(wbuff, "This is a test string being written to file..");
99 bytes_written = write(fd, wbuff, strlen(wbuff));
100 printf("\r\nRemote>Wrote to fd = %d, size = %d, content = %s\r\n", fd,
101 bytes_written, wbuff);
102 close(fd);
103 printf("\r\nRemote>Closed fd = %d\r\n", fd);
105 /* Remote performing file IO on Master */
106 printf("\r\nRemote>Reading a file on master and displaying its contents..\r\n");
107 fd = open(fname, REDEF_O_RDONLY, S_IRUSR | S_IWUSR);
108 printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
109 bytes_read = read(fd, rbuff, 1024);
110 *(char *)(&rbuff[0] + bytes_read + 1) = 0;
111 printf("\r\nRemote>Read from fd = %d, size = %d, printing contents below .. %s\r\n",
112 fd, bytes_read, rbuff);
113 close(fd);
114 printf("\r\nRemote>Closed fd = %d\r\n", fd);
116 while (1) {
117 /* Remote performing STDIO on Master */
118 printf("\r\nRemote>Remote firmware using scanf and printf ..\r\n");
119 printf("\r\nRemote>Scanning user input from master..\r\n");
120 printf("\r\nRemote>Enter name\r\n");
121 ret = scanf("%s", ubuff);
122 if (ret) {
123 printf("\r\nRemote>Enter age\r\n");
124 ret = scanf("%d", &idata);
125 if (ret) {
126 printf("\r\nRemote>Enter value for pi\r\n");
127 ret = scanf("%f", &fdata);
128 if (ret) {
129 printf("\r\nRemote>User name = '%s'\r\n", ubuff);
130 printf("\r\nRemote>User age = '%d'\r\n", idata);
131 printf("\r\nRemote>User entered value of pi = '%f'\r\n", fdata);
132 }
133 }
134 }
135 if (!ret) {
136 scanf("%s", ubuff);
137 printf("Remote> Invalid value. Starting again....");
138 } else {
139 printf("\r\nRemote>Repeat demo ? (enter yes or no) \r\n");
140 scanf("%s", ubuff);
141 if ((strcmp(ubuff, "no")) && (strcmp(ubuff, "yes"))) {
142 printf("\r\nRemote>Invalid option. Starting again....\r\n");
143 } else if ((!strcmp(ubuff, "no"))) {
144 printf("\r\nRemote>RPC retargetting quitting ...\r\n");
145 sprintf(wbuff, RPC_CHANNEL_READY_TO_CLOSE);
146 break;
147 }
148 }
149 }
151 printf("\r\nRemote> Firmware's rpmsg-openamp-demo-channel going down! \r\n");
153 rpmsg_retarget_send(wbuff, sizeof (RPC_CHANNEL_READY_TO_CLOSE) + 1);
155 while (chnl_is_alive)
156 hil_poll(proc->proc, 0);
158 rpmsg_retarget_deinit(app_rp_chnl);
159 remoteproc_resource_deinit(proc);
160 cleanup_system();
161 return 0;
162 }
164 static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl)
165 {
166 app_rp_chnl = rp_chnl;
167 chnl_is_alive = 1;
168 }
170 static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl)
171 {
172 (void)rp_chnl;
173 app_rp_chnl = NULL;
174 }
176 static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
177 void *priv, unsigned long src)
178 {
179 (void)rp_chnl;
180 (void)data;
181 (void)len;
182 (void)priv;
183 (void)src;
184 }
186 static void shutdown_cb(struct rpmsg_channel *rp_chnl)
187 {
188 (void)rp_chnl;
189 chnl_is_alive = 0;
190 }