diff --git a/mcs/CMakeLists.txt b/mcs/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c5c0241f82bf95d2f3c1107f9a236f6918e610b8 --- /dev/null +++ b/mcs/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.19) + +project(openamp_demo) + +set(CMAKE_C_COMPILER ${CC}) + +message(STATUS "SDKTARGETSYSROOT=$ENV{SDKTARGETSYSROOT}") +message(STATUS "DEMO_TARGET=${DEMO_TARGET}") + +set(SHARED_LINK_LIBS + $ENV{SDKTARGETSYSROOT}/usr/lib64/libopen_amp.so + $ENV{SDKTARGETSYSROOT}/usr/lib64/libmetal.so + $ENV{SDKTARGETSYSROOT}/lib64/libsysfs.so +) + +add_library(remoteproc STATIC + ./modules/remoteproc_module.c +) +target_link_libraries(remoteproc + ${SHARED_LINK_LIBS} +) + +add_library(virtio STATIC + ./modules/virtio_module.c +) +target_link_libraries(virtio + ${SHARED_LINK_LIBS} +) + +add_library(pty STATIC + ./modules/rpmsg_pty.c +) + +set(INC_PATH + $ENV{SDKTARGETSYSROOT}/usr/include + ./modules +) + +if(DEMO_TARGET MATCHES "openamp_demo") + list(APPEND INC_PATH "./openamp_demo") + list(APPEND SRC_FILE "./openamp_demo/rpmsg_main.c") + list(APPEND STATIC_LINK_LIBS "remoteproc;virtio") +elseif(DEMO_TARGET MATCHES "rpmsg_pty_demo") + list(APPEND INC_PATH "./rpmsg_pty_demo") + list(APPEND SRC_FILE "./rpmsg_pty_demo/rpmsg_main.c") + list(APPEND STATIC_LINK_LIBS "remoteproc;virtio;pty") +else() + message(FATAL_ERROR "DEMO_TARGET: choose a target to build. + [openamp_demo|rpmsg_pty_demo]") #rsc_table_demo|cyclitest_demo|rpmsg_service_demo +endif() + +include_directories(${INC_PATH}) +add_executable(rpmsg_main ${SRC_FILE}) +target_link_libraries(rpmsg_main + ${SHARED_LINK_LIBS} + ${STATIC_LINK_LIBS} +) \ No newline at end of file diff --git a/mcs/README.md b/mcs/README.md index 87220c141e483a96fb4c0076a1a7a3be76385f10..f2387dc2ad9a251a75d4330f96e7e9279a36ebaf 100644 --- a/mcs/README.md +++ b/mcs/README.md @@ -42,7 +42,8 @@ OpenAMP包括如下三大重要组件: 3. 编译用户态程序rpmsg_main,编译方式如下: ```` - cd openamp_demo + cmake -S . -B build -DDEMO_TARGET=openamp_demo + cd build make ```` diff --git a/mcs/modules/remoteproc_module.c b/mcs/modules/remoteproc_module.c new file mode 100644 index 0000000000000000000000000000000000000000..e12f5002beb997cf3e09b1e14e5dcf7e2f90e757 --- /dev/null +++ b/mcs/modules/remoteproc_module.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include "remoteproc_module.h" + +#define BOOTCMD_MAXSIZE 100 + +static struct remoteproc *rproc_init(struct remoteproc *rproc, + const struct remoteproc_ops *ops, void *args) +{ + struct rproc_priv *priv; + + (void)rproc; + priv = metal_allocate_memory(sizeof(*priv)); + if (!priv) + return NULL; + + memcpy(priv, (struct rproc_priv *)args, sizeof(*priv)); + priv->rproc->ops = ops; + metal_list_init(&priv->rproc->mems); + priv->rproc->priv = priv; + rproc->state = RPROC_READY; + return priv->rproc; +} + +static void rproc_remove(struct remoteproc *rproc) +{ + struct rproc_priv *priv; + + priv = (struct rproc_priv *)rproc->priv; + metal_free_memory(priv); +} + +static int rproc_start(struct remoteproc *rproc) +{ + int cpu_handler_fd; + int ret; + char on[BOOTCMD_MAXSIZE]; + struct rproc_priv *args = (struct rproc_priv *)rproc->priv; + + (void)snprintf(on, sizeof(on), "%d%s%d", args->cpu_id, "@", args->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 int rproc_stop(struct remoteproc *rproc) +{ +#if 0 + /* send message to zephyr, zephyr shut itself down by PSCI */ + int ret = send_message("shutdown\r\n", 10); + sleep(3); +#endif + return 0; +} + +const struct remoteproc_ops rproc_ops = { + .init = rproc_init, + .remove = rproc_remove, + .start = rproc_start, + .stop = rproc_stop, +}; + +/* create remoteproc */ +struct remoteproc *platform_create_proc(struct rproc_priv *args) +{ + struct remoteproc *rproc = remoteproc_init(args->rproc, &rproc_ops, args); + if (!rproc) + return NULL; + + return rproc; +} diff --git a/mcs/modules/remoteproc_module.h b/mcs/modules/remoteproc_module.h new file mode 100644 index 0000000000000000000000000000000000000000..d8b51b32649bf3d4540811d83059f429ffea3a77 --- /dev/null +++ b/mcs/modules/remoteproc_module.h @@ -0,0 +1,33 @@ +#ifndef REMOTEPROC_MODULE_H +#define REMOTEPROC_MODULE_H + +#include + +#define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" + +struct rproc_priv { + struct remoteproc *rproc; /* pass a remoteproc instance pointer */ + unsigned int idx; /* remoteproc instance idx */ + unsigned int cpu_id; /* related arg: cpu id */ + unsigned int boot_address; /* related arg: boot address(in hex format) */ +}; + +/* create remoteproc */ +struct remoteproc *platform_create_proc(struct rproc_priv *args); + +/* + start remoteproc: refet to + int remoteproc_start(struct remoteproc *rproc); +*/ + +/* + stop remoteproc: refet to + int remoteproc_stop(struct remoteproc *rproc); +*/ + +/* + remove remoteproc: refet to + int remoteproc_remove(struct remoteproc *rproc); +*/ + +#endif \ No newline at end of file diff --git a/mcs/openamp_demo/rpmsg_app.c b/mcs/modules/rpmsg_pty.c similarity index 52% rename from mcs/openamp_demo/rpmsg_app.c rename to mcs/modules/rpmsg_pty.c index 749603ff4a6ba1a9cfbc4062d60c479525613a0c..af2750f6a3e49d4c8f446725dc71e3cd8e03bcd1 100644 --- a/mcs/openamp_demo/rpmsg_app.c +++ b/mcs/modules/rpmsg_pty.c @@ -1,17 +1,14 @@ #define _XOPEN_SOURCE 600 #include +#include #include #include #include -#include -#include - -#include "rpmsg-internal.h" +#include +#include "virtio_module.h" /* define the keys according to your terminfo */ #define KEY_CTRL_C 3 -#define KEY_BACKSPACE 127 -#define KEY_ENTER '\r' void open_pty(int *pfdm, int *pfds) { @@ -39,66 +36,30 @@ void open_pty(int *pfdm, int *pfds) *pfds = fds; } -int simple_shell(int fdm, unsigned char *cmd, int cmd_len, int *real_len) -{ - int i; - int ret; - char display[64] = "\ruart:~$ "; - const int title_len = strlen(display); - int dislen = strlen(display); - int dislen_echo; - - memset(cmd, 0, cmd_len); - for (i = 0; i < cmd_len; i++) { - ret = read(fdm, &cmd[i], 1); - - display[dislen] = cmd[i]; - dislen++; - dislen_echo = dislen; - - if (cmd[i] == KEY_CTRL_C) { /* special key: ctrl+c */ - pthread_exit(NULL); - } - - if ((cmd[i] == KEY_BACKSPACE) && (dislen > title_len)) { /* special key: backspace */ - dislen -= 2; - display[dislen] = ' '; - dislen_echo = dislen + 1; - } - - if (cmd[i] == KEY_ENTER) { /* special key: enter */ - cmd[i] = '\n'; - break; - } - - ret = write(fdm, display, dislen_echo); /* the command echo */ - } - - ret = write(fdm, "\ruart:~$ ", title_len); /* override the command return from rtos */ - *real_len = i + 1; - return ret; -} - void *shell_user(void *arg) { int ret; int fdm, fds; - unsigned char cmd[64] = {0}; - int cmd_len; - unsigned char reply[2048] = {0}; + unsigned char cmd[1]; + unsigned char reply[2048]; int reply_len; /* open PTY, pts binds to terminal, using screen to open pts */ open_pty(&fdm, &fds); while (1) { - ret = simple_shell(fdm, cmd, sizeof(cmd), &cmd_len); /* get command from ptmx */ + memset(cmd, 0, 1); + ret = read(fdm, cmd, 1); /* get command from ptmx */ if (ret < 0) { - printf("shell_user: simple_shell(%s) failed: %d\n", cmd, ret); + printf("shell_user: get from ptmx failed: %d\n", ret); return (void*)-1; } - ret = send_message(cmd, cmd_len); /* send command to rtos */ + if (cmd[0] == KEY_CTRL_C) /* special key: ctrl+c */ + //pthread_exit(NULL); + return (void*)0; + + ret = send_message(cmd, 1); /* send command to rtos */ if (ret < 0) { printf("shell_user: send_message(%s) failed: %d\n", cmd, ret); return (void*)-1; @@ -106,7 +67,7 @@ void *shell_user(void *arg) ret = receive_message(reply, sizeof(reply), &reply_len); /* receive reply from rtos */ if (ret < 0) { - printf("shell_user: receive_message(%s) failed: %d\n", reply, ret); + printf("shell_user: receive_message failed: %d\n", ret); return (void*)-1; } @@ -123,30 +84,11 @@ void *shell_user(void *arg) void *log_user(void *arg) { int ret; - int cmd_fd, log_fd; - unsigned char cmd[64] = {0}; - int cmd_len; + int log_fd; unsigned char log[2048] = {0}; int log_len; - const char *cmd_file = "/tmp/zephyr_cmd.txt"; const char *log_file = "/tmp/zephyr_log.txt"; - /* read command from file */ - cmd_fd = open(cmd_file, O_RDONLY); - if (cmd_fd < 0) { - printf("log_user: open (%s) failed: %d\n", cmd_file, cmd_fd); - return (void*)-1; - } - cmd_len = read(cmd_fd, cmd, sizeof(cmd)); - cmd[cmd_len] = '\n'; - close(cmd_fd); - - ret = send_message(cmd, cmd_len + 1); /* send command to rtos */ - if (ret < 0) { - printf("shell_user: send_message(%s) failed: %d\n", cmd, ret); - return (void*)-1; - } - ret = receive_message(log, sizeof(log), &log_len); /* receive log from rtos */ if (ret < 0) { printf("log_user: receive_message(%s) failed: %d\n", log, ret); diff --git a/mcs/modules/rpmsg_pty.h b/mcs/modules/rpmsg_pty.h new file mode 100644 index 0000000000000000000000000000000000000000..59da943b04ca94d5ee36ae2c3eba7a843f04bd50 --- /dev/null +++ b/mcs/modules/rpmsg_pty.h @@ -0,0 +1,7 @@ +#ifndef RPMSG_PTY_H +#define RPMSG_PTY_H + +void *shell_user(void *arg); +void *log_user(void *arg); + +#endif \ No newline at end of file diff --git a/mcs/openamp_demo/rpmsg_ping.c b/mcs/modules/virtio_module.c similarity index 96% rename from mcs/openamp_demo/rpmsg_ping.c rename to mcs/modules/virtio_module.c index ff9b1135cbc0469f93df9e9c9b490b4cb7f14de6..6a440270fc8735877ac863ceea482daac8eeb793 100644 --- a/mcs/openamp_demo/rpmsg_ping.c +++ b/mcs/modules/virtio_module.c @@ -5,8 +5,7 @@ #include #include #include - -#include "rpmsg-internal.h" +#include "virtio_module.h" static struct virtio_vring_info rvrings[2] = { [0] = { @@ -102,7 +101,7 @@ void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) /* message standard receive interface */ int receive_message(unsigned char *message, int message_len, int *real_len) { - int ret = -1; + int ret; int cpu_handler_fd; struct pollfd fds; @@ -136,9 +135,10 @@ int receive_message(unsigned char *message, int message_len, int *real_len) } } - if (received_len >= message_len) { + if (received_len > message_len) { printf("receive_message: buffer is too small.\n"); *real_len = 0; + ret = -1; goto _cleanup; } @@ -159,12 +159,14 @@ int send_message(unsigned char *message, int len) static struct rpmsg_virtio_shm_pool shpool; -void rpmsg_endpoint_init(void) +void virtio_init(void) { int status = 0; char message[100] = {0}; int len; + printf("Initialize the virtio, virtqueue, return rpmsg device...\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); diff --git a/mcs/openamp_demo/rpmsg-internal.h b/mcs/modules/virtio_module.h similarity index 78% rename from mcs/openamp_demo/rpmsg-internal.h rename to mcs/modules/virtio_module.h index 6e07328ff856366d8586cc257617617eb3ba32d7..d4c0d3006b5cf40ea4321971a13be42826c2dafb 100644 --- a/mcs/openamp_demo/rpmsg-internal.h +++ b/mcs/modules/virtio_module.h @@ -1,9 +1,5 @@ -#ifndef RPMSG_INTERNAL_H_ -#define RPMSG_INTERNAL_H_ - -#include -#include -#include +#ifndef VIRTIO_MODULE_H +#define VIRTIO_MODULE_H #define VDEV_START_ADDR 0x70000000 #define VDEV_SIZE 0x30000 @@ -23,14 +19,12 @@ #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; +void virtio_init(void); -void rpmsg_endpoint_init(void); int receive_message(unsigned char *message, int message_len, int *real_len); int send_message(unsigned char *message, int len); -void *shell_user(void *arg); -void *log_user(void *arg); +extern char *cpu_id; +extern struct metal_io_region *io; -#endif +#endif \ No newline at end of file diff --git a/mcs/openamp_demo/Makefile b/mcs/openamp_demo/Makefile deleted file mode 100644 index daccc80d5591eab2a3dc8b9a513e8555ce073c39..0000000000000000000000000000000000000000 --- a/mcs/openamp_demo/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -rpmsg_main: clean rpmsg_main.o rpmsg_ping.o rpmsg_app.o - $(CC) rpmsg_main.o rpmsg_ping.o rpmsg_app.o $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so -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 - -rpmsg_ping.o: rpmsg_ping.c rpmsg-internal.h - $(CC) -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_ping.c -o rpmsg_ping.o - -rpmsg_app.o: rpmsg_ping.c rpmsg-internal.h - $(CC) -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_app.c -o rpmsg_app.o - -clean: - rm -rf *.o rpmsg_main diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c index a95d031121b4f1ba6cde1293369bf416e109c30b..a0e86dffacd065457c5db013ba47856de729fbcf 100644 --- a/mcs/openamp_demo/rpmsg_main.c +++ b/mcs/openamp_demo/rpmsg_main.c @@ -1,130 +1,90 @@ #include #include #include -#include #include #include #include +#include "remoteproc_module.h" +#include "virtio_module.h" -#include "rpmsg-internal.h" - -#define BOOTCMD_MAXSIZE 100 - -static struct remoteproc rproc_inst; -static struct remoteproc_ops ops; +#define MAX_BIN_BUFLEN (10 * 1024 * 1024) char *cpu_id; static 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_stop(&rproc_inst); - remoteproc_remove(&rproc_inst); - if (io) - free(io); -} - -static void handler(int sig) -{ - exit(0); -} - -static struct remoteproc *rproc_init(struct remoteproc *rproc, - const 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) +static int load_bin(void) { - int cpu_handler_fd; - int ret; - char on[BOOTCMD_MAXSIZE]; - - (void)snprintf(on, sizeof(on), "%s%s%s", cpu_id, "@", boot_address); + int memfd = open("/dev/mem", O_RDWR); + int bin_fd = open(target_binfile, O_RDONLY); + void *access_address = NULL, *bin_buffer = NULL; + long bin_size; + long long int bin_addr = strtoll(target_binaddr, NULL, 0); + + if (bin_fd < 0 || memfd < 0) { + printf("invalid bin file fd\n"); + exit(-1); + } - 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; + bin_buffer = (void *)malloc(MAX_BIN_BUFLEN); + if (!bin_buffer) { + printf("malloc bin_buffer failed\n"); + exit(-1); } - ret = write(cpu_handler_fd, on, sizeof(on)); - return 0; -} + bin_size = read(bin_fd, bin_buffer, MAX_BIN_BUFLEN); + if (bin_size == 0) { + printf("read bin file failed\n"); + exit(-1); + } -static int rproc_stop(struct remoteproc *rproc) -{ -#if 0 - /* send message to zephyr, zephyr shut itself down by PSCI */ - int ret = send_message("shutdown\r\n", 10); - sleep(3); -#endif + access_address = mmap((void *)bin_addr, MAX_BIN_BUFLEN, PROT_READ | PROT_WRITE, + MAP_SHARED, memfd, bin_addr); + memcpy(access_address, bin_buffer, bin_size); + free(bin_buffer); return 0; } -static void rproc_remove(struct remoteproc *rproc) +int rpmsg_app_master(void) { - struct rproc_priv *priv; + int ret; + unsigned int message = 0; + int len; - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} + printf("start processing OpenAMP demo...\n"); -struct remoteproc_ops rproc_ops = { - .init = rproc_init, - .remove = rproc_remove, - .start = rproc_start, - .stop = rproc_stop, -}; + while (message < 99) { + ret = send_message((unsigned char*)&message, sizeof(message)); + if (ret < 0) { + printf("send_message(%u) failed with status %d\n", message, ret); + return ret; + } -static struct remoteproc *platform_create_proc(unsigned int id) -{ - struct remoteproc *rproc; + sleep(1); + ret = receive_message((unsigned char*)&message, sizeof(message), &len); + if (ret < 0) { + printf("receive_message failed with status %d\n", ret); + return ret; + } + printf("Master core received a message: %u\n", message); - ops = rproc_ops; - rproc = remoteproc_init(&rproc_inst, &ops, &id); - if (!rproc) - return NULL; + message++; + sleep(1); + } - return &rproc_inst; + return 0; } int main(int argc, char **argv) { - struct remoteproc *rproc = NULL; - unsigned int id = 1; int ret; int opt; - pthread_t tida, tidb, tidc; - void *reta, *retb, *retc; + struct remoteproc rproc; + struct rproc_priv args = { &rproc, 1 }; + struct remoteproc *rproc_inst; - /* ctrl+c signal, exit program and do cleanup */ - atexit(cleanup); - signal(SIGINT, handler); - - /* using qemu arg: -device loader,file=zephyr.elf,cpu-num=1 */ - while ((opt = getopt(argc, argv, "c:b:")) != -1) { + while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { switch (opt) { case 'c': cpu_id = optarg; @@ -132,62 +92,52 @@ int main(int argc, char **argv) case 'b': boot_address = optarg; break; + case 't': + target_binfile = optarg; + break; + case 'a': + target_binaddr = optarg; + break; default: break; } } - rproc = platform_create_proc(id); - if (!rproc) { + args.cpu_id = strtol(cpu_id, NULL, 10); + args.boot_address = strtol(boot_address, NULL, 16); + rproc_inst = platform_create_proc(&args); + if (!rproc_inst) { printf("create rproc failed\n"); return -1; } - ret = remoteproc_start(rproc); + ret = load_bin(); if (ret) { - printf("start processor failed\n"); + printf("failed to load client os\n"); return ret; } - sleep(5); - printf("start processing OpenAMP demo...\n"); - rpmsg_endpoint_init(); + ret = remoteproc_start(rproc_inst); + if (ret) { + printf("start processor failed\n"); + return ret; + } - /* Multi-thread processing user requests */ - printf("Multi-thread processing user requests...\n"); + sleep(5); /* wait for zephyr booting */ + virtio_init(); - /* userA: user shell, open with screen */ - if (pthread_create(&tida, NULL, shell_user, NULL) < 0) { - perror("userA pthread_create"); - return -1; - } -#if 0 - /* userB: dual user shell, open with screen */ - if (pthread_create(&tidb, NULL, shell_user, NULL) < 0) { - perror("userB pthread_create"); - return -1; - } -#endif - /* userC: zephyr log */ - if (pthread_create(&tidc, NULL, log_user, NULL) < 0) { - perror("userC pthread_create"); - return -1; + ret = rpmsg_app_master(); + if (ret) { + printf("openamp demo run failed\n"); + return ret; } - pthread_join(tida, &reta); - if ((long)reta) { - printf("userA return failed: %ld", (long)reta); - } -#if 0 - pthread_join(tidb, &retb); - if ((long)retb) { - printf("userB return failed: %ld", (long)retb); - } -#endif - pthread_join(tidc, &retc); - if ((long)retc) { - printf("userC return failed: %ld", (long)retc); - } + printf("\nOpenAMP demo ended.\n"); + if (io) + free(io); + remoteproc_stop(rproc_inst); + rproc_inst->state = RPROC_OFFLINE; + remoteproc_remove(rproc_inst); return 0; } diff --git a/mcs/openamp_demo/zephyr.bin b/mcs/openamp_demo/zephyr.bin new file mode 100644 index 0000000000000000000000000000000000000000..585dd2d37f30ff057677080ce98ed06fb1b0c2ae Binary files /dev/null and b/mcs/openamp_demo/zephyr.bin differ diff --git a/mcs/openamp_demo_pty_multithread/Makefile b/mcs/openamp_demo_pty_multithread/Makefile deleted file mode 100644 index 2e7a8f5c4029dce6c81e571d4faf8618759ab907..0000000000000000000000000000000000000000 --- a/mcs/openamp_demo_pty_multithread/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -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 - -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 - -clean: - rm -rf *.o rpmsg_main diff --git a/mcs/openamp_demo_pty_multithread/rpmsg-internal.h b/mcs/openamp_demo_pty_multithread/rpmsg-internal.h deleted file mode 100644 index 105d6c7c7ab800ba81e27c8b0591a7078a879999..0000000000000000000000000000000000000000 --- a/mcs/openamp_demo_pty_multithread/rpmsg-internal.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef RPMSG_INTERNAL_H_ -#define RPMSG_INTERNAL_H_ - -#include -#include -#include - -#define VDEV_START_ADDR 0x70000000 -#define VDEV_SIZE 0x30000 - -#define VDEV_STATUS_ADDR VDEV_START_ADDR -#define VDEV_STATUS_SIZE 0x4000 - -#define SHM_START_ADDR (VDEV_START_ADDR + VDEV_STATUS_SIZE) -#define SHM_SIZE (VDEV_SIZE - VDEV_STATUS_SIZE) - -#define VRING_COUNT 2 -#define VRING_RX_ADDRESS (VDEV_START_ADDR + SHM_SIZE - VDEV_STATUS_SIZE) -#define VRING_TX_ADDRESS (VDEV_START_ADDR + SHM_SIZE) -#define VRING_ALIGNMENT 4 -#define VRING_SIZE 16 - -#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; -}; - -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(void *arg_list); -void *slave(void *arg_list); - -#endif diff --git a/mcs/openamp_demo_pty_multithread/rpmsg_ping.c b/mcs/openamp_demo_pty_multithread/rpmsg_ping.c deleted file mode 100644 index 722b0853c79d399dddf5a9ca2ffdb0dd2b1ff95a..0000000000000000000000000000000000000000 --- a/mcs/openamp_demo_pty_multithread/rpmsg_ping.c +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -static struct virtio_vring_info rvrings[2] = { - [0] = { - .info.align = VRING_ALIGNMENT, - }, - [1] = { - .info.align = VRING_ALIGNMENT, - }, -}; - -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 unsigned char virtio_get_status(struct virtio_device *vdev) -{ - return VIRTIO_CONFIG_STATUS_DRIVER_OK; -} - -static void virtio_set_status(struct virtio_device *vdev, unsigned char status) -{ - void *stat_addr = NULL; - stat_addr = mmap((void *)VDEV_STATUS_ADDR, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VDEV_STATUS_ADDR); - *(volatile unsigned int *)stat_addr = (unsigned int)status; -} - -static uint32_t virtio_get_features(struct virtio_device *vdev) -{ - return 1 << VIRTIO_RPMSG_F_NS; -} - -static void virtio_notify(struct virtqueue *vq) -{ - (void)vq; - 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; - } - - ret = ioctl(cpu_handler_fd, IRQ_SENDTO_CLIENTOS, cpu_num); - if (ret) { - printf("send ipi tp second os failed\n"); - } - - close(cpu_handler_fd); - return; -} - -struct virtio_dispatch dispatch = { - .get_status = virtio_get_status, - .set_status = virtio_set_status, - .get_features = virtio_get_features, - .notify = virtio_notify, -}; - -int endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - received_data = *((unsigned int *) 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; - rpmsg_destroy_ept(ep); -} - -void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) -{ - (void)rpmsg_create_ept(ep, rdev, name, - RPMSG_ADDR_ANY, dest, - endpoint_cb, - rpmsg_service_unbind); -} - -static struct rpmsg_virtio_shm_pool shpool; - -void rpmsg_endpoint_init(void) -{ - int status = 0; - - 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"); - return; - } - 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 = 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].info.vaddr = rx_addr; - rvrings[1].info.num_descs = VRING_SIZE; - rvrings[1].info.align = VRING_ALIGNMENT; - rvrings[1].vq = vq[1]; - - 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); - 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; - } - } - - return 0; -err: - close(cpu_handler_fd); - return -1; -} diff --git a/mcs/openamp_demo_pty_multithread/rpmsg_pty.c b/mcs/openamp_demo_pty_multithread/rpmsg_pty.c deleted file mode 100644 index 57251928fb819e827bcc77d953f3146c637bdd62..0000000000000000000000000000000000000000 --- a/mcs/openamp_demo_pty_multithread/rpmsg_pty.c +++ /dev/null @@ -1,153 +0,0 @@ -#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(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); - } - } -} - -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; -} diff --git a/mcs/openamp_demo_pty_multithread/rpmsg_main.c b/mcs/rpmsg_pty_demo/rpmsg_main.c similarity index 35% rename from mcs/openamp_demo_pty_multithread/rpmsg_main.c rename to mcs/rpmsg_pty_demo/rpmsg_main.c index b8e230baa1a03731d3e25f5c6076178b073bc669..639afbe296cc4828b65b2bbe1ecfec1dd7707081 100644 --- a/mcs/openamp_demo_pty_multithread/rpmsg_main.c +++ b/mcs/rpmsg_pty_demo/rpmsg_main.c @@ -1,44 +1,21 @@ #include #include #include -#include #include #include #include -#include - -#include "rpmsg-internal.h" +#include "remoteproc_module.h" +#include "virtio_module.h" +#include "rpmsg_pty.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; 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,57 @@ int load_bin(void) return 0; } -static struct remoteproc *rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) +int rpmsg_app_master(void) { - 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; -} + pthread_t tida, tidb, tidc; + void *reta, *retb, *retc; -static int rproc_start(struct remoteproc *rproc) -{ - int cpu_handler_fd; - int ret; - char on[BOOTCMD_MAXSIZE]; + printf("Multi-thread processing user requests...\n"); - (void)snprintf(on, sizeof(on), "%s%s%s", cpu_id, "@", boot_address); + /* userA: user shell, open with screen */ + if (pthread_create(&tida, NULL, shell_user, NULL) < 0) { + perror("userA pthread_create"); + return -1; + } +#if 0 + /* userB: dual user shell, open with screen */ + if (pthread_create(&tidb, NULL, shell_user, NULL) < 0) { + perror("userB pthread_create"); + return -1; + } +#endif + /* userC: zephyr log */ + if (pthread_create(&tidc, NULL, log_user, NULL) < 0) { + perror("userC pthread_create"); + return -1; + } - 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; + pthread_join(tida, &reta); + if ((long)reta) { + printf("userA return failed: %ld", (long)reta); + } +#if 0 + pthread_join(tidb, &retb); + if ((long)retb) { + printf("userB return failed: %ld", (long)retb); + } +#endif + pthread_join(tidc, &retc); + if ((long)retc) { + printf("userC return failed: %ld", (long)retc); } - 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 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 + struct remoteproc rproc; + struct rproc_priv args = { &rproc, 1 }; + struct remoteproc *rproc_inst; + while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { switch (opt) { case 'c': @@ -162,55 +116,42 @@ int main(int argc, char **argv) break; } } -#endif - cpu_id = "3"; - boot_address = "0x7a000ffc"; - target_binfile = "zephyr.bin"; - target_binaddr = "0x7a000000"; + args.cpu_id = strtol(cpu_id, NULL, 10); + args.boot_address = strtol(boot_address, NULL, 16); + rproc_inst = platform_create_proc(&args); + if (!rproc_inst) { + 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_inst); + 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); /* wait for zephyr booting */ + virtio_init(); + + ret = rpmsg_app_master(); + if (ret) { + printf("openamp demo run failed\n"); + return ret; } + printf("\nOpenAMP demo ended.\n"); + if (io) + free(io); + remoteproc_stop(rproc_inst); + rproc_inst->state = RPROC_OFFLINE; + remoteproc_remove(rproc_inst); + return 0; } diff --git a/mcs/rpmsg_pty_demo/zephyr.bin b/mcs/rpmsg_pty_demo/zephyr.bin new file mode 100644 index 0000000000000000000000000000000000000000..3d3f85216423e18b262099e489f35b5fc8ea9969 Binary files /dev/null and b/mcs/rpmsg_pty_demo/zephyr.bin differ diff --git a/mcs/zephyr/zephyr.elf b/mcs/zephyr/zephyr.elf deleted file mode 100755 index c7145bc26b204e3f2a0193a7a37ee02490b76c85..0000000000000000000000000000000000000000 Binary files a/mcs/zephyr/zephyr.elf and /dev/null differ