From bf03434ccce4985433f67638cc8bf351a97f6a58 Mon Sep 17 00:00:00 2001 From: Wendy Liang Date: Thu, 14 Jun 2018 06:23:06 -0700 Subject: [PATCH] apps: copy echo_test to examples/echo Move the echo_test to examples will add a messaging test to implement a more complete messaging verification. Signed-off-by: Wendy Liang --- apps/examples/CMakeLists.txt | 1 + apps/examples/echo/CMakeLists.txt | 46 +++++++ apps/examples/echo/rpmsg-echo.c | 116 +++++++++++++++++ apps/examples/echo/rpmsg-ping.c | 208 ++++++++++++++++++++++++++++++ 4 files changed, 371 insertions(+) create mode 100644 apps/examples/echo/CMakeLists.txt create mode 100644 apps/examples/echo/rpmsg-echo.c create mode 100644 apps/examples/echo/rpmsg-ping.c diff --git a/apps/examples/CMakeLists.txt b/apps/examples/CMakeLists.txt index ad47273..dff652c 100644 --- a/apps/examples/CMakeLists.txt +++ b/apps/examples/CMakeLists.txt @@ -1,6 +1,7 @@ option (WITH_LOAD_FW "Include loading firmware example" OFF) +add_subdirectory (echo) add_subdirectory (matrix_multiply) if (WITH_LOAD_FW) add_subdirectory (load_fw) diff --git a/apps/examples/echo/CMakeLists.txt b/apps/examples/echo/CMakeLists.txt new file mode 100644 index 0000000..f01de6e --- /dev/null +++ b/apps/examples/echo/CMakeLists.txt @@ -0,0 +1,46 @@ + +set (_cflags "${CMAKE_C_FLAGS} ${APP_EXTRA_C_FLAGS} -fdata-sections -ffunction-sections") +set (_fw_dir "${APPS_SHARE_DIR}") + +collector_list (_list PROJECT_INC_DIRS) +collector_list (_app_list APP_INC_DIRS) +include_directories (${_list} ${_app_list} ${CMAKE_CURRENT_SOURCE_DIR}) + +collector_list (_list PROJECT_LIB_DIRS) +collector_list (_app_list APP_LIB_DIRS) +link_directories (${_list} ${_app_list}) + +get_property (_linker_opt GLOBAL PROPERTY APP_LINKER_OPT) +collector_list (_deps PROJECT_LIB_DEPS) + +set (OPENAMP_LIB open_amp) + +foreach (_app rpmsg-echo-ping rpmsg-echo) + collector_list (_sources APP_COMMON_SOURCES) + if (${_app} STREQUAL "rpmsg-echo-ping") + list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg-ping.c") + elseif (${_app} STREQUAL "rpmsg-echo") + list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg-echo.c") + endif (${_app} STREQUAL "rpmsg-echo-ping") + + if (WITH_SHARED_LIB) + add_executable (${_app}-shared ${_sources}) + target_link_libraries (${_app}-shared ${OPENAMP_LIB}-shared ${_deps}) + install (TARGETS ${_app}-shared RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif (WITH_SHARED_LIB) + + if (WITH_STATIC_LIB) + if (${PROJECT_SYSTEM} STREQUAL "linux") + add_executable (${_app}-static ${_sources}) + target_link_libraries (${_app}-static ${OPENAMP_LIB}-static ${_deps}) + install (TARGETS ${_app}-static RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + else (${PROJECT_SYSTEM}) + add_executable (${_app}.out ${_sources}) + set_source_files_properties(${_sources} PROPERTIES COMPILE_FLAGS "${_cflags}") + + target_link_libraries(${_app}.out -Wl,-Map=${_app}.map -Wl,--gc-sections ${_linker_opt} -Wl,--start-group ${OPENAMP_LIB}-static ${_deps} -Wl,--end-group) + + install (TARGETS ${_app}.out RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif (${PROJECT_SYSTEM} STREQUAL "linux" ) + endif (WITH_STATIC_LIB) +endforeach(_app) diff --git a/apps/examples/echo/rpmsg-echo.c b/apps/examples/echo/rpmsg-echo.c new file mode 100644 index 0000000..0bf32a2 --- /dev/null +++ b/apps/examples/echo/rpmsg-echo.c @@ -0,0 +1,116 @@ +/* This is a sample demonstration application that showcases usage of rpmsg +This application is meant to run on the remote CPU running baremetal code. +This application echoes back data that was sent to it by the master core. */ + +#include +#include +#include +#include "platform_info.h" + +#define SHUTDOWN_MSG 0xEF56A55A + +#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__) +//#define LPRINTF(format, ...) +#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__) + +static struct rpmsg_endpoint lept; +static int ept_deleted = 0; + +/* External functions */ +extern int init_system(void); +extern void cleanup_system(void); + +/*-----------------------------------------------------------------------------* + * RPMSG endpoint callbacks + *-----------------------------------------------------------------------------*/ +static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, + uint32_t src, void *priv) +{ + (void)priv; + (void)src; + + /* On reception of a shutdown we signal the application to terminate */ + if ((*(unsigned int *)data) == SHUTDOWN_MSG) { + LPRINTF("shutdown message is received.\n"); + rpmsg_destroy_ept(ept); + return RPMSG_SUCCESS; + } + + /* Send data back to master */ + if (rpmsg_send(ept, data, len) < 0) { + LPERROR("rpmsg_send failed\n"); + } + return RPMSG_SUCCESS; +} + +static void rpmsg_endpoint_destroy(struct rpmsg_endpoint *ept) +{ + (void)ept; + LPRINTF("Endpoint is destroyed\n"); + ept_deleted = 1; +} + +/*-----------------------------------------------------------------------------* + * Application + *-----------------------------------------------------------------------------*/ +int app(struct rpmsg_device *rdev, void *priv) +{ + int ret; + + /* Initialize RPMSG framework */ + LPRINTF("Try to create rpmsg endpoint.\n"); + + ret = rpmsg_create_ept(&lept, rdev, RPMSG_CHAN_NAME, 0, RPMSG_ADDR_ANY, + rpmsg_endpoint_cb, rpmsg_endpoint_destroy); + if (ret) { + LPERROR("Failed to create endpoint.\n"); + return -1; + } + + LPRINTF("Successfully created rpmsg endpoint.\n"); + while(1) { + platform_poll(priv); + /* we got a shutdown request, exit */ + if (ept_deleted) { + break; + } + } + + return 0; +} + +/*-----------------------------------------------------------------------------* + * Application entry point + *-----------------------------------------------------------------------------*/ +int main(int argc, char *argv[]) +{ + void *platform; + struct rpmsg_device *rpdev; + int ret; + + LPRINTF("Starting application...\n"); + + /* Initialize platform */ + ret = platform_init(argc, argv, &platform); + if (ret) { + LPERROR("Failed to initialize platform.\n"); + ret = -1; + } else { + rpdev = platform_create_rpmsg_vdev(platform, 0, + VIRTIO_DEV_SLAVE, + NULL, NULL); + if (!rpdev) { + LPERROR("Failed to create rpmsg virtio device.\n"); + ret = -1; + } else { + app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev); + ret = 0; + } + } + + LPRINTF("Stopping application...\n"); + platform_cleanup(platform); + + return ret; +} diff --git a/apps/examples/echo/rpmsg-ping.c b/apps/examples/echo/rpmsg-ping.c new file mode 100644 index 0000000..d9ea36a --- /dev/null +++ b/apps/examples/echo/rpmsg-ping.c @@ -0,0 +1,208 @@ +/* This is a sample demonstration application that showcases usage of rpmsg +This application is meant to run on the remote CPU running baremetal code. +This application echoes back data that was sent to it by the master core. */ + +#include +#include +#include +#include +#include +#include +#include "platform_info.h" + +#define SHUTDOWN_MSG 0xEF56A55A +#define APP_EPT_ADDR 0 +#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__) +#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__) + +struct _payload { + unsigned long num; + unsigned long size; + unsigned char data[]; +}; + +static int err_cnt; + +#define PAYLOAD_MIN_SIZE 1 + +/* Globals */ +static struct rpmsg_endpoint lept; +static struct _payload *i_payload; +static int rnum = 0; +static int err_cnt = 0; +static int ept_deleted = 0; + +/* External functions */ +extern int init_system(); +extern void cleanup_system(); + +/*-----------------------------------------------------------------------------* + * RPMSG endpoint callbacks + *-----------------------------------------------------------------------------*/ +static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len, + uint32_t src, void *priv) +{ + int i; + struct _payload *r_payload = (struct _payload *)data; + + (void)ept; + (void)src; + (void)priv; + LPRINTF(" received payload number %lu of size %d \r\n", + r_payload->num, len); + + if (r_payload->size == 0) { + LPERROR(" Invalid size of package is received.\n"); + err_cnt++; + return RPMSG_SUCCESS; + } + /* Validate data buffer integrity. */ + for (i = 0; i < (int)r_payload->size; i++) { + if (r_payload->data[i] != 0xA5) { + LPRINTF("Data corruption at index %d\n", i); + err_cnt++; + break; + } + } + rnum = r_payload->num + 1; + return RPMSG_SUCCESS; +} + +static void rpmsg_endpoint_destroy(struct rpmsg_endpoint *ept) +{ + (void)ept; + LPRINTF("Endpoint is destroyed\n"); + ept_deleted = 1; +} + +static void rpmsg_new_endpoint_cb(struct rpmsg_device *rdev, const char *name, + uint32_t src) +{ + LPRINTF("new endpoint notification is received.\n"); + if (strcmp(name, RPMSG_CHAN_NAME)) + LPERROR("Unexpected name service %s.\n", name); + else + (void)rpmsg_create_ept(&lept, rdev, RPMSG_CHAN_NAME, + APP_EPT_ADDR, src, + rpmsg_endpoint_cb, + rpmsg_endpoint_destroy); + +} + +/*-----------------------------------------------------------------------------* + * Application + *-----------------------------------------------------------------------------*/ +int app (struct rpmsg_device *rdev, void *priv) +{ + int ret; + int shutdown_msg = SHUTDOWN_MSG; + int i; + int size, max_size, num_payloads; + int expect_rnum = 0; + + LPRINTF(" 1 - Send data to remote core, retrieve the echo"); + LPRINTF(" and validate its integrity ..\n"); + + max_size = rpmsg_virtio_get_buffer_size(rdev); + if (max_size < 0) { + LPERROR("No avaiable buffer size.\n"); + return -1; + } + max_size -= sizeof(struct _payload); + num_payloads = max_size - PAYLOAD_MIN_SIZE + 1; + i_payload = + (struct _payload *)metal_allocate_memory(2 * sizeof(unsigned long) + + max_size); + + if (!i_payload) { + LPERROR("memory allocation failed.\n"); + return -1; + } + + /* Create RPMsg endpoint */ + ret = rpmsg_create_ept(&lept, rdev, RPMSG_CHAN_NAME, APP_EPT_ADDR, + RPMSG_ADDR_ANY, + rpmsg_endpoint_cb, rpmsg_endpoint_destroy); + + if (ret) { + LPERROR("Failed to create RPMsg endpoint.\n"); + return ret; + } + + while (!is_rpmsg_ept_ready(&lept)) + platform_poll(priv); + + LPRINTF("RPMSG endpoint is binded with remote.\n"); + for (i = 0, size = PAYLOAD_MIN_SIZE; i < num_payloads; i++, size++) { + i_payload->num = i; + i_payload->size = size; + + /* Mark the data buffer. */ + memset(&(i_payload->data[0]), 0xA5, size); + + LPRINTF("sending payload number %lu of size %d\n", + i_payload->num, (2 * sizeof(unsigned long)) + size); + + ret = rpmsg_send(&lept, i_payload, + (2 * sizeof(unsigned long)) + size); + + if (ret < 0) { + LPERROR("Failed to send data...\n"); + break; + } + LPRINTF("echo test: sent : %d\n", + (2 * sizeof(unsigned long)) + size); + + expect_rnum++; + do { + platform_poll(priv); + } while ((rnum < expect_rnum) && !err_cnt); + + } + + LPRINTF("**********************************\n"); + LPRINTF(" Test Results: Error count = %d \n", err_cnt); + LPRINTF("**********************************\n"); + /* Send shutdown message to remote */ + rpmsg_send(&lept, &shutdown_msg, sizeof(int)); + rpmsg_destroy_ept(&lept); + while(!ept_deleted) + platform_poll(priv); + LPRINTF("Quitting application .. Echo test end\n"); + + metal_free_memory(i_payload); + return 0; +} + +int main(int argc, char *argv[]) +{ + void *platform; + struct rpmsg_device *rpdev; + int ret; + + /* Initialize platform */ + ret = platform_init(argc, argv, &platform); + if (ret) { + LPERROR("Failed to initialize platform.\n"); + ret = -1; + } else { + rpdev = platform_create_rpmsg_vdev(platform, 0, + VIRTIO_DEV_MASTER, + NULL, + rpmsg_new_endpoint_cb); + if (!rpdev) { + LPERROR("Failed to create rpmsg virtio device.\n"); + ret = -1; + } else { + app(rpdev, platform); + platform_release_rpmsg_vdev(rpdev); + ret = 0; + } + } + + LPRINTF("Stopping application...\n"); + platform_cleanup(platform); + + return ret; +} +