From e95fffb24190625f83f80e2c37c5b2e632055dfa Mon Sep 17 00:00:00 2001 From: Luoject <13113951796@163.com> Date: Tue, 7 Jun 2022 19:49:48 +0800 Subject: [PATCH 1/3] openamp_demo support pty at Linux Endpoint --- mcs/openamp_demo/Makefile | 11 ++- mcs/openamp_demo/rpmsg-internal.h | 18 +++- mcs/openamp_demo/rpmsg_main.c | 85 +++++++++++----- mcs/openamp_demo/rpmsg_ping.c | 143 +++++++++++++-------------- mcs/openamp_demo/rpmsg_pty.c | 155 ++++++++++++++++++++++++++++++ 5 files changed, 307 insertions(+), 105 deletions(-) create mode 100644 mcs/openamp_demo/rpmsg_pty.c diff --git a/mcs/openamp_demo/Makefile b/mcs/openamp_demo/Makefile index c293881e..2e7a8f5c 100644 --- a/mcs/openamp_demo/Makefile +++ b/mcs/openamp_demo/Makefile @@ -1,11 +1,14 @@ -rpmsg_main: rpmsg_main.o rpmsg_ping.o - $(CC) rpmsg_main.o rpmsg_ping.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so -o rpmsg_main +rpmsg_main: rpmsg_main.o rpmsg_ping.o rpmsg_pty.o + $(CC) -g rpmsg_main.o rpmsg_ping.o rpmsg_pty.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so $(SDKTARGETSYSROOT)/lib64/libpthread.so.0 -o rpmsg_main rpmsg_main.o: rpmsg_main.c rpmsg-internal.h - $(CC) -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_main.c -o rpmsg_main.o + $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_main.c -o rpmsg_main.o rpmsg_ping.o: rpmsg_ping.c rpmsg-internal.h - $(CC) -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_ping.c -o rpmsg_ping.o + $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_ping.c -o rpmsg_ping.o + +rpmsg_pty.o: rpmsg_pty.c + $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_pty.c -o rpmsg_pty.o clean: rm -rf *.o rpmsg_main diff --git a/mcs/openamp_demo/rpmsg-internal.h b/mcs/openamp_demo/rpmsg-internal.h index ebfde5fb..42c2a4a9 100644 --- a/mcs/openamp_demo/rpmsg-internal.h +++ b/mcs/openamp_demo/rpmsg-internal.h @@ -24,6 +24,22 @@ #define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" extern char *cpu_id; +extern struct metal_io_region *io; + +struct thread_args { + int fd; + int *pipefd; +}; + +struct remoteproc *platform_create_proc(unsigned int id); +int load_bin(void); +void rpmsg_endpoint_init(void); +int rpmsg_endpoint_app(int fds, int ns_setup); + +void open_pty(int *pfdm, int *pfds); +//void master(int fdm, int pipefd[2]); +void *master(void *arg_list); +//int slave(int fds, int pipefd[2]); +void *slave(void *arg_list); -void rpmsg_app_master(void); #endif diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c index 037ec8e9..d67ae703 100644 --- a/mcs/openamp_demo/rpmsg_main.c +++ b/mcs/openamp_demo/rpmsg_main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "rpmsg-internal.h" @@ -24,7 +25,20 @@ struct rproc_priv { unsigned int id; }; -static int load_bin(void) +static void cleanup(void) +{ + printf("\nOpenAMP demo ended.\n"); + remoteproc_remove(&rproc_inst); + if (io) + free(io); +} + +static void handler(int sig) +{ + exit(0); +} + +int load_bin(void) { int memfd = open("/dev/mem", O_RDWR); int bin_fd = open(target_binfile, O_RDONLY); @@ -108,7 +122,7 @@ struct remoteproc_ops rproc_ops = { .start = rproc_start, }; -static struct remoteproc *platform_create_proc(unsigned int id) +struct remoteproc *platform_create_proc(unsigned int id) { struct remoteproc *rproc; @@ -122,10 +136,13 @@ static struct remoteproc *platform_create_proc(unsigned int id) int main(int argc, char **argv) { - struct remoteproc *rproc = NULL; - unsigned int id = 1; - int ret; int opt; + int fdm = -1, fds = -1; + pid_t pid; + int pipefd[2]; + pthread_t tidm, tids; + struct thread_args args; + void *retval; while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { switch (opt) { @@ -146,28 +163,48 @@ int main(int argc, char **argv) } } - rproc = platform_create_proc(id); - if (!rproc) { - printf("create rproc failed\n"); - return -1; - } + /* Open the master side and the slave side of the PTY */ + open_pty(&fdm, &fds); - ret = load_bin(); - if (ret) { - printf("failed to load client os\n"); - return ret; + /* Create unamed pipe */ + if (pipe(pipefd) < 0) { + perror("pipe"); + return -1; } - ret = remoteproc_start(rproc); - if (ret) { - printf("start processor failed\n"); - return ret; + /* Create the child process */ + if ((pid = fork()) < 0) { + perror("fork"); + return -1; + } else if (pid > 0) { + close(fds); /* Close the slave side of the PTY */ + + args.fd = fdm; + args.pipefd = pipefd; + if (pthread_create(&tidm, NULL, master, (void*)&args) < 0) { //T3 + perror("parent pthread_create"); + exit(1); + } + //printf("This is thread1: %ld, pid:%d\n", pthread_self(), getpid()); //T1 + pthread_join(tidm, NULL); + } else { + /* ctrl+c signal, exit program and do cleanup */ + atexit(cleanup); + signal(SIGINT, handler); + + close(fdm); /* Close the master side of the PTY */ + + args.fd = fds; + args.pipefd = pipefd; + if (pthread_create(&tids, NULL, slave, (void*)&args) < 0) { //T4 + perror("child pthread_create"); + exit(1); + } + //printf("This is thread2: %ld, pid:%d\n", pthread_self(), getpid()); //T2 + pthread_join(tids, &retval); + if (*(int*)retval) + exit(1); } - sleep(5); - printf("start processing OpenAMP demo...\n"); - rpmsg_app_master(); - - remoteproc_remove(rproc); - return ret; + return 0; } diff --git a/mcs/openamp_demo/rpmsg_ping.c b/mcs/openamp_demo/rpmsg_ping.c index 6cea999a..722b0853 100644 --- a/mcs/openamp_demo/rpmsg_ping.c +++ b/mcs/openamp_demo/rpmsg_ping.c @@ -18,11 +18,13 @@ static struct virtio_vring_info rvrings[2] = { }; static int g_memfd; -static volatile unsigned int received_data; +volatile unsigned int received_data; static struct virtio_device vdev; static struct rpmsg_virtio_device rvdev; -static struct metal_io_region *io; -static struct virtqueue *vq[2]; +struct metal_io_region *io; +struct virtqueue *vq[2]; +static void *tx_addr, *rx_addr, *shm_start_addr; +static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; static unsigned char virtio_get_status(struct virtio_device *vdev) { @@ -94,61 +96,11 @@ void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) rpmsg_service_unbind); } -static unsigned int receive_message(void) -{ - int cpu_handler_fd; - struct pollfd fds; - int ret; - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("open %s failed.\n", DEV_CLIENT_OS_AGENT); - return cpu_handler_fd; - } - - fds.fd = cpu_handler_fd; - fds.events = POLLIN; - - printf("Master core waiting for messages.... \n"); - while (1) { - ret = poll(&fds, 1, -1); - if (ret < 0) { - printf("poll error.\n"); - close(cpu_handler_fd); - return ret; - } - - if (ret == 0) { - printf("poll time out.\n"); - close(cpu_handler_fd); - return ret; - } - - if (fds.revents & POLLIN) { - printf("Master core receiving messages....\n"); - virtqueue_notification(vq[0]); - break; - } - } - close(cpu_handler_fd); - return received_data; -} - -static int send_message(unsigned int message) -{ - return rpmsg_send(ep, &message, sizeof(message)); -} - static struct rpmsg_virtio_shm_pool shpool; -void rpmsg_app_master(void) +void rpmsg_endpoint_init(void) { int status = 0; - unsigned int message = 0U; - void *tx_addr, *rx_addr, *shm_start_addr; - metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; - - printf("\r\nOpenAMP[master] demo started\r\n"); g_memfd = open("/dev/mem", O_RDWR); tx_addr = mmap((void *)VRING_TX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_TX_ADDRESS); @@ -201,29 +153,68 @@ void rpmsg_app_master(void) free(io); return; } +} + +int rpmsg_endpoint_app(int fds, int ns_setup) +{ + int cpu_handler_fd; + struct pollfd poll_fd[2] = {0}; + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("open %s failed.\n", DEV_CLIENT_OS_AGENT); + return -1; + } + + poll_fd[0].fd = fds; + poll_fd[0].events = POLLIN; + poll_fd[1].fd = cpu_handler_fd; + poll_fd[1].events = POLLIN; + + /* Wait for data from slave side of PTY, and data from endpoint of openamp, blocked */ + if (poll(poll_fd, 2, -1) == -1) { + printf("Error %d on poll()\n", errno); + goto err; + } + + close(cpu_handler_fd); + + /* If data on slave side of PTY */ + if (poll_fd[0].revents & POLLIN) { + char recv_buf[200] = {0}; + unsigned int number; + + poll_fd[0].revents = 0; + if (read(fds, recv_buf, sizeof(recv_buf)) > 0) { + number = atoi(recv_buf); + //printf("Master core sending messages: %d\n", number); + rpmsg_send(ep, &number, sizeof(number)); + } + } - /* Since we are using name service, we need to wait for a response - * from NS setup and than we need to process it - */ - receive_message(); - - while (message < 99) { - status = send_message(message); - if (status < 0) { - printf("send_message(%u) failed with status %d\n", - message, status); - goto _cleanup; - } - - sleep(1); - message = receive_message(); - printf("Master core received a message: %u\n", message); - - message++; - sleep(1); + /* If data on endpoint of openamp */ + if (poll_fd[1].revents & POLLIN) { + char send_buf[200] = {0}; + int wc; + + poll_fd[1].revents = 0; + virtqueue_notification(vq[0]); + //printf("Master core receiving messages: %d\n", received_data); + + /* Check whether poll event is ns setup */ + if (ns_setup == 1) + return 0; + + received_data++; + wc = snprintf(send_buf, sizeof(send_buf), "Output number: %d\n", received_data); + if (write(fds, send_buf, wc) == -1) { + printf("Error %d on rpmsg_endpoint_app write()\n", errno); + goto err; + } } -_cleanup: - free(io); - printf("OpenAMP demo ended.\n"); + return 0; +err: + close(cpu_handler_fd); + return -1; } diff --git a/mcs/openamp_demo/rpmsg_pty.c b/mcs/openamp_demo/rpmsg_pty.c new file mode 100644 index 00000000..465bb700 --- /dev/null +++ b/mcs/openamp_demo/rpmsg_pty.c @@ -0,0 +1,155 @@ +#define _XOPEN_SOURCE 600 +#define _DEFAULT_SOURCE +#include +#include +#include +#include +#include +#include + +#include + +#include "rpmsg-internal.h" + +void open_pty(int *pfdm, int *pfds) +{ + int rc, fdm, fds; + + /* Open the master side of the PTY */ + fdm = posix_openpt(O_RDWR | O_NOCTTY); + if (fdm < 0) + printf("Error %d on posix_openpt()\n", errno); + + rc = grantpt(fdm); + if (rc != 0) + printf("Error %d on grantpt()\n", errno); + + rc = unlockpt(fdm); + if (rc != 0) + printf("Error %d on unlockpt()\n", errno); + + /* Open the slave side of the PTY */ + fds = open(ptsname(fdm), O_RDWR | O_NOCTTY); + + *pfdm = fdm; + *pfds = fds; +} + +static void ptmx_read_write(const char *name, int in, int out) +{ + char input[200]; + int rc, ret; + + rc = read(in, input, sizeof(input)); + if (rc == -1) + printf("Error %d on ptmx_read %s\n", errno, name); + + ret = write(out, input, rc); + if (ret == -1) + printf("Error %d on ptmx_write %s\n", errno, name); +} + +//void master(int fdm, int pipefd[2]) +void *master(void *arg_list) +{ + fd_set fd_in; + char buf[50] = {0}; + int nullfd; + struct thread_args *args = (struct thread_args*)arg_list; + + /* Wait for child */ + close(args->pipefd[1]); + while (read(args->pipefd[0], buf, sizeof(buf)) > 0) { + if (strcmp(buf, "init done\n") == 0) + break; + } + + //printf("This is thread3: %ld, pid:%d\n", pthread_self(), getpid()); //T3 + //printf("thread3 fd:%d, pipefd[0]:%d, pipefd[1]:%d\n", args->fd, args->pipefd[0], args->pipefd[1]); + + printf("----------PTY Terminal----------\n"); + printf("Input number: "); + fflush(stdout); + + for (;;) { + /* Wait for data from standard input and master side of PTY */ + FD_ZERO(&fd_in); + FD_SET(0, &fd_in); + FD_SET(args->fd, &fd_in); + + if (select(args->fd + 1, &fd_in, NULL, NULL, NULL) == -1) + printf("Error %d on select()\n", errno); + + /* If data on standard input */ + if (FD_ISSET(0, &fd_in)) { + ptmx_read_write("standard input", 0, args->fd); + + /* flush data to /dev/null on ptmx, avoid printing repeatedly */ + nullfd = open("/dev/null", O_RDWR); + ptmx_read_write("standard input", args->fd, nullfd); + } + + /* If data on master side of PTY */ + if (FD_ISSET(args->fd, &fd_in)) { + ptmx_read_write("master pty", args->fd, 1); + printf("Input number: "); + fflush(stdout); + } + } +} + +//int slave(int fds, int pipefd[2]) +void *slave(void *arg_list) +{ + struct remoteproc *rproc = NULL; + unsigned int id = 1; + int ret; + struct thread_args *args = (struct thread_args*)arg_list; + + //printf("This is thread4: %ld, pid:%d\n", pthread_self(), getpid()); //T4 + //printf("thread4 fd:%d, pipefd[0]:%d, pipefd[1]:%d\n", args->fd, args->pipefd[0], args->pipefd[1]); + + rproc = platform_create_proc(id); + if (!rproc) { + printf("create rproc failed\n"); + return (void*)1; + } + + ret = load_bin(); + if (ret) { + printf("failed to load client os\n"); + return (void*)1; + } + + ret = remoteproc_start(rproc); + if (ret) { + printf("start processor failed\n"); + return (void*)1; + } + + sleep(5); /* wait for clientos booting */ + rpmsg_endpoint_init(); + + /* Since we are using name service, we need to wait for a response + * from NS setup and then we need to process it + */ + rpmsg_endpoint_app(args->fd, 1); + + /* now wake up parent using unamed pipe, init console */ + close(args->pipefd[0]); + ret = write(args->pipefd[1], "init done\n", strlen("init done\n")); + if (ret == -1) { + printf("failed to wake up parent\n"); + return (void*)1; + } + + for (;;) { + ret = rpmsg_endpoint_app(args->fd, 0); + if (ret) { + printf("rpmsg_endpoint_app failed\n"); + return (void*)1; + } + } + + return (void*)0; +} -- Gitee From 4f0428f4d39b417b03e5d07e28fd6e4d09aaca11 Mon Sep 17 00:00:00 2001 From: Luoject <13113951796@163.com> Date: Tue, 7 Jun 2022 20:13:27 +0800 Subject: [PATCH 2/3] add resource table for openamp_demo, and init from parsing table --- mcs/openamp_demo/Makefile | 10 +- mcs/openamp_demo/rpmsg-internal.h | 24 +-- mcs/openamp_demo/rpmsg_main.c | 172 ++++--------------- mcs/openamp_demo/rpmsg_ping.c | 172 ++++++++++--------- mcs/openamp_demo/rproc_rsc.c | 274 ++++++++++++++++++++++++++++++ 5 files changed, 415 insertions(+), 237 deletions(-) create mode 100644 mcs/openamp_demo/rproc_rsc.c diff --git a/mcs/openamp_demo/Makefile b/mcs/openamp_demo/Makefile index 2e7a8f5c..67c52b23 100644 --- a/mcs/openamp_demo/Makefile +++ b/mcs/openamp_demo/Makefile @@ -1,5 +1,7 @@ -rpmsg_main: rpmsg_main.o rpmsg_ping.o rpmsg_pty.o - $(CC) -g rpmsg_main.o rpmsg_ping.o rpmsg_pty.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so $(SDKTARGETSYSROOT)/lib64/libpthread.so.0 -o rpmsg_main +rpmsg_main: rpmsg_main.o rpmsg_ping.o rproc_rsc.o + $(CC) -g rpmsg_main.o rpmsg_ping.o rproc_rsc.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so -o rpmsg_main + #$(LD) --verbose > rproc_rsc.ld + #-T rproc_rsc.ld rpmsg_main.o: rpmsg_main.c rpmsg-internal.h $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_main.c -o rpmsg_main.o @@ -7,8 +9,8 @@ rpmsg_main.o: rpmsg_main.c rpmsg-internal.h rpmsg_ping.o: rpmsg_ping.c rpmsg-internal.h $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_ping.c -o rpmsg_ping.o -rpmsg_pty.o: rpmsg_pty.c - $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_pty.c -o rpmsg_pty.o +rproc_rsc.o: rproc_rsc.c rpmsg-internal.h + $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rproc_rsc.c -o rproc_rsc.o clean: rm -rf *.o rpmsg_main diff --git a/mcs/openamp_demo/rpmsg-internal.h b/mcs/openamp_demo/rpmsg-internal.h index 42c2a4a9..41d71b5b 100644 --- a/mcs/openamp_demo/rpmsg-internal.h +++ b/mcs/openamp_demo/rpmsg-internal.h @@ -20,26 +20,20 @@ #define VRING_ALIGNMENT 4 #define VRING_SIZE 16 +#define RSC_TABLE_ADDR 0x71000000 + #define IRQ_SENDTO_CLIENTOS _IOW('A', 0, int) #define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" extern char *cpu_id; -extern struct metal_io_region *io; - -struct thread_args { - int fd; - int *pipefd; -}; +extern char *boot_address; +extern volatile unsigned int received_data; +extern struct rpmsg_endpoint *ep; struct remoteproc *platform_create_proc(unsigned int id); -int load_bin(void); -void rpmsg_endpoint_init(void); -int rpmsg_endpoint_app(int fds, int ns_setup); - -void open_pty(int *pfdm, int *pfds); -//void master(int fdm, int pipefd[2]); -void *master(void *arg_list); -//int slave(int fds, int pipefd[2]); -void *slave(void *arg_list); +struct rpmsg_device *platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, + unsigned int role, void (*rst_cb)(struct virtio_device *vdev), rpmsg_ns_bind_cb ns_bind_cb); +void rpmsg_app_master(struct remoteproc *rproc); #endif + diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c index d67ae703..1c7e004c 100644 --- a/mcs/openamp_demo/rpmsg_main.c +++ b/mcs/openamp_demo/rpmsg_main.c @@ -5,40 +5,17 @@ #include #include #include -#include #include "rpmsg-internal.h" #define MAX_BIN_BUFLEN (10 * 1024 * 1024) -#define BOOTCMD_MAXSIZE 100 - -static struct remoteproc rproc_inst; -static struct remoteproc_ops ops; char *cpu_id; -static char *boot_address; +char *boot_address; static char *target_binfile; static char *target_binaddr; -struct rproc_priv { - struct remoteproc *rproc; - unsigned int id; -}; - -static void cleanup(void) -{ - printf("\nOpenAMP demo ended.\n"); - remoteproc_remove(&rproc_inst); - if (io) - free(io); -} - -static void handler(int sig) -{ - exit(0); -} - -int load_bin(void) +static int load_bin(void) { int memfd = open("/dev/mem", O_RDWR); int bin_fd = open(target_binfile, O_RDONLY); @@ -70,80 +47,14 @@ int load_bin(void) return 0; } -static struct remoteproc *rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) -{ - struct rproc_priv *priv; - unsigned int id = *((unsigned int *)arg); - - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memset(priv, 0, sizeof(*priv)); - priv->rproc = rproc; - priv->id = id; - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static int rproc_start(struct remoteproc *rproc) -{ - int cpu_handler_fd; - int ret; - char on[BOOTCMD_MAXSIZE]; - - (void)snprintf(on, sizeof(on), "%s%s%s", cpu_id, "@", boot_address); - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("failed to open %s\n", DEV_CLIENT_OS_AGENT); - return cpu_handler_fd; - } - - ret = write(cpu_handler_fd, on, sizeof(on)); - return 0; -} - -static void rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -struct remoteproc_ops rproc_ops = { - .init = rproc_init, - .remove = rproc_remove, - .start = rproc_start, -}; - -struct remoteproc *platform_create_proc(unsigned int id) -{ - struct remoteproc *rproc; - - ops = rproc_ops; - rproc = remoteproc_init(&rproc_inst, &ops, &id); - if (!rproc) - return NULL; - - return &rproc_inst; -} - int main(int argc, char **argv) { + struct remoteproc *rproc = NULL; + struct rpmsg_device *rdev = NULL; + unsigned int id = 1; + int ret; int opt; - int fdm = -1, fds = -1; - pid_t pid; - int pipefd[2]; - pthread_t tidm, tids; - struct thread_args args; - void *retval; - +#if 0 while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { switch (opt) { case 'c': @@ -162,49 +73,40 @@ int main(int argc, char **argv) break; } } - - /* Open the master side and the slave side of the PTY */ - open_pty(&fdm, &fds); - - /* Create unamed pipe */ - if (pipe(pipefd) < 0) { - perror("pipe"); +#endif + cpu_id = "3"; + boot_address = "0x7a000ffc"; + target_binfile = "zephyr.bin"; + target_binaddr = "0x7a000000"; + + rproc = platform_create_proc(id); + if (!rproc) { + printf("create rproc failed\n"); return -1; } - /* Create the child process */ - if ((pid = fork()) < 0) { - perror("fork"); - return -1; - } else if (pid > 0) { - close(fds); /* Close the slave side of the PTY */ - - args.fd = fdm; - args.pipefd = pipefd; - if (pthread_create(&tidm, NULL, master, (void*)&args) < 0) { //T3 - perror("parent pthread_create"); - exit(1); - } - //printf("This is thread1: %ld, pid:%d\n", pthread_self(), getpid()); //T1 - pthread_join(tidm, NULL); - } else { - /* ctrl+c signal, exit program and do cleanup */ - atexit(cleanup); - signal(SIGINT, handler); - - close(fdm); /* Close the master side of the PTY */ + ret = load_bin(); + if (ret) { + printf("failed to load client os\n"); + return ret; + } - args.fd = fds; - args.pipefd = pipefd; - if (pthread_create(&tids, NULL, slave, (void*)&args) < 0) { //T4 - perror("child pthread_create"); - exit(1); - } - //printf("This is thread2: %ld, pid:%d\n", pthread_self(), getpid()); //T2 - pthread_join(tids, &retval); - if (*(int*)retval) - exit(1); + ret = remoteproc_start(rproc); + if (ret) { + printf("start processor failed\n"); + return ret; } + sleep(5); + printf("start processing OpenAMP demo...\n"); +#if 0 + rdev = platform_create_rpmsg_vdev(rproc, 0, VIRTIO_DEV_MASTER, NULL, ns_bind_cb); + if (ret) { + printf("create rpmsg vdev failed\n"); + return ret; + } +#endif + rpmsg_app_master(rproc); - return 0; + remoteproc_remove(rproc); + return ret; } diff --git a/mcs/openamp_demo/rpmsg_ping.c b/mcs/openamp_demo/rpmsg_ping.c index 722b0853..ba3b07af 100644 --- a/mcs/openamp_demo/rpmsg_ping.c +++ b/mcs/openamp_demo/rpmsg_ping.c @@ -21,10 +21,7 @@ static int g_memfd; volatile unsigned int received_data; static struct virtio_device vdev; static struct rpmsg_virtio_device rvdev; -struct metal_io_region *io; -struct virtqueue *vq[2]; -static void *tx_addr, *rx_addr, *shm_start_addr; -static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; +static struct virtqueue *vq[2]; static unsigned char virtio_get_status(struct virtio_device *vdev) { @@ -72,6 +69,10 @@ struct virtio_dispatch dispatch = { .notify = virtio_notify, }; +/* NAME SERVICE CALLBACK */ +struct rpmsg_endpoint my_ept; +struct rpmsg_endpoint *ep = &my_ept; + int endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { @@ -79,9 +80,6 @@ int endpoint_cb(struct rpmsg_endpoint *ept, void *data, return RPMSG_SUCCESS; } -struct rpmsg_endpoint my_ept; -struct rpmsg_endpoint *ep = &my_ept; - static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) { (void)ept; @@ -96,48 +94,95 @@ void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) rpmsg_service_unbind); } +static unsigned int receive_message(struct remoteproc *rproc) +{ + int cpu_handler_fd; + struct pollfd fds; + int ret; + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("open %s failed.\n", DEV_CLIENT_OS_AGENT); + return cpu_handler_fd; + } + + fds.fd = cpu_handler_fd; + fds.events = POLLIN; + + printf("Master core waiting for messages.... \n"); + while (1) { + ret = poll(&fds, 1, -1); + if (ret < 0) { + printf("poll error.\n"); + close(cpu_handler_fd); + return ret; + } + + if (ret == 0) { + printf("poll time out.\n"); + close(cpu_handler_fd); + return ret; + } + + if (fds.revents & POLLIN) { + printf("Master core receiving messages....\n"); + virtqueue_notification(vq[0]); + break; + } + } + close(cpu_handler_fd); + return received_data; +} + +static int send_message(unsigned int message) +{ + return rpmsg_send(ep, &message, sizeof(message)); +} + static struct rpmsg_virtio_shm_pool shpool; -void rpmsg_endpoint_init(void) +void rpmsg_app_master(struct remoteproc *rproc) { int status = 0; + unsigned int message = 0U; + void *tx_addr, *rx_addr; + metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; + + printf("\r\nOpenAMP[master] demo started\r\n"); g_memfd = open("/dev/mem", O_RDWR); tx_addr = mmap((void *)VRING_TX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_TX_ADDRESS); rx_addr = mmap((void *)VRING_RX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_RX_ADDRESS); - shm_start_addr = mmap((void *)SHM_START_ADDR, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, SHM_START_ADDR); - io = malloc(sizeof(struct metal_io_region)); - if (!io) { - printf("malloc io failed\n"); + void *shbuf; + struct metal_io_region *shbuf_io; + shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); + if (!shbuf_io) return; - } - metal_io_init(io, shm_start_addr, shm_physmap, SHM_SIZE, -1, 0, NULL); + shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); /* setup vdev */ vq[0] = virtqueue_allocate(VRING_SIZE); if (vq[0] == NULL) { printf("virtqueue_allocate failed to alloc vq[0]\n"); - free(io); return; } vq[1] = virtqueue_allocate(VRING_SIZE); if (vq[1] == NULL) { printf("virtqueue_allocate failed to alloc vq[1]\n"); - free(io); return; } vdev.role = RPMSG_MASTER; vdev.vrings_num = VRING_COUNT; vdev.func = &dispatch; - rvrings[0].io = io; + rvrings[0].io = shbuf_io; rvrings[0].info.vaddr = tx_addr; rvrings[0].info.num_descs = VRING_SIZE; rvrings[0].info.align = VRING_ALIGNMENT; rvrings[0].vq = vq[0]; - rvrings[1].io = io; + rvrings[1].io = shbuf_io; rvrings[1].info.vaddr = rx_addr; rvrings[1].info.num_descs = VRING_SIZE; rvrings[1].info.align = VRING_ALIGNMENT; @@ -145,76 +190,37 @@ void rpmsg_endpoint_init(void) vdev.vrings_info = &rvrings[0]; - /* setup rvdev */ - rpmsg_virtio_init_shm_pool(&shpool, shm_start_addr, SHM_SIZE); - status = rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, io, &shpool); + printf("initializing rpmsg shared buffer pool\r\n"); + /* Only RPMsg virtio master needs to initialize the shared buffers pool */ + rpmsg_virtio_init_shm_pool(&shpool, shbuf, SHM_SIZE); + + status = rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, shbuf_io, &shpool); if (status != 0) { printf("rpmsg_init_vdev failed %d\n", status); - free(io); return; } -} - -int rpmsg_endpoint_app(int fds, int ns_setup) -{ - int cpu_handler_fd; - struct pollfd poll_fd[2] = {0}; - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("open %s failed.\n", DEV_CLIENT_OS_AGENT); - return -1; - } - - poll_fd[0].fd = fds; - poll_fd[0].events = POLLIN; - poll_fd[1].fd = cpu_handler_fd; - poll_fd[1].events = POLLIN; - - /* Wait for data from slave side of PTY, and data from endpoint of openamp, blocked */ - if (poll(poll_fd, 2, -1) == -1) { - printf("Error %d on poll()\n", errno); - goto err; - } - - close(cpu_handler_fd); - - /* If data on slave side of PTY */ - if (poll_fd[0].revents & POLLIN) { - char recv_buf[200] = {0}; - unsigned int number; - - poll_fd[0].revents = 0; - if (read(fds, recv_buf, sizeof(recv_buf)) > 0) { - number = atoi(recv_buf); - //printf("Master core sending messages: %d\n", number); - rpmsg_send(ep, &number, sizeof(number)); - } - } - /* If data on endpoint of openamp */ - if (poll_fd[1].revents & POLLIN) { - char send_buf[200] = {0}; - int wc; - - poll_fd[1].revents = 0; - virtqueue_notification(vq[0]); - //printf("Master core receiving messages: %d\n", received_data); - - /* Check whether poll event is ns setup */ - if (ns_setup == 1) - return 0; - - received_data++; - wc = snprintf(send_buf, sizeof(send_buf), "Output number: %d\n", received_data); - if (write(fds, send_buf, wc) == -1) { - printf("Error %d on rpmsg_endpoint_app write()\n", errno); - goto err; - } + /* Since we are using name service, we need to wait for a response + * from NS setup and than we need to process it + */ + receive_message(rproc); + + while (message < 99) { + status = send_message(message); + if (status < 0) { + printf("send_message(%u) failed with status %d\n", + message, status); + goto _cleanup; + } + + sleep(1); + message = receive_message(rproc); + printf("Master core received a message: %u\n", message); + + message++; + sleep(1); } - return 0; -err: - close(cpu_handler_fd); - return -1; +_cleanup: + printf("OpenAMP demo ended.\n"); } diff --git a/mcs/openamp_demo/rproc_rsc.c b/mcs/openamp_demo/rproc_rsc.c new file mode 100644 index 00000000..fde06b54 --- /dev/null +++ b/mcs/openamp_demo/rproc_rsc.c @@ -0,0 +1,274 @@ +#include +#include +#include +#include + +#include "rpmsg-internal.h" + +#define BOOTCMD_MAXSIZE 100 + +struct rproc_priv { + struct remoteproc *rproc; + unsigned int id; +}; + +static struct remoteproc *rproc_init(struct remoteproc *rproc, + struct remoteproc_ops *ops, void *arg) +{ + struct rproc_priv *priv; + unsigned int id = *((unsigned int *)arg); + + priv = metal_allocate_memory(sizeof(*priv)); + if (!priv) + return NULL; + + memset(priv, 0, sizeof(*priv)); + priv->rproc = rproc; + priv->id = id; + priv->rproc->ops = ops; + metal_list_init(&priv->rproc->mems); + priv->rproc->priv = priv; + rproc->state = RPROC_READY; + return priv->rproc; +} + +static int rproc_start(struct remoteproc *rproc) +{ + int cpu_handler_fd; + int ret; + char on[BOOTCMD_MAXSIZE]; + + (void)snprintf(on, sizeof(on), "%s%s%s", cpu_id, "@", boot_address); + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("failed to open %s\n", DEV_CLIENT_OS_AGENT); + return cpu_handler_fd; + } + + ret = write(cpu_handler_fd, on, sizeof(on)); + return 0; +} + +static void rproc_remove(struct remoteproc *rproc) +{ + struct rproc_priv *priv; + + priv = (struct rproc_priv *)rproc->priv; + metal_free_memory(priv); +} + +void *rproc_mmap(struct remoteproc *rproc, + metal_phys_addr_t *pa, metal_phys_addr_t *da, + size_t size, unsigned int attribute, + struct metal_io_region **io) +{ + struct remoteproc_mem *mem; + struct metal_io_region *tmpio; + + if (*pa == METAL_BAD_PHYS && *da == METAL_BAD_PHYS) + return NULL; + if (*pa == METAL_BAD_PHYS) + *pa = *da; + if (*da == METAL_BAD_PHYS) + *da = *pa; + + mem = metal_allocate_memory(sizeof(*mem)); + if (!mem) + return NULL; + tmpio = metal_allocate_memory(sizeof(*tmpio)); + if (!tmpio) { + metal_free_memory(mem); + return NULL; + } + + /* mmap pa to va */ + int memfd; + void *va; + memfd = open("/dev/mem", O_RDWR); + va = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, *pa); + if (va == NULL) + return NULL; + perror("mmap"); + + remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio); + metal_io_init(tmpio, va, &mem->pa, size, -1, attribute, NULL); /* metal io manage va and pa */ + remoteproc_add_mem(rproc, mem); + if (io) + *io = tmpio; + + printf("%s: pa=0x%lx, da=0x%lx, size=0x%lx, attribute=0x%x, va=%p, io=%p, rproc=%p.\r\n", + __func__, *pa, *da, size, attribute, va, tmpio, rproc); + + return metal_io_phys_to_virt(tmpio, mem->pa); +} + +int rproc_notify(struct remoteproc *rproc, uint32_t id) +{ +#if 0 + int cpu_handler_fd; + int ret; + int cpu_num = strtol(cpu_id, NULL, 0); + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("open %s failed\n", DEV_CLIENT_OS_AGENT); + return -1; + } + + ret = ioctl(cpu_handler_fd, IRQ_SENDTO_CLIENTOS, cpu_num); + if (ret) { + printf("send ipi tp second os failed\n"); + } + + close(cpu_handler_fd); +#endif + return 0; +} + +struct remoteproc_ops rproc_ops = { + .init = rproc_init, + .remove = rproc_remove, + .start = rproc_start, + .mmap = rproc_mmap, + .notify = rproc_notify, +}; + +static struct remoteproc rproc_inst; + +struct mem_file { + char* base; /* store image base address */ +}; + +#define IMAGE_MAX_LEN (1024 * 1024) +char img_buffer[IMAGE_MAX_LEN] = { 0 }; + +int mem_image_open(void *store, const char *path, const void **image_data) +{ + int fd; + long img_size; + struct mem_file *image = store; + + fd = open(path, O_RDONLY); + if (fd < 0) { + printf("open %s failed.\r\n", path); + perror("open error"); + return -1; + } + + img_size = read(fd, img_buffer, IMAGE_MAX_LEN); + if (img_size <= 0) { + printf("read %s failed.\r\n", path); + perror("read error"); + return -1; + } + + *image_data = img_buffer; + image->base = img_buffer; + + printf("open image %s successfully.\r\n", path); + return img_size; +} + +void mem_image_close(void *store) +{ + return; +} + +int mem_image_load(void *store, size_t offset, size_t size, const void **data, metal_phys_addr_t pa, struct metal_io_region *io, char is_blcoking) +{ + struct mem_file *image = store; + void *va; + + if (pa == METAL_BAD_PHYS) { + if (data == NULL) + return -1; + *data = (const void*)((const char*)(image->base) + offset); + } else { + if (io == NULL) + return -1; + va = metal_io_phys_to_virt(io, pa); + if (va == NULL) + return -1; + memcpy(va, (const void*)((const char*)(image->base) + offset), size); + } + + printf("mem_image_load exec successfully. base:%p, offset:0x%x, size:0x%x, data:%p, pa:0x%x, io:%p, va:%p.\r\n", + image->base, (int)offset, (int)size, *data, (unsigned int)pa, io, va); + return (int)size; +} + +struct image_store_ops mem_image_store_ops = { + .open = mem_image_open, + .close = mem_image_close, + .load = mem_image_load, + .features = SUPPORT_SEEK, +}; + +struct remoteproc *platform_create_proc(unsigned int id) +{ + int ret; + struct mem_file image; + + /* Initialize remoteproc instance */ + if (!remoteproc_init(&rproc_inst, &rproc_ops, &id)) + return NULL; + + /* load elf firmware: resource table */ + remoteproc_config(&rproc_inst, NULL); + ret = remoteproc_load(&rproc_inst, "rsc_elf.elf", &image, &mem_image_store_ops, NULL); + if (ret) { + printf("failed to load firmware.\r\n"); + return NULL; + } + + printf("Initialize remoteproc successfully.\r\n"); + + return &rproc_inst; +} + +struct rpmsg_device *platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, + unsigned int role, void (*rst_cb)(struct virtio_device *vdev), rpmsg_ns_bind_cb ns_bind_cb) +{ + struct remoteproc *rproc = platform; + struct rpmsg_virtio_device *rpmsg_vdev; + struct virtio_device *vdev; + void *shbuf; + struct metal_io_region *shbuf_io; + int ret; + struct rpmsg_virtio_shm_pool shpool; + + rpmsg_vdev = metal_allocate_memory(sizeof(*rpmsg_vdev)); + if (!rpmsg_vdev) + return NULL; + shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); + if (!shbuf_io) + goto err1; + shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); + + printf("creating remoteproc virtio\r\n"); + vdev = remoteproc_create_virtio(rproc, vdev_index, role, rst_cb); + if (!vdev) { + printf("failed remoteproc_create_virtio\r\n"); + goto err1; + } + + printf("initializing rpmsg shared buffer pool\r\n"); + /* Only RPMsg virtio master needs to initialize the shared buffers pool */ + rpmsg_virtio_init_shm_pool(&shpool, shbuf, SHM_SIZE); + + printf("initializing rpmsg vdev\r\n"); + /* RPMsg virtio slave can set shared buffers pool argument to NULL */ + ret = rpmsg_init_vdev(rpmsg_vdev, vdev, ns_bind_cb, shbuf_io, &shpool); + if (ret) { + printf("failed rpmsg_init_vdev\r\n"); + goto err2; + } + + return rpmsg_virtio_get_rpmsg_device(rpmsg_vdev); +err2: + remoteproc_remove_virtio(rproc, vdev); +err1: + metal_free_memory(rpmsg_vdev); + return NULL; +} -- Gitee From 0278edbea5af51c265e151aad5b78503dd19ef02 Mon Sep 17 00:00:00 2001 From: Luoject <13113951796@163.com> Date: Tue, 7 Jun 2022 20:22:40 +0800 Subject: [PATCH 3/3] recover --- mcs/openamp_demo/Makefile | 10 +- mcs/openamp_demo/rpmsg-internal.h | 24 ++- mcs/openamp_demo/rpmsg_main.c | 172 +++++++++++++++---- mcs/openamp_demo/rpmsg_ping.c | 172 +++++++++---------- mcs/openamp_demo/rproc_rsc.c | 274 ------------------------------ 5 files changed, 237 insertions(+), 415 deletions(-) delete mode 100644 mcs/openamp_demo/rproc_rsc.c diff --git a/mcs/openamp_demo/Makefile b/mcs/openamp_demo/Makefile index 67c52b23..2e7a8f5c 100644 --- a/mcs/openamp_demo/Makefile +++ b/mcs/openamp_demo/Makefile @@ -1,7 +1,5 @@ -rpmsg_main: rpmsg_main.o rpmsg_ping.o rproc_rsc.o - $(CC) -g rpmsg_main.o rpmsg_ping.o rproc_rsc.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so -o rpmsg_main - #$(LD) --verbose > rproc_rsc.ld - #-T rproc_rsc.ld +rpmsg_main: rpmsg_main.o rpmsg_ping.o rpmsg_pty.o + $(CC) -g rpmsg_main.o rpmsg_ping.o rpmsg_pty.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so $(SDKTARGETSYSROOT)/lib64/libpthread.so.0 -o rpmsg_main rpmsg_main.o: rpmsg_main.c rpmsg-internal.h $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_main.c -o rpmsg_main.o @@ -9,8 +7,8 @@ rpmsg_main.o: rpmsg_main.c rpmsg-internal.h rpmsg_ping.o: rpmsg_ping.c rpmsg-internal.h $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_ping.c -o rpmsg_ping.o -rproc_rsc.o: rproc_rsc.c rpmsg-internal.h - $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rproc_rsc.c -o rproc_rsc.o +rpmsg_pty.o: rpmsg_pty.c + $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_pty.c -o rpmsg_pty.o clean: rm -rf *.o rpmsg_main diff --git a/mcs/openamp_demo/rpmsg-internal.h b/mcs/openamp_demo/rpmsg-internal.h index 41d71b5b..42c2a4a9 100644 --- a/mcs/openamp_demo/rpmsg-internal.h +++ b/mcs/openamp_demo/rpmsg-internal.h @@ -20,20 +20,26 @@ #define VRING_ALIGNMENT 4 #define VRING_SIZE 16 -#define RSC_TABLE_ADDR 0x71000000 - #define IRQ_SENDTO_CLIENTOS _IOW('A', 0, int) #define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" extern char *cpu_id; -extern char *boot_address; -extern volatile unsigned int received_data; -extern struct rpmsg_endpoint *ep; +extern struct metal_io_region *io; + +struct thread_args { + int fd; + int *pipefd; +}; struct remoteproc *platform_create_proc(unsigned int id); -struct rpmsg_device *platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, - unsigned int role, void (*rst_cb)(struct virtio_device *vdev), rpmsg_ns_bind_cb ns_bind_cb); +int load_bin(void); +void rpmsg_endpoint_init(void); +int rpmsg_endpoint_app(int fds, int ns_setup); -void rpmsg_app_master(struct remoteproc *rproc); -#endif +void open_pty(int *pfdm, int *pfds); +//void master(int fdm, int pipefd[2]); +void *master(void *arg_list); +//int slave(int fds, int pipefd[2]); +void *slave(void *arg_list); +#endif diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c index 1c7e004c..d67ae703 100644 --- a/mcs/openamp_demo/rpmsg_main.c +++ b/mcs/openamp_demo/rpmsg_main.c @@ -5,17 +5,40 @@ #include #include #include +#include #include "rpmsg-internal.h" #define MAX_BIN_BUFLEN (10 * 1024 * 1024) +#define BOOTCMD_MAXSIZE 100 + +static struct remoteproc rproc_inst; +static struct remoteproc_ops ops; char *cpu_id; -char *boot_address; +static char *boot_address; static char *target_binfile; static char *target_binaddr; -static int load_bin(void) +struct rproc_priv { + struct remoteproc *rproc; + unsigned int id; +}; + +static void cleanup(void) +{ + printf("\nOpenAMP demo ended.\n"); + remoteproc_remove(&rproc_inst); + if (io) + free(io); +} + +static void handler(int sig) +{ + exit(0); +} + +int load_bin(void) { int memfd = open("/dev/mem", O_RDWR); int bin_fd = open(target_binfile, O_RDONLY); @@ -47,14 +70,80 @@ static int load_bin(void) return 0; } -int main(int argc, char **argv) +static struct remoteproc *rproc_init(struct remoteproc *rproc, + struct remoteproc_ops *ops, void *arg) +{ + struct rproc_priv *priv; + unsigned int id = *((unsigned int *)arg); + + priv = metal_allocate_memory(sizeof(*priv)); + if (!priv) + return NULL; + + memset(priv, 0, sizeof(*priv)); + priv->rproc = rproc; + priv->id = id; + priv->rproc->ops = ops; + metal_list_init(&priv->rproc->mems); + priv->rproc->priv = priv; + rproc->state = RPROC_READY; + return priv->rproc; +} + +static int rproc_start(struct remoteproc *rproc) { - struct remoteproc *rproc = NULL; - struct rpmsg_device *rdev = NULL; - unsigned int id = 1; + int cpu_handler_fd; int ret; + char on[BOOTCMD_MAXSIZE]; + + (void)snprintf(on, sizeof(on), "%s%s%s", cpu_id, "@", boot_address); + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("failed to open %s\n", DEV_CLIENT_OS_AGENT); + return cpu_handler_fd; + } + + ret = write(cpu_handler_fd, on, sizeof(on)); + return 0; +} + +static void rproc_remove(struct remoteproc *rproc) +{ + struct rproc_priv *priv; + + priv = (struct rproc_priv *)rproc->priv; + metal_free_memory(priv); +} + +struct remoteproc_ops rproc_ops = { + .init = rproc_init, + .remove = rproc_remove, + .start = rproc_start, +}; + +struct remoteproc *platform_create_proc(unsigned int id) +{ + struct remoteproc *rproc; + + ops = rproc_ops; + rproc = remoteproc_init(&rproc_inst, &ops, &id); + if (!rproc) + return NULL; + + return &rproc_inst; +} + +int main(int argc, char **argv) +{ int opt; -#if 0 + int fdm = -1, fds = -1; + pid_t pid; + int pipefd[2]; + pthread_t tidm, tids; + struct thread_args args; + void *retval; + while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { switch (opt) { case 'c': @@ -73,40 +162,49 @@ int main(int argc, char **argv) break; } } -#endif - cpu_id = "3"; - boot_address = "0x7a000ffc"; - target_binfile = "zephyr.bin"; - target_binaddr = "0x7a000000"; - - rproc = platform_create_proc(id); - if (!rproc) { - printf("create rproc failed\n"); + + /* Open the master side and the slave side of the PTY */ + open_pty(&fdm, &fds); + + /* Create unamed pipe */ + if (pipe(pipefd) < 0) { + perror("pipe"); return -1; } - ret = load_bin(); - if (ret) { - printf("failed to load client os\n"); - return ret; - } + /* Create the child process */ + if ((pid = fork()) < 0) { + perror("fork"); + return -1; + } else if (pid > 0) { + close(fds); /* Close the slave side of the PTY */ - ret = remoteproc_start(rproc); - if (ret) { - printf("start processor failed\n"); - return ret; - } - sleep(5); - printf("start processing OpenAMP demo...\n"); -#if 0 - rdev = platform_create_rpmsg_vdev(rproc, 0, VIRTIO_DEV_MASTER, NULL, ns_bind_cb); - if (ret) { - printf("create rpmsg vdev failed\n"); - return ret; + args.fd = fdm; + args.pipefd = pipefd; + if (pthread_create(&tidm, NULL, master, (void*)&args) < 0) { //T3 + perror("parent pthread_create"); + exit(1); + } + //printf("This is thread1: %ld, pid:%d\n", pthread_self(), getpid()); //T1 + pthread_join(tidm, NULL); + } else { + /* ctrl+c signal, exit program and do cleanup */ + atexit(cleanup); + signal(SIGINT, handler); + + close(fdm); /* Close the master side of the PTY */ + + args.fd = fds; + args.pipefd = pipefd; + if (pthread_create(&tids, NULL, slave, (void*)&args) < 0) { //T4 + perror("child pthread_create"); + exit(1); + } + //printf("This is thread2: %ld, pid:%d\n", pthread_self(), getpid()); //T2 + pthread_join(tids, &retval); + if (*(int*)retval) + exit(1); } -#endif - rpmsg_app_master(rproc); - remoteproc_remove(rproc); - return ret; + return 0; } diff --git a/mcs/openamp_demo/rpmsg_ping.c b/mcs/openamp_demo/rpmsg_ping.c index ba3b07af..722b0853 100644 --- a/mcs/openamp_demo/rpmsg_ping.c +++ b/mcs/openamp_demo/rpmsg_ping.c @@ -21,7 +21,10 @@ static int g_memfd; volatile unsigned int received_data; static struct virtio_device vdev; static struct rpmsg_virtio_device rvdev; -static struct virtqueue *vq[2]; +struct metal_io_region *io; +struct virtqueue *vq[2]; +static void *tx_addr, *rx_addr, *shm_start_addr; +static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; static unsigned char virtio_get_status(struct virtio_device *vdev) { @@ -69,10 +72,6 @@ struct virtio_dispatch dispatch = { .notify = virtio_notify, }; -/* NAME SERVICE CALLBACK */ -struct rpmsg_endpoint my_ept; -struct rpmsg_endpoint *ep = &my_ept; - int endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) { @@ -80,6 +79,9 @@ int endpoint_cb(struct rpmsg_endpoint *ept, void *data, return RPMSG_SUCCESS; } +struct rpmsg_endpoint my_ept; +struct rpmsg_endpoint *ep = &my_ept; + static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) { (void)ept; @@ -94,95 +96,48 @@ void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) rpmsg_service_unbind); } -static unsigned int receive_message(struct remoteproc *rproc) -{ - int cpu_handler_fd; - struct pollfd fds; - int ret; - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("open %s failed.\n", DEV_CLIENT_OS_AGENT); - return cpu_handler_fd; - } - - fds.fd = cpu_handler_fd; - fds.events = POLLIN; - - printf("Master core waiting for messages.... \n"); - while (1) { - ret = poll(&fds, 1, -1); - if (ret < 0) { - printf("poll error.\n"); - close(cpu_handler_fd); - return ret; - } - - if (ret == 0) { - printf("poll time out.\n"); - close(cpu_handler_fd); - return ret; - } - - if (fds.revents & POLLIN) { - printf("Master core receiving messages....\n"); - virtqueue_notification(vq[0]); - break; - } - } - close(cpu_handler_fd); - return received_data; -} - -static int send_message(unsigned int message) -{ - return rpmsg_send(ep, &message, sizeof(message)); -} - static struct rpmsg_virtio_shm_pool shpool; -void rpmsg_app_master(struct remoteproc *rproc) +void rpmsg_endpoint_init(void) { int status = 0; - unsigned int message = 0U; - void *tx_addr, *rx_addr; - metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; - - printf("\r\nOpenAMP[master] demo started\r\n"); g_memfd = open("/dev/mem", O_RDWR); tx_addr = mmap((void *)VRING_TX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_TX_ADDRESS); rx_addr = mmap((void *)VRING_RX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_RX_ADDRESS); + shm_start_addr = mmap((void *)SHM_START_ADDR, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, SHM_START_ADDR); - void *shbuf; - struct metal_io_region *shbuf_io; - shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); - if (!shbuf_io) + io = malloc(sizeof(struct metal_io_region)); + if (!io) { + printf("malloc io failed\n"); return; - shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); + } + metal_io_init(io, shm_start_addr, shm_physmap, SHM_SIZE, -1, 0, NULL); /* setup vdev */ vq[0] = virtqueue_allocate(VRING_SIZE); if (vq[0] == NULL) { printf("virtqueue_allocate failed to alloc vq[0]\n"); + free(io); return; } vq[1] = virtqueue_allocate(VRING_SIZE); if (vq[1] == NULL) { printf("virtqueue_allocate failed to alloc vq[1]\n"); + free(io); return; } vdev.role = RPMSG_MASTER; vdev.vrings_num = VRING_COUNT; vdev.func = &dispatch; - rvrings[0].io = shbuf_io; + rvrings[0].io = io; rvrings[0].info.vaddr = tx_addr; rvrings[0].info.num_descs = VRING_SIZE; rvrings[0].info.align = VRING_ALIGNMENT; rvrings[0].vq = vq[0]; - rvrings[1].io = shbuf_io; + rvrings[1].io = io; rvrings[1].info.vaddr = rx_addr; rvrings[1].info.num_descs = VRING_SIZE; rvrings[1].info.align = VRING_ALIGNMENT; @@ -190,37 +145,76 @@ void rpmsg_app_master(struct remoteproc *rproc) vdev.vrings_info = &rvrings[0]; - printf("initializing rpmsg shared buffer pool\r\n"); - /* Only RPMsg virtio master needs to initialize the shared buffers pool */ - rpmsg_virtio_init_shm_pool(&shpool, shbuf, SHM_SIZE); - - status = rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, shbuf_io, &shpool); + /* setup rvdev */ + rpmsg_virtio_init_shm_pool(&shpool, shm_start_addr, SHM_SIZE); + status = rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, io, &shpool); if (status != 0) { printf("rpmsg_init_vdev failed %d\n", status); + free(io); return; } +} + +int rpmsg_endpoint_app(int fds, int ns_setup) +{ + int cpu_handler_fd; + struct pollfd poll_fd[2] = {0}; + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("open %s failed.\n", DEV_CLIENT_OS_AGENT); + return -1; + } + + poll_fd[0].fd = fds; + poll_fd[0].events = POLLIN; + poll_fd[1].fd = cpu_handler_fd; + poll_fd[1].events = POLLIN; + + /* Wait for data from slave side of PTY, and data from endpoint of openamp, blocked */ + if (poll(poll_fd, 2, -1) == -1) { + printf("Error %d on poll()\n", errno); + goto err; + } + + close(cpu_handler_fd); + + /* If data on slave side of PTY */ + if (poll_fd[0].revents & POLLIN) { + char recv_buf[200] = {0}; + unsigned int number; + + poll_fd[0].revents = 0; + if (read(fds, recv_buf, sizeof(recv_buf)) > 0) { + number = atoi(recv_buf); + //printf("Master core sending messages: %d\n", number); + rpmsg_send(ep, &number, sizeof(number)); + } + } - /* Since we are using name service, we need to wait for a response - * from NS setup and than we need to process it - */ - receive_message(rproc); - - while (message < 99) { - status = send_message(message); - if (status < 0) { - printf("send_message(%u) failed with status %d\n", - message, status); - goto _cleanup; - } - - sleep(1); - message = receive_message(rproc); - printf("Master core received a message: %u\n", message); - - message++; - sleep(1); + /* If data on endpoint of openamp */ + if (poll_fd[1].revents & POLLIN) { + char send_buf[200] = {0}; + int wc; + + poll_fd[1].revents = 0; + virtqueue_notification(vq[0]); + //printf("Master core receiving messages: %d\n", received_data); + + /* Check whether poll event is ns setup */ + if (ns_setup == 1) + return 0; + + received_data++; + wc = snprintf(send_buf, sizeof(send_buf), "Output number: %d\n", received_data); + if (write(fds, send_buf, wc) == -1) { + printf("Error %d on rpmsg_endpoint_app write()\n", errno); + goto err; + } } -_cleanup: - printf("OpenAMP demo ended.\n"); + return 0; +err: + close(cpu_handler_fd); + return -1; } diff --git a/mcs/openamp_demo/rproc_rsc.c b/mcs/openamp_demo/rproc_rsc.c deleted file mode 100644 index fde06b54..00000000 --- a/mcs/openamp_demo/rproc_rsc.c +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -#define BOOTCMD_MAXSIZE 100 - -struct rproc_priv { - struct remoteproc *rproc; - unsigned int id; -}; - -static struct remoteproc *rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) -{ - struct rproc_priv *priv; - unsigned int id = *((unsigned int *)arg); - - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memset(priv, 0, sizeof(*priv)); - priv->rproc = rproc; - priv->id = id; - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static int rproc_start(struct remoteproc *rproc) -{ - int cpu_handler_fd; - int ret; - char on[BOOTCMD_MAXSIZE]; - - (void)snprintf(on, sizeof(on), "%s%s%s", cpu_id, "@", boot_address); - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("failed to open %s\n", DEV_CLIENT_OS_AGENT); - return cpu_handler_fd; - } - - ret = write(cpu_handler_fd, on, sizeof(on)); - return 0; -} - -static void rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -void *rproc_mmap(struct remoteproc *rproc, - metal_phys_addr_t *pa, metal_phys_addr_t *da, - size_t size, unsigned int attribute, - struct metal_io_region **io) -{ - struct remoteproc_mem *mem; - struct metal_io_region *tmpio; - - if (*pa == METAL_BAD_PHYS && *da == METAL_BAD_PHYS) - return NULL; - if (*pa == METAL_BAD_PHYS) - *pa = *da; - if (*da == METAL_BAD_PHYS) - *da = *pa; - - mem = metal_allocate_memory(sizeof(*mem)); - if (!mem) - return NULL; - tmpio = metal_allocate_memory(sizeof(*tmpio)); - if (!tmpio) { - metal_free_memory(mem); - return NULL; - } - - /* mmap pa to va */ - int memfd; - void *va; - memfd = open("/dev/mem", O_RDWR); - va = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, *pa); - if (va == NULL) - return NULL; - perror("mmap"); - - remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio); - metal_io_init(tmpio, va, &mem->pa, size, -1, attribute, NULL); /* metal io manage va and pa */ - remoteproc_add_mem(rproc, mem); - if (io) - *io = tmpio; - - printf("%s: pa=0x%lx, da=0x%lx, size=0x%lx, attribute=0x%x, va=%p, io=%p, rproc=%p.\r\n", - __func__, *pa, *da, size, attribute, va, tmpio, rproc); - - return metal_io_phys_to_virt(tmpio, mem->pa); -} - -int rproc_notify(struct remoteproc *rproc, uint32_t id) -{ -#if 0 - int cpu_handler_fd; - int ret; - int cpu_num = strtol(cpu_id, NULL, 0); - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("open %s failed\n", DEV_CLIENT_OS_AGENT); - return -1; - } - - ret = ioctl(cpu_handler_fd, IRQ_SENDTO_CLIENTOS, cpu_num); - if (ret) { - printf("send ipi tp second os failed\n"); - } - - close(cpu_handler_fd); -#endif - return 0; -} - -struct remoteproc_ops rproc_ops = { - .init = rproc_init, - .remove = rproc_remove, - .start = rproc_start, - .mmap = rproc_mmap, - .notify = rproc_notify, -}; - -static struct remoteproc rproc_inst; - -struct mem_file { - char* base; /* store image base address */ -}; - -#define IMAGE_MAX_LEN (1024 * 1024) -char img_buffer[IMAGE_MAX_LEN] = { 0 }; - -int mem_image_open(void *store, const char *path, const void **image_data) -{ - int fd; - long img_size; - struct mem_file *image = store; - - fd = open(path, O_RDONLY); - if (fd < 0) { - printf("open %s failed.\r\n", path); - perror("open error"); - return -1; - } - - img_size = read(fd, img_buffer, IMAGE_MAX_LEN); - if (img_size <= 0) { - printf("read %s failed.\r\n", path); - perror("read error"); - return -1; - } - - *image_data = img_buffer; - image->base = img_buffer; - - printf("open image %s successfully.\r\n", path); - return img_size; -} - -void mem_image_close(void *store) -{ - return; -} - -int mem_image_load(void *store, size_t offset, size_t size, const void **data, metal_phys_addr_t pa, struct metal_io_region *io, char is_blcoking) -{ - struct mem_file *image = store; - void *va; - - if (pa == METAL_BAD_PHYS) { - if (data == NULL) - return -1; - *data = (const void*)((const char*)(image->base) + offset); - } else { - if (io == NULL) - return -1; - va = metal_io_phys_to_virt(io, pa); - if (va == NULL) - return -1; - memcpy(va, (const void*)((const char*)(image->base) + offset), size); - } - - printf("mem_image_load exec successfully. base:%p, offset:0x%x, size:0x%x, data:%p, pa:0x%x, io:%p, va:%p.\r\n", - image->base, (int)offset, (int)size, *data, (unsigned int)pa, io, va); - return (int)size; -} - -struct image_store_ops mem_image_store_ops = { - .open = mem_image_open, - .close = mem_image_close, - .load = mem_image_load, - .features = SUPPORT_SEEK, -}; - -struct remoteproc *platform_create_proc(unsigned int id) -{ - int ret; - struct mem_file image; - - /* Initialize remoteproc instance */ - if (!remoteproc_init(&rproc_inst, &rproc_ops, &id)) - return NULL; - - /* load elf firmware: resource table */ - remoteproc_config(&rproc_inst, NULL); - ret = remoteproc_load(&rproc_inst, "rsc_elf.elf", &image, &mem_image_store_ops, NULL); - if (ret) { - printf("failed to load firmware.\r\n"); - return NULL; - } - - printf("Initialize remoteproc successfully.\r\n"); - - return &rproc_inst; -} - -struct rpmsg_device *platform_create_rpmsg_vdev(void *platform, unsigned int vdev_index, - unsigned int role, void (*rst_cb)(struct virtio_device *vdev), rpmsg_ns_bind_cb ns_bind_cb) -{ - struct remoteproc *rproc = platform; - struct rpmsg_virtio_device *rpmsg_vdev; - struct virtio_device *vdev; - void *shbuf; - struct metal_io_region *shbuf_io; - int ret; - struct rpmsg_virtio_shm_pool shpool; - - rpmsg_vdev = metal_allocate_memory(sizeof(*rpmsg_vdev)); - if (!rpmsg_vdev) - return NULL; - shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); - if (!shbuf_io) - goto err1; - shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); - - printf("creating remoteproc virtio\r\n"); - vdev = remoteproc_create_virtio(rproc, vdev_index, role, rst_cb); - if (!vdev) { - printf("failed remoteproc_create_virtio\r\n"); - goto err1; - } - - printf("initializing rpmsg shared buffer pool\r\n"); - /* Only RPMsg virtio master needs to initialize the shared buffers pool */ - rpmsg_virtio_init_shm_pool(&shpool, shbuf, SHM_SIZE); - - printf("initializing rpmsg vdev\r\n"); - /* RPMsg virtio slave can set shared buffers pool argument to NULL */ - ret = rpmsg_init_vdev(rpmsg_vdev, vdev, ns_bind_cb, shbuf_io, &shpool); - if (ret) { - printf("failed rpmsg_init_vdev\r\n"); - goto err2; - } - - return rpmsg_virtio_get_rpmsg_device(rpmsg_vdev); -err2: - remoteproc_remove_virtio(rproc, vdev); -err1: - metal_free_memory(rpmsg_vdev); - return NULL; -} -- Gitee