diff --git a/mcs/CMakeLists.txt b/mcs/CMakeLists.txt index c5c0241f82bf95d2f3c1107f9a236f6918e610b8..a23538dad6ef624a7496a0c0dcc0467ecbf6b972 100644 --- a/mcs/CMakeLists.txt +++ b/mcs/CMakeLists.txt @@ -13,45 +13,32 @@ set(SHARED_LINK_LIBS $ENV{SDKTARGETSYSROOT}/lib64/libsysfs.so ) -add_library(remoteproc STATIC +add_library(openamp STATIC + ./modules/openamp_module.c ./modules/remoteproc_module.c -) -target_link_libraries(remoteproc - ${SHARED_LINK_LIBS} -) - -add_library(virtio STATIC ./modules/virtio_module.c + ./modules/rpmsg_module.c ) -target_link_libraries(virtio +target_link_libraries(openamp ${SHARED_LINK_LIBS} ) -add_library(pty STATIC - ./modules/rpmsg_pty.c -) - -set(INC_PATH - $ENV{SDKTARGETSYSROOT}/usr/include - ./modules +set(SRC_FILE + ./${DEMO_TARGET}/rpmsg_main.c ) 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") + list(APPEND SRC_FILE "./${DEMO_TARGET}/rpmsg_pty.c") else() message(FATAL_ERROR "DEMO_TARGET: choose a target to build. - [openamp_demo|rpmsg_pty_demo]") #rsc_table_demo|cyclitest_demo|rpmsg_service_demo + [openamp_demo|rpmsg_pty_demo]") #rsc_table_demo|cyclitest_demo|rpmsg_service_demo|gdb_demo endif() -include_directories(${INC_PATH}) +include_directories( + $ENV{SDKTARGETSYSROOT}/usr/include + ./modules + ./${DEMO_TARGET} +) add_executable(rpmsg_main ${SRC_FILE}) -target_link_libraries(rpmsg_main - ${SHARED_LINK_LIBS} - ${STATIC_LINK_LIBS} -) \ No newline at end of file +target_link_libraries(rpmsg_main openamp) \ No newline at end of file diff --git a/mcs/README.md b/mcs/README.md index f2387dc2ad9a251a75d4330f96e7e9279a36ebaf..fd83a2050c9d57928256937ce21e6fc6c0347ced 100644 --- a/mcs/README.md +++ b/mcs/README.md @@ -85,3 +85,13 @@ OpenAMP包括如下三大重要组件: 此处定义Client OS起始地址为0x7a000000,启动地址为0x7a000ffc,Client OS镜像路径为/tmp/zephyr.bin。 +#### 用户开发 +参考demo实现流程,当前提供了多个API,包含在libopenamp.a中,供用户使用和二次开发,用户无需感知openamp实现细节。 + +1. 调用openamp_init,初始化remoteproc、virtio、rpmsg。 + +2. 调用bringup_endpoint,启动endpoint动态配对,Linux端与Client OS建立配对的endpoint,供消息收发使用。 + +3. 调用receive_message、send_message收发消息。 + +4. 调用openamp_deinit,释放openamp资源。 \ No newline at end of file diff --git a/mcs/modules/openamp_module.c b/mcs/modules/openamp_module.c new file mode 100644 index 0000000000000000000000000000000000000000..e23a85b8d366c8f87172c870e495edc184aca256 --- /dev/null +++ b/mcs/modules/openamp_module.c @@ -0,0 +1,77 @@ +#include +#include "openamp_module.h" + +#define MAX_BIN_BUFLEN (10 * 1024 * 1024) + +static int load_bin(void) +{ + 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); + } + + bin_buffer = (void *)malloc(MAX_BIN_BUFLEN); + if (!bin_buffer) { + printf("malloc bin_buffer failed\n"); + exit(-1); + } + + bin_size = read(bin_fd, bin_buffer, MAX_BIN_BUFLEN); + if (bin_size == 0) { + printf("read bin file failed\n"); + exit(-1); + } + + 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; +} + +int openamp_init(void) +{ + int ret; + struct remoteproc *rproc; + + rproc = create_remoteproc(); + if (!rproc) { + printf("create remoteproc failed\n"); + return -1; + } + + ret = load_bin(); + if (ret) { + printf("failed to load client os\n"); + return ret; + } + + ret = remoteproc_start(rproc); + if (ret) { + printf("start processor failed\n"); + return ret; + } + + sleep(5); /* wait for zephyr booting */ + virtio_init(); + + return 0; +} + +int openamp_deinit(void) +{ + 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/modules/openamp_module.h b/mcs/modules/openamp_module.h new file mode 100644 index 0000000000000000000000000000000000000000..f5be2bf02617125bf4119a1fde5fb5046da025b7 --- /dev/null +++ b/mcs/modules/openamp_module.h @@ -0,0 +1,15 @@ +#ifndef OPENAMP_MODULE_H +#define OPENAMP_MODULE_H + +#include +#include "remoteproc_module.h" +#include "virtio_module.h" +#include "rpmsg_module.h" + +extern char *target_binfile; +extern char *target_binaddr; + +int openamp_init(void); +int openamp_deinit(void); + +#endif \ No newline at end of file diff --git a/mcs/modules/remoteproc_module.c b/mcs/modules/remoteproc_module.c index e12f5002beb997cf3e09b1e14e5dcf7e2f90e757..f6efca0bec4944d2df53540c9d2b67a96c2aea94 100644 --- a/mcs/modules/remoteproc_module.c +++ b/mcs/modules/remoteproc_module.c @@ -1,11 +1,19 @@ #include #include #include -#include #include "remoteproc_module.h" #define BOOTCMD_MAXSIZE 100 +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) */ +}; + +struct remoteproc rproc_inst; + static struct remoteproc *rproc_init(struct remoteproc *rproc, const struct remoteproc_ops *ops, void *args) { @@ -68,10 +76,16 @@ const struct remoteproc_ops rproc_ops = { .stop = rproc_stop, }; -/* create remoteproc */ -struct remoteproc *platform_create_proc(struct rproc_priv *args) +struct remoteproc *create_remoteproc(void) { - struct remoteproc *rproc = remoteproc_init(args->rproc, &rproc_ops, args); + struct remoteproc *rproc; + struct rproc_priv args; + + args.rproc = &rproc_inst; + args.idx = 1; + args.cpu_id = strtol(cpu_id, NULL, 10); + args.boot_address = strtol(boot_address, NULL, 16); + rproc = remoteproc_init(&rproc_inst, &rproc_ops, &args); if (!rproc) return NULL; diff --git a/mcs/modules/remoteproc_module.h b/mcs/modules/remoteproc_module.h index d8b51b32649bf3d4540811d83059f429ffea3a77..7a54f471d7a11276856fd54d35293b7eb26075e9 100644 --- a/mcs/modules/remoteproc_module.h +++ b/mcs/modules/remoteproc_module.h @@ -5,15 +5,8 @@ #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); +struct remoteproc *create_remoteproc(void); /* start remoteproc: refet to @@ -30,4 +23,8 @@ struct remoteproc *platform_create_proc(struct rproc_priv *args); int remoteproc_remove(struct remoteproc *rproc); */ +extern char *cpu_id; +extern char *boot_address; +extern struct remoteproc rproc_inst; + #endif \ No newline at end of file diff --git a/mcs/modules/rpmsg_module.c b/mcs/modules/rpmsg_module.c new file mode 100644 index 0000000000000000000000000000000000000000..5078f14e28267095cc4ee72517c546967fd51634 --- /dev/null +++ b/mcs/modules/rpmsg_module.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include "virtio_module.h" +#include "rpmsg_module.h" + +static unsigned char received_data[2048] = {0}; +static unsigned int received_len = 0; +struct rpmsg_endpoint *ep; /* current using endpoint */ + +void bringup_endpoint(struct rpmsg_endpoint *ept_inst) +{ + unsigned char message[100]; + int len; + + ep = ept_inst; + (void)receive_message(message, sizeof(message), &len); /* name service: endpoint matching */ +} + +int endpoint_cb(struct rpmsg_endpoint *ept, void *data, + size_t len, uint32_t src, void *priv) +{ + memcpy(received_data + received_len, data, len); + received_len += len; + + return RPMSG_SUCCESS; +} + +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); +} + +int receive_message(unsigned char *message, int message_len, int *real_len) +{ + int ret; + int cpu_handler_fd; + struct pollfd fds; + + cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + if (cpu_handler_fd < 0) { + printf("receive_message: open %s failed.\n", DEV_CLIENT_OS_AGENT); + return cpu_handler_fd; + } + + fds.fd = cpu_handler_fd; + fds.events = POLLIN; + + /* clear the receive buffer */ + memset(received_data, 0, sizeof(received_data)); + received_len = 0; + + while (1) { + ret = poll(&fds, 1, 100); /* 100ms timeout */ + if (ret < 0) { + printf("receive_message: poll failed.\n"); + *real_len = 0; + goto _cleanup; + } + + if (ret == 0) { + break; + } + + if (fds.revents & POLLIN) { + virtqueue_notification(vq[0]); /* will call endpoint_cb */ + } + } + + if (received_len > message_len) { + printf("receive_message: buffer is too small.\n"); + *real_len = 0; + ret = -1; + goto _cleanup; + } + + memset(message, 0, message_len); + memcpy(message, received_data, received_len); + *real_len = received_len; + +_cleanup: + close(cpu_handler_fd); + return ret; +} + +int send_message(unsigned char *message, int len) +{ + return rpmsg_send(ep, message, len); +} diff --git a/mcs/modules/rpmsg_module.h b/mcs/modules/rpmsg_module.h new file mode 100644 index 0000000000000000000000000000000000000000..ddeee24cf0ec818614d53b19b929e96cde959469 --- /dev/null +++ b/mcs/modules/rpmsg_module.h @@ -0,0 +1,20 @@ +#ifndef RPMSG_MODULE_H +#define RPMSG_MODULE_H + +#include + +#define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" + +/* callback of ns */ +void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest); + +/* bringup a endpoint, receive_message and send_message are based on this */ +void bringup_endpoint(struct rpmsg_endpoint *ept_inst); + +/* message standard receive interface */ +int receive_message(unsigned char *message, int message_len, int *real_len); + +/* message standard send interface */ +int send_message(unsigned char *message, int len); + +#endif \ No newline at end of file diff --git a/mcs/modules/virtio_module.c b/mcs/modules/virtio_module.c index 6a440270fc8735877ac863ceea482daac8eeb793..418aaedbbe8a8a9abdc101731e32e5e7adf6af95 100644 --- a/mcs/modules/virtio_module.c +++ b/mcs/modules/virtio_module.c @@ -1,10 +1,8 @@ #include -#include +#include #include -#include #include -#include -#include +#include "rpmsg_module.h" #include "virtio_module.h" static struct virtio_vring_info rvrings[2] = { @@ -17,12 +15,10 @@ static struct virtio_vring_info rvrings[2] = { }; static int g_memfd; -static unsigned char received_data[2048] = {0}; -static unsigned int received_len = 0; static struct virtio_device vdev; static struct rpmsg_virtio_device rvdev; struct metal_io_region *io; -static struct virtqueue *vq[2]; +struct virtqueue *vq[2]; static void *tx_addr, *rx_addr, *shm_start_addr; static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; @@ -72,100 +68,13 @@ struct virtio_dispatch dispatch = { .notify = virtio_notify, }; -int endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - memcpy(received_data + received_len, data, len); - received_len += len; - - 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); -} - -/* message standard receive interface */ -int receive_message(unsigned char *message, int message_len, int *real_len) -{ - int ret; - int cpu_handler_fd; - struct pollfd fds; - - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("receive_message: open %s failed.\n", DEV_CLIENT_OS_AGENT); - return cpu_handler_fd; - } - - fds.fd = cpu_handler_fd; - fds.events = POLLIN; - - /* clear the receive buffer */ - memset(received_data, 0, sizeof(received_data)); - received_len = 0; - - while (1) { - ret = poll(&fds, 1, 100); /* 100ms timeout */ - if (ret < 0) { - printf("receive_message: poll failed.\n"); - *real_len = 0; - goto _cleanup; - } - - if (ret == 0) { - break; - } - - if (fds.revents & POLLIN) { - virtqueue_notification(vq[0]); /* will call endpoint_cb */ - } - } - - if (received_len > message_len) { - printf("receive_message: buffer is too small.\n"); - *real_len = 0; - ret = -1; - goto _cleanup; - } - - memset(message, 0, message_len); - memcpy(message, received_data, received_len); - *real_len = received_len; - -_cleanup: - close(cpu_handler_fd); - return ret; -} - -/* message standard send interface */ -int send_message(unsigned char *message, int len) -{ - return rpmsg_send(ep, message, len); -} - static struct rpmsg_virtio_shm_pool shpool; void virtio_init(void) { int status = 0; - char message[100] = {0}; - int len; - printf("Initialize the virtio, virtqueue, return rpmsg device...\n"); + printf("\nInitialize the virtio, virtqueue and 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); @@ -218,9 +127,4 @@ void virtio_init(void) free(io); return; } - - /* Since we are using name service, we need to wait for a response - * from NS setup and than we need to process it - */ - (void)receive_message(message, sizeof(message), &len); } diff --git a/mcs/modules/virtio_module.h b/mcs/modules/virtio_module.h index d4c0d3006b5cf40ea4321971a13be42826c2dafb..8914534436ac242731c2e22664f7801cb36adb98 100644 --- a/mcs/modules/virtio_module.h +++ b/mcs/modules/virtio_module.h @@ -1,6 +1,9 @@ #ifndef VIRTIO_MODULE_H #define VIRTIO_MODULE_H +#include +#include + #define VDEV_START_ADDR 0x70000000 #define VDEV_SIZE 0x30000 @@ -21,10 +24,8 @@ void virtio_init(void); -int receive_message(unsigned char *message, int message_len, int *real_len); -int send_message(unsigned char *message, int len); - extern char *cpu_id; extern struct metal_io_region *io; +extern struct virtqueue *vq[2]; #endif \ No newline at end of file diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c index a0e86dffacd065457c5db013ba47856de729fbcf..857327d264c1d47af1431bf74a2670db883df6f2 100644 --- a/mcs/openamp_demo/rpmsg_main.c +++ b/mcs/openamp_demo/rpmsg_main.c @@ -1,74 +1,38 @@ -#include -#include -#include -#include #include #include -#include "remoteproc_module.h" -#include "virtio_module.h" - -#define MAX_BIN_BUFLEN (10 * 1024 * 1024) +#include "openamp_module.h" char *cpu_id; -static char *boot_address; -static char *target_binfile; -static char *target_binaddr; - -static int load_bin(void) -{ - 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); - } - - bin_buffer = (void *)malloc(MAX_BIN_BUFLEN); - if (!bin_buffer) { - printf("malloc bin_buffer failed\n"); - exit(-1); - } - - bin_size = read(bin_fd, bin_buffer, MAX_BIN_BUFLEN); - if (bin_size == 0) { - printf("read bin file failed\n"); - exit(-1); - } - - 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; -} +char *boot_address; +char *target_binfile; +char *target_binaddr; int rpmsg_app_master(void) { int ret; unsigned int message = 0; int len; + struct rpmsg_endpoint ept_inst; printf("start processing OpenAMP demo...\n"); + /* To ensure thread saftety, endpoint instance should be a local variable */ + bringup_endpoint(&ept_inst); + 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; } - 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); - message++; sleep(1); } @@ -80,9 +44,6 @@ int main(int argc, char **argv) { int ret; int opt; - 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) { @@ -103,41 +64,23 @@ int main(int argc, char **argv) } } - 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 = load_bin(); + ret = openamp_init(); if (ret) { - printf("failed to load client os\n"); + printf("openamp init failed: %d\n", ret); return ret; } - ret = remoteproc_start(rproc_inst); + ret = rpmsg_app_master(); if (ret) { - printf("start processor failed\n"); + printf("rpmsg app master failed: %d\n", ret); return ret; } - sleep(5); /* wait for zephyr booting */ - virtio_init(); - - ret = rpmsg_app_master(); + ret = openamp_deinit(); if (ret) { - printf("openamp demo run failed\n"); + printf("openamp deinit failed: %d\n", ret); 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/rpmsg_main.c b/mcs/rpmsg_pty_demo/rpmsg_main.c index 639afbe296cc4828b65b2bbe1ecfec1dd7707081..0ca15596af26928f2861a82deb4a5ff7503428c2 100644 --- a/mcs/rpmsg_pty_demo/rpmsg_main.c +++ b/mcs/rpmsg_pty_demo/rpmsg_main.c @@ -1,91 +1,27 @@ -#include -#include -#include -#include #include #include -#include "remoteproc_module.h" -#include "virtio_module.h" #include "rpmsg_pty.h" - -#define MAX_BIN_BUFLEN (10 * 1024 * 1024) +#include "openamp_module.h" char *cpu_id; -static char *boot_address; -static char *target_binfile; -static char *target_binaddr; - -static int load_bin(void) -{ - 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); - } - - bin_buffer = (void *)malloc(MAX_BIN_BUFLEN); - if (!bin_buffer) { - printf("malloc bin_buffer failed\n"); - exit(-1); - } - - bin_size = read(bin_fd, bin_buffer, MAX_BIN_BUFLEN); - if (bin_size == 0) { - printf("read bin file failed\n"); - exit(-1); - } - - 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; -} +char *boot_address; +char *target_binfile; +char *target_binaddr; int rpmsg_app_master(void) { pthread_t tida, tidb, tidc; - void *reta, *retb, *retc; printf("Multi-thread processing user requests...\n"); - /* userA: user shell, open with screen */ + /* zephyr 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; - } + pthread_detach(tida); - 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); - } + while (1); return 0; } @@ -94,9 +30,6 @@ int main(int argc, char **argv) { int ret; int opt; - 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) { @@ -117,41 +50,23 @@ int main(int argc, char **argv) } } - 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 = load_bin(); + ret = openamp_init(); if (ret) { - printf("failed to load client os\n"); + printf("openamp init failed: %d\n", ret); return ret; } - ret = remoteproc_start(rproc_inst); + ret = rpmsg_app_master(); if (ret) { - printf("start processor failed\n"); + printf("rpmsg app master failed: %d\n", ret); return ret; } - sleep(5); /* wait for zephyr booting */ - virtio_init(); - - ret = rpmsg_app_master(); + ret = openamp_deinit(); if (ret) { - printf("openamp demo run failed\n"); + printf("openamp deinit failed: %d\n", ret); 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/modules/rpmsg_pty.c b/mcs/rpmsg_pty_demo/rpmsg_pty.c similarity index 63% rename from mcs/modules/rpmsg_pty.c rename to mcs/rpmsg_pty_demo/rpmsg_pty.c index af2750f6a3e49d4c8f446725dc71e3cd8e03bcd1..90e1d8409682cb86cfc8617ed651c440b112d726 100644 --- a/mcs/modules/rpmsg_pty.c +++ b/mcs/rpmsg_pty_demo/rpmsg_pty.c @@ -5,12 +5,12 @@ #include #include #include -#include "virtio_module.h" +#include "openamp_module.h" /* define the keys according to your terminfo */ #define KEY_CTRL_C 3 -void open_pty(int *pfdm, int *pfds) +void open_pty(int *pfdm, int *pfds, const char *pty_name) { int ret; int fdm, fds; @@ -30,7 +30,7 @@ void open_pty(int *pfdm, int *pfds) /* Open the slave side of the PTY */ fds = open(ptsname(fdm), O_RDWR | O_NOCTTY); - printf("open a new terminal, exec zephyr shell: screen %s\n", ptsname(fdm)); + printf("open a new terminal, zephyr %s: screen %s\n", pty_name, ptsname(fdm)); *pfdm = fdm; *pfds = fds; @@ -43,21 +43,25 @@ void *shell_user(void *arg) unsigned char cmd[1]; unsigned char reply[2048]; int reply_len; + struct rpmsg_endpoint ept_inst; - /* open PTY, pts binds to terminal, using screen to open pts */ - open_pty(&fdm, &fds); + /* To ensure thread saftety, endpoint instance should be defined in thread */ + bringup_endpoint(&ept_inst); + + open_pty(&fdm, &fds, "shell"); while (1) { - memset(cmd, 0, 1); ret = read(fdm, cmd, 1); /* get command from ptmx */ if (ret < 0) { printf("shell_user: get from ptmx failed: %d\n", ret); return (void*)-1; } - if (cmd[0] == KEY_CTRL_C) /* special key: ctrl+c */ - //pthread_exit(NULL); - return (void*)0; + if (cmd[0] == KEY_CTRL_C) { /* special key: ctrl+c */ + close(fds); + close(fdm); + return (void*)0; /* exit this thread, the same as pthread_exit */ + } ret = send_message(cmd, 1); /* send command to rtos */ if (ret < 0) { @@ -81,6 +85,37 @@ void *shell_user(void *arg) return (void*)0; } +void *console_user(void *arg) +{ + int ret; + int fdm, fds; + unsigned char reply[2048]; + int reply_len; + struct rpmsg_endpoint ept_inst; + + /* To ensure thread saftety, endpoint instance should be defined in thread */ + bringup_endpoint(&ept_inst); + + /* open PTY, pts binds to terminal, using screen to open pts */ + open_pty(&fdm, &fds, "console"); + + while (1) { + ret = receive_message(reply, sizeof(reply), &reply_len); /* receive reply from rtos */ + if (ret < 0) { + printf("shell_user: receive_message failed: %d\n", ret); + return (void*)-1; + } + + ret = write(fdm, reply, reply_len); /* send reply to ptmx */ + if (ret < 0) { + printf("shell_user: write to ptmx(%s) failed: %d\n", reply, ret); + return (void*)-1; + } + } + + return (void*)0; +} + void *log_user(void *arg) { int ret; @@ -88,6 +123,10 @@ void *log_user(void *arg) unsigned char log[2048] = {0}; int log_len; const char *log_file = "/tmp/zephyr_log.txt"; + struct rpmsg_endpoint ept_inst; + + /* To ensure thread saftety, endpoint instance should be defined in thread */ + bringup_endpoint(&ept_inst); ret = receive_message(log, sizeof(log), &log_len); /* receive log from rtos */ if (ret < 0) { diff --git a/mcs/modules/rpmsg_pty.h b/mcs/rpmsg_pty_demo/rpmsg_pty.h similarity index 77% rename from mcs/modules/rpmsg_pty.h rename to mcs/rpmsg_pty_demo/rpmsg_pty.h index 59da943b04ca94d5ee36ae2c3eba7a843f04bd50..b3f3399e1fecbf6e4e7e2799040618728eb9b602 100644 --- a/mcs/modules/rpmsg_pty.h +++ b/mcs/rpmsg_pty_demo/rpmsg_pty.h @@ -2,6 +2,7 @@ #define RPMSG_PTY_H void *shell_user(void *arg); +void *console_user(void *arg); void *log_user(void *arg); #endif \ No newline at end of file