mirror of
https://github.com/OpenAMP/open-amp.git
synced 2026-02-06 11:13:09 +08:00
Add BSD license when missing. Copyright has also been added for files when possible. Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
134 lines
3.3 KiB
C
134 lines
3.3 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
/*
|
|
* 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\r\n",
|
|
(unsigned int)count, payload);
|
|
if (rpmsg_send(ept, (char *)data, len) < 0) {
|
|
LPERROR("rpmsg_send failed\r\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\r\n");
|
|
shutdown_req = 1;
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------------*
|
|
* Application
|
|
*-----------------------------------------------------------------------------*/
|
|
int app(struct rpmsg_device *rdev, void *priv)
|
|
{
|
|
int ret;
|
|
|
|
/* Initialize RPMSG framework */
|
|
LPRINTF("Try to create rpmsg endpoint.\r\n");
|
|
|
|
ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERV_NAME,
|
|
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
|
|
rpmsg_endpoint_cb, rpmsg_service_unbind);
|
|
if (ret) {
|
|
LPERROR("Failed to create endpoint.\r\n");
|
|
return -1;
|
|
}
|
|
|
|
LPRINTF("Successfully created rpmsg endpoint.\r\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...\r\n");
|
|
|
|
/* Initialize platform */
|
|
ret = platform_init(argc, argv, &platform);
|
|
if (ret) {
|
|
LPERROR("Failed to initialize platform.\r\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.\r\n");
|
|
ret = -1;
|
|
} else {
|
|
app(rpdev, platform);
|
|
platform_release_rpmsg_vdev(rpdev, platform);
|
|
ret = 0;
|
|
}
|
|
}
|
|
|
|
LPRINTF("Stopping application...\r\n");
|
|
platform_cleanup(platform);
|
|
|
|
return ret;
|
|
}
|