建立工程,成功创建两个虚拟串口

This commit is contained in:
ranchuan
2023-06-21 18:00:56 +08:00
commit 3604192d8f
872 changed files with 428764 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
set (_cflags "${CMAKE_C_FLAGS} ${APP_EXTRA_C_FLAGS}")
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_LARGE_TEXT_OPT)
if (NOT _linker_opt)
get_property (_linker_opt GLOBAL PROPERTY APP_LINKER_OPT)
endif (NOT _linker_opt)
collector_list (_deps PROJECT_LIB_DEPS)
set (OPENAMP_LIB open_amp)
if (${PROJECT_SYSTEM} STREQUAL "linux")
set (app_list rpc_demod)
else (${PROJECT_SYSTEM})
set (app_list rpc_demo)
endif (${PROJECT_SYSTEM} STREQUAL "linux")
foreach (_app ${app_list})
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)

View File

@@ -0,0 +1,169 @@
/* This is a sample demonstration application that showcases usage of proxy from the remote core.
This application is meant to run on the remote CPU running baremetal.
This applicationr can print to to master console and perform file I/O using proxy mechanism. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <openamp/open_amp.h>
#include <openamp/rpmsg_retarget.h>
#include "rsc_table.h"
#include "platform_info.h"
#include "rpmsg-rpc-demo.h"
#define REDEF_O_CREAT 0000100
#define REDEF_O_EXCL 0000200
#define REDEF_O_RDONLY 0000000
#define REDEF_O_WRONLY 0000001
#define REDEF_O_RDWR 0000002
#define REDEF_O_APPEND 0002000
#define REDEF_O_ACCMODE 0000003
#define LPRINTF(format, ...) xil_printf(format, ##__VA_ARGS__)
//#define LPRINTF(format, ...)
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
static void rpmsg_rpc_shutdown(struct rpmsg_rpc_data *rpc)
{
(void)rpc;
LPRINTF("RPMSG RPC is shutting down.\n");
}
/*-----------------------------------------------------------------------------*
* Application specific
*-----------------------------------------------------------------------------*/
int app(struct rpmsg_device *rdev, void *priv)
{
struct rpmsg_rpc_data rpc;
struct rpmsg_rpc_syscall rpccall;
int fd, bytes_written, bytes_read;
char fname[] = "remote.file";
char wbuff[50];
char rbuff[1024];
char ubuff[50];
float fdata;
int idata;
int ret;
/* redirect I/Os */
LPRINTF("Initializating I/Os redirection...\n");
ret = rpmsg_rpc_init(&rpc, rdev, RPMSG_SERVICE_NAME,
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
priv, platform_poll, rpmsg_rpc_shutdown);
rpmsg_set_default_rpc(&rpc);
if (ret) {
LPRINTF("Failed to intialize rpmsg rpc\n");
return -1;
}
printf("\r\nRemote>Baremetal Remote Procedure Call (RPC) Demonstration\r\n");
printf("\r\nRemote>***************************************************\r\n");
printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");
/* Remote performing file IO on Master */
printf("\r\nRemote>FileIO demo ..\r\n");
printf("\r\nRemote>Creating a file on master and writing to it..\r\n");
fd = open(fname, REDEF_O_CREAT | REDEF_O_WRONLY | REDEF_O_APPEND,
S_IRUSR | S_IWUSR);
printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
sprintf(wbuff, "This is a test string being written to file..");
bytes_written = write(fd, wbuff, strlen(wbuff));
printf("\r\nRemote>Wrote to fd = %d, size = %d, content = %s\r\n", fd,
bytes_written, wbuff);
close(fd);
printf("\r\nRemote>Closed fd = %d\r\n", fd);
/* Remote performing file IO on Master */
printf("\r\nRemote>Reading a file on master and displaying its contents..\r\n");
fd = open(fname, REDEF_O_RDONLY, S_IRUSR | S_IWUSR);
printf("\r\nRemote>Opened file '%s' with fd = %d\r\n", fname, fd);
bytes_read = read(fd, rbuff, 1024);
*(char *)(&rbuff[0] + bytes_read + 1) = 0;
printf("\r\nRemote>Read from fd = %d, size = %d, printing contents below .. %s\r\n",
fd, bytes_read, rbuff);
close(fd);
printf("\r\nRemote>Closed fd = %d\r\n", fd);
while (1) {
/* Remote performing STDIO on Master */
printf("\r\nRemote>Remote firmware using scanf and printf ..\r\n");
printf("\r\nRemote>Scanning user input from master..\r\n");
printf("\r\nRemote>Enter name\r\n");
ret = scanf("%s", ubuff);
if (ret) {
printf("\r\nRemote>Enter age\r\n");
ret = scanf("%d", &idata);
if (ret) {
printf("\r\nRemote>Enter value for pi\r\n");
ret = scanf("%f", &fdata);
if (ret) {
printf("\r\nRemote>User name = '%s'\r\n", ubuff);
printf("\r\nRemote>User age = '%d'\r\n", idata);
printf("\r\nRemote>User entered value of pi = '%f'\r\n", fdata);
}
}
}
if (!ret) {
scanf("%s", ubuff);
printf("Remote> Invalid value. Starting again....");
} else {
printf("\r\nRemote>Repeat demo ? (enter yes or no) \r\n");
scanf("%s", ubuff);
if ((strcmp(ubuff, "no")) && (strcmp(ubuff, "yes"))) {
printf("\r\nRemote>Invalid option. Starting again....\r\n");
} else if ((!strcmp(ubuff, "no"))) {
printf("\r\nRemote>RPC retargetting quitting ...\r\n");
break;
}
}
}
printf("\r\nRemote> Firmware's rpmsg-rpc-channel going down! \r\n");
rpccall.id = TERM_SYSCALL_ID;
(void)rpmsg_rpc_send(&rpc, &rpccall, sizeof(rpccall), NULL, 0);
LPRINTF("Release remoteproc procedure call\n");
rpmsg_rpc_release(&rpc);
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;
}

View File

@@ -0,0 +1,371 @@
/* This is a sample demonstration application that showcases usage of proxy from the remote core.
This application is meant to run on the remote CPU running baremetal.
This applicationr can print to to master console and perform file I/O using proxy mechanism. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <openamp/open_amp.h>
#include <openamp/rpmsg_retarget.h>
#include "platform_info.h"
#include "rpmsg-rpc-demo.h"
#define RPC_BUFF_SIZE 496
#define REDEF_O_CREAT 100
#define REDEF_O_EXCL 200
#define REDEF_O_RDONLY 0
#define REDEF_O_WRONLY 1
#define REDEF_O_RDWR 2
#define REDEF_O_APPEND 2000
#define REDEF_O_ACCMODE 3
#define raw_printf(format, ...) printf(format, ##__VA_ARGS__)
#define LPRINTF(format, ...) raw_printf("Master> " format, ##__VA_ARGS__)
#define LPERROR(format, ...) LPRINTF("ERROR: " format, ##__VA_ARGS__)
static void *platform;
static struct rpmsg_device *rpdev;
static struct rpmsg_endpoint app_ept;
static int request_termination = 0;
static int ept_deleted = 0;
static int err_cnt = 0;
static void *copy_from_shbuf(void *dst, void *shbuf, int len)
{
void *retdst = dst;
while (len && ((uintptr_t)shbuf % sizeof(int))) {
*(uint8_t *)dst = *(uint8_t *)shbuf;
dst++;
shbuf++;
len--;
}
while (len >= (int)sizeof(int)) {
*(unsigned int *)dst = *(unsigned int *)shbuf;
dst += sizeof(int);
shbuf += sizeof(int);
len -= sizeof(int);
}
while (len > 0) {
*(uint8_t *)dst = *(uint8_t *)shbuf;
dst++;
shbuf++;
len--;
}
return retdst;
}
static int handle_open(struct rpmsg_rpc_syscall *syscall,
struct rpmsg_endpoint *ept)
{
char *buf;
struct rpmsg_rpc_syscall resp;
int fd, ret;
if (!syscall || !ept)
return -EINVAL;
buf = (char *)syscall;
buf += sizeof(*syscall);
/* Open remote fd */
fd = open(buf, syscall->args.int_field1, syscall->args.int_field2);
/* Construct rpc response */
resp.id = OPEN_SYSCALL_ID;
resp.args.int_field1 = fd;
resp.args.int_field2 = 0; /*not used */
resp.args.data_len = 0; /*not used */
/* Transmit rpc response */
ret = rpmsg_send(ept, (void *)&resp, sizeof(resp));
return ret > 0 ? 0 : ret;
}
static int handle_close(struct rpmsg_rpc_syscall *syscall,
struct rpmsg_endpoint *ept)
{
struct rpmsg_rpc_syscall resp;
int ret;
if (!syscall || !ept)
return -EINVAL;
/* Close remote fd */
ret = close(syscall->args.int_field1);
/* Construct rpc response */
resp.id = CLOSE_SYSCALL_ID;
resp.args.int_field1 = ret;
resp.args.int_field2 = 0; /*not used */
resp.args.data_len = 0; /*not used */
/* Transmit rpc response */
ret = rpmsg_send(ept, &resp, sizeof(resp));
return ret > 0 ? 0 : ret;
}
static int handle_read(struct rpmsg_rpc_syscall *syscall,
struct rpmsg_endpoint *ept)
{
struct rpmsg_rpc_syscall *resp;
unsigned char buf[RPC_BUFF_SIZE];
unsigned char *payload;
int bytes_read, payload_size;
int ret;
if (!syscall || !ept)
return -EINVAL;
payload = buf + sizeof(*resp);
if (syscall->args.int_field1 == 0) {
bytes_read = sizeof(buf) - sizeof(*resp);
/* Perform read from fd for large size since this is a
STD/I request */
bytes_read = read(syscall->args.int_field1, payload,
bytes_read);
} else {
/* Perform read from fd */
bytes_read = read(syscall->args.int_field1, payload,
syscall->args.int_field2);
}
/* Construct rpc response */
resp = (struct rpmsg_rpc_syscall *)buf;
resp->id = READ_SYSCALL_ID;
resp->args.int_field1 = bytes_read;
resp->args.int_field2 = 0; /* not used */
resp->args.data_len = bytes_read;
payload_size = sizeof(*resp) +
((bytes_read > 0) ? bytes_read : 0);
/* Transmit rpc response */
ret = rpmsg_send(ept, buf, payload_size);
return ret > 0 ? 0 : ret;
}
static int handle_write(struct rpmsg_rpc_syscall *syscall,
struct rpmsg_endpoint *ept)
{
struct rpmsg_rpc_syscall resp;
unsigned char *buf;
int bytes_written;
int ret;
if (!syscall || !ept)
return -EINVAL;
buf = (unsigned char *)syscall;
buf += sizeof(*syscall);
/* Write to remote fd */
bytes_written = write(syscall->args.int_field1, buf,
syscall->args.int_field2);
/* Construct rpc response */
resp.id = WRITE_SYSCALL_ID;
resp.args.int_field1 = bytes_written;
resp.args.int_field2 = 0; /*not used */
resp.args.data_len = 0; /*not used */
/* Transmit rpc response */
ret = rpmsg_send(ept, (void *)&resp, sizeof(resp));
return ret > 0 ? 0 : ret;
}
static int handle_rpc(struct rpmsg_rpc_syscall *syscall,
struct rpmsg_endpoint *ept)
{
int retval;
/* Handle RPC */
switch (syscall->id) {
case OPEN_SYSCALL_ID:
{
retval = handle_open(syscall, ept);
break;
}
case CLOSE_SYSCALL_ID:
{
retval = handle_close(syscall, ept);
break;
}
case READ_SYSCALL_ID:
{
retval = handle_read(syscall, ept);
break;
}
case WRITE_SYSCALL_ID:
{
retval = handle_write(syscall, ept);
break;
}
case TERM_SYSCALL_ID:
{
LPRINTF("Received termination request\n");
request_termination = 1;
retval = 0;
break;
}
default:
{
LPERROR
("Invalid RPC sys call ID: %d:%d!\n",
(int)syscall->id, (int)WRITE_SYSCALL_ID);
retval = -1;
break;
}
}
return retval;
}
static void rpmsg_service_unbind(struct rpmsg_endpoint *ept)
{
(void)ept;
rpmsg_destroy_ept(&app_ept);
LPRINTF("Endpoint is destroyed\n");
ept_deleted = 1;
}
static int rpmsg_endpoint_cb(struct rpmsg_endpoint *ept, void *data, size_t len,
uint32_t src, void *priv)
{
unsigned char buf[RPC_BUFF_SIZE];
struct rpmsg_rpc_syscall *syscall;
(void)priv;
(void)src;
if (len < (int)sizeof(*syscall)) {
LPERROR("Received data is less than the rpc structure: %d\n",
len);
err_cnt++;
return RPMSG_SUCCESS;
}
/* In case the shared memory is device memory
* E.g. For now, we only use UIO device memory in Linux.
*/
if (len > RPC_BUFF_SIZE)
len = RPC_BUFF_SIZE;
copy_from_shbuf(buf, data, len);
syscall = (struct rpmsg_rpc_syscall *)buf;
if (handle_rpc(syscall, ept)) {
LPRINTF("\nHandling remote procedure call errors:\n");
raw_printf("rpc id %d\n", syscall->id);
raw_printf("rpc int field1 %d\n",
syscall->args.int_field1);
raw_printf("\nrpc int field2 %d\n",
syscall->args.int_field2);
err_cnt++;
}
return RPMSG_SUCCESS;
}
void terminate_rpc_app()
{
LPRINTF("Destroying endpoint.\n");
if (!ept_deleted)
rpmsg_destroy_ept(&app_ept);
}
void exit_action_handler(int signum)
{
(void)signum;
terminate_rpc_app();
}
void kill_action_handler(int signum)
{
(void)signum;
LPRINTF("RPC service killed !!\n");
terminate_rpc_app();
if (rpdev)
platform_release_rpmsg_vdev(rpdev);
if (platform)
platform_cleanup(platform);
}
/* Application entry point */
int app(struct rpmsg_device *rdev, void *priv)
{
int ret = 0;
struct sigaction exit_action;
struct sigaction kill_action;
/* Initialize signalling infrastructure */
memset(&exit_action, 0, sizeof(struct sigaction));
memset(&kill_action, 0, sizeof(struct sigaction));
exit_action.sa_handler = exit_action_handler;
kill_action.sa_handler = kill_action_handler;
sigaction(SIGTERM, &exit_action, NULL);
sigaction(SIGINT, &exit_action, NULL);
sigaction(SIGKILL, &kill_action, NULL);
sigaction(SIGHUP, &kill_action, NULL);
/* Initialize RPMSG framework */
LPRINTF("Try to create rpmsg endpoint.\n");
ret = rpmsg_create_ept(&app_ept, rdev, RPMSG_SERVICE_NAME,
0, RPMSG_ADDR_ANY, rpmsg_endpoint_cb,
rpmsg_service_unbind);
if (ret) {
LPERROR("Failed to create endpoint.\n");
return -EINVAL;
}
LPRINTF("Successfully created rpmsg endpoint.\n");
while(1) {
platform_poll(priv);
if (err_cnt) {
LPERROR("Got error!\n");
ret = -EINVAL;
break;
}
/* we got a shutdown request, exit */
if (ept_deleted || request_termination) {
break;
}
}
LPRINTF("\nRPC service exiting !!\n");
terminate_rpc_app();
return ret;
}
int main(int argc, char *argv[])
{
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_MASTER,
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;
}

View File

@@ -0,0 +1,6 @@
#ifndef RPMSG_RPC_DEMO_H
#define RPMSG_RPC_DEMO_H
#define RPMSG_SERVICE_NAME "rpmsg-openamp-demo-channel"
#endif /* RPMSG_RPC_DEMO_H */