建立工程,成功创建两个虚拟串口
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
|
||||
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-sample-echo rpmsg-sample-ping)
|
||||
collector_list (_sources APP_COMMON_SOURCES)
|
||||
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/${_app}.c")
|
||||
|
||||
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)
|
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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 allows to check the compatibility with linux OS running on
|
||||
* the master CPU. For this it echo MSG_LIMIT time message sent by the rpmsg
|
||||
* sample client available in linux kernel distribution.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openamp/open_amp.h>
|
||||
#include <metal/alloc.h>
|
||||
#include "platform_info.h"
|
||||
|
||||
#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
|
||||
|
||||
|
||||
#define RPMSG_SERV_NAME "rpmsg-client-sample"
|
||||
#define MSG_LIMIT 100
|
||||
|
||||
static struct rpmsg_endpoint lept;
|
||||
static int shutdown_req = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------------*
|
||||
* 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;
|
||||
static uint32_t count = 0;
|
||||
char payload[RPMSG_BUFFER_SIZE];
|
||||
|
||||
/* Send data back MSG_LIMIT time to master */
|
||||
memset(payload, 0, RPMSG_BUFFER_SIZE);
|
||||
memcpy(payload, data, len);
|
||||
if (++count <= MSG_LIMIT) {
|
||||
LPRINTF("echo message number %u: %s\n",
|
||||
(unsigned int)count, payload);
|
||||
if (rpmsg_send(ept, (char *)data, len) < 0) {
|
||||
LPERROR("rpmsg_send failed\n");
|
||||
goto destroy_ept;
|
||||
}
|
||||
|
||||
if (count == MSG_LIMIT) {
|
||||
goto destroy_ept;
|
||||
}
|
||||
}
|
||||
return RPMSG_SUCCESS;
|
||||
|
||||
destroy_ept:
|
||||
shutdown_req = 1;
|
||||
return RPMSG_SUCCESS;
|
||||
}
|
||||
|
||||
static void rpmsg_service_unbind(struct rpmsg_endpoint *ept)
|
||||
{
|
||||
(void)ept;
|
||||
LPRINTF("unexpected Remote endpoint destroy\n");
|
||||
shutdown_req = 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_SERV_NAME, 0, RPMSG_ADDR_ANY,
|
||||
rpmsg_endpoint_cb, rpmsg_service_unbind);
|
||||
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 (shutdown_req) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rpmsg_destroy_ept(&lept);
|
||||
|
||||
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;
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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 simulate linux sample rpmsg driver. For this it echo 100
|
||||
* time message sent by the rpmsg sample client available in linux kernel
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <openamp/open_amp.h>
|
||||
#include <metal/alloc.h>
|
||||
#include "platform_info.h"
|
||||
|
||||
#define RPMSG_SERV_NAME "rpmsg-client-sample"
|
||||
|
||||
#define HELLO_MSG "hello world!"
|
||||
#define BYE_MSG "goodbye!"
|
||||
#define MSG_LIMIT 100
|
||||
|
||||
#define APP_EPT_ADDR 0
|
||||
#define LPRINTF(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
|
||||
|
||||
static int err_cnt;
|
||||
|
||||
|
||||
/* Globals */
|
||||
static struct rpmsg_endpoint lept;
|
||||
static int rnum = 0;
|
||||
static int err_cnt = 0;
|
||||
static int ept_deleted = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------------*
|
||||
* RPMSG endpoint callbacks
|
||||
*-----------------------------------------------------------------------------*/
|
||||
static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len,
|
||||
uint32_t src, void *priv)
|
||||
{
|
||||
char payload[RPMSG_BUFFER_SIZE];
|
||||
char seed[20];
|
||||
|
||||
(void)ept;
|
||||
(void)src;
|
||||
(void)priv;
|
||||
|
||||
memset(payload, 0, RPMSG_BUFFER_SIZE);
|
||||
memcpy(payload, data, len);
|
||||
LPRINTF("received message %d: %s of size %lu \r\n",
|
||||
rnum + 1, payload, (unsigned long)len);
|
||||
|
||||
if (rnum == (MSG_LIMIT - 1))
|
||||
sprintf (seed, "%s", BYE_MSG);
|
||||
else
|
||||
sprintf (seed, "%s", HELLO_MSG);
|
||||
|
||||
LPRINTF(" seed %s: \r\n", seed);
|
||||
|
||||
if (strncmp(payload, seed, len)) {
|
||||
LPERROR(" Invalid message is received.\n");
|
||||
err_cnt++;
|
||||
return RPMSG_SUCCESS;
|
||||
}
|
||||
LPRINTF(" rnum %d: \r\n", rnum);
|
||||
rnum++;
|
||||
|
||||
return RPMSG_SUCCESS;
|
||||
}
|
||||
|
||||
static void rpmsg_service_unbind(struct rpmsg_endpoint *ept)
|
||||
{
|
||||
(void)ept;
|
||||
rpmsg_destroy_ept(&lept);
|
||||
LPRINTF("echo test: service is destroyed\n");
|
||||
ept_deleted = 1;
|
||||
}
|
||||
|
||||
static void rpmsg_name_service_bind_cb(struct rpmsg_device *rdev,
|
||||
const char *name, uint32_t dest)
|
||||
{
|
||||
LPRINTF("new endpoint notification is received.\n");
|
||||
if (strcmp(name, RPMSG_SERV_NAME))
|
||||
LPERROR("Unexpected name service %s.\n", name);
|
||||
else
|
||||
(void)rpmsg_create_ept(&lept, rdev, RPMSG_SERV_NAME,
|
||||
APP_EPT_ADDR, dest,
|
||||
rpmsg_endpoint_cb,
|
||||
rpmsg_service_unbind);
|
||||
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*
|
||||
* Application
|
||||
*-----------------------------------------------------------------------------*/
|
||||
int app(struct rpmsg_device *rdev, void *priv)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
LPRINTF(" 1 - Send data to remote core, retrieve the echo");
|
||||
LPRINTF(" and validate its integrity ..\n");
|
||||
|
||||
/* Create RPMsg endpoint */
|
||||
ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERV_NAME, APP_EPT_ADDR,
|
||||
RPMSG_ADDR_ANY,
|
||||
rpmsg_endpoint_cb, rpmsg_service_unbind);
|
||||
|
||||
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 = 1; i <= MSG_LIMIT; i++) {
|
||||
|
||||
|
||||
if (i < MSG_LIMIT)
|
||||
ret = rpmsg_send(&lept, HELLO_MSG, strlen(HELLO_MSG));
|
||||
else
|
||||
ret = rpmsg_send(&lept, BYE_MSG, strlen(BYE_MSG));
|
||||
|
||||
if (ret < 0) {
|
||||
LPERROR("Failed to send data...\n");
|
||||
break;
|
||||
}
|
||||
LPRINTF("rpmsg sample test: message %d sent\n", i);
|
||||
|
||||
do {
|
||||
platform_poll(priv);
|
||||
} while ((rnum < i) && !err_cnt);
|
||||
|
||||
}
|
||||
|
||||
LPRINTF("**********************************\n");
|
||||
LPRINTF(" Test Results: Error count = %d\n", err_cnt);
|
||||
LPRINTF("**********************************\n");
|
||||
while (!ept_deleted)
|
||||
platform_poll(priv);
|
||||
LPRINTF("Quitting application .. rpmsg sample test end\n");
|
||||
|
||||
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_name_service_bind_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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user