Skip to content

Commit

Permalink
apps: add msg-test-rpmsg-nocopy-ping test
Browse files Browse the repository at this point in the history
to demo the usage of zero copy API

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
  • Loading branch information
xiaoxiang781216 committed Nov 9, 2020
1 parent 94eb6ad commit e0f42a4
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 1 deletion.
4 changes: 3 additions & 1 deletion apps/tests/msg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@ collector_list (_deps PROJECT_LIB_DEPS)

set (OPENAMP_LIB open_amp)

foreach (_app msg-test-rpmsg-ping msg-test-rpmsg-update msg-test-rpmsg-flood-ping)
foreach (_app msg-test-rpmsg-ping msg-test-rpmsg-update msg-test-rpmsg-flood-ping msg-test-rpmsg-nocopy-ping)
collector_list (_sources APP_COMMON_SOURCES)
if (${_app} STREQUAL "msg-test-rpmsg-ping")
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg-ping.c")
elseif (${_app} STREQUAL "msg-test-rpmsg-update")
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg-update.c")
elseif (${_app} STREQUAL "msg-test-rpmsg-flood-ping")
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg-flood-ping.c")
elseif (${_app} STREQUAL "msg-test-rpmsg-nocopy-ping")
list (APPEND _sources "${CMAKE_CURRENT_SOURCE_DIR}/rpmsg-nocopy-ping.c")
endif (${_app} STREQUAL "msg-test-rpmsg-ping")

if (WITH_SHARED_LIB)
Expand Down
199 changes: 199 additions & 0 deletions apps/tests/msg/rpmsg-nocopy-ping.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
/*
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2020, Xiaomi Inc. All rights reserved.
*/

#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"
#include "rpmsg-ping.h"

#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 int rnum;
static int err_cnt;
static int ept_deleted;

/* External functions */
extern int init_system(void);
extern void cleanup_system(void);

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 %lu \r\n",
r_payload->num, (unsigned long)len);

if (r_payload->size == 0) {
LPERROR(" Invalid size of package is received.\r\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\r\n", i);
err_cnt++;
break;
}
}
rnum = r_payload->num + 1;
return RPMSG_SUCCESS;
}

static void rpmsg_service_unbind(struct rpmsg_endpoint *ept)
{
(void)ept;
rpmsg_destroy_ept(&lept);
LPRINTF("echo test: service is destroyed\r\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.\r\n");
if (strcmp(name, RPMSG_SERVICE_NAME))
LPERROR("Unexpected name service %s.\r\n", name);
else
(void)rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME,
RPMSG_ADDR_ANY, dest,
rpmsg_endpoint_cb,
rpmsg_service_unbind);

}

static int app(struct rpmsg_device *rdev, void *priv)
{
int ret;
int i, num_payloads;
uint32_t size, max_size;
int expect_rnum = 0;

LPRINTF(" 1 - Send data to remote core, retrieve the echo");
LPRINTF(" and validate its integrity ..\r\n");

max_size = rpmsg_virtio_get_buffer_size(rdev);
if ((int32_t)max_size < 0) {
LPERROR("No available buffer size.\r\n");
return -1;
}
max_size -= sizeof(struct _payload);
num_payloads = max_size - PAYLOAD_MIN_SIZE + 1;

/* Create RPMsg endpoint */
ret = rpmsg_create_ept(&lept, rdev, RPMSG_SERVICE_NAME,
RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
rpmsg_endpoint_cb, rpmsg_service_unbind);

if (ret) {
LPERROR("Failed to create RPMsg endpoint.\r\n");
return ret;
}

while (!is_rpmsg_ept_ready(&lept))
platform_poll(priv);

LPRINTF("RPMSG endpoint is binded with remote.\r\n");
for (i = 0, size = PAYLOAD_MIN_SIZE; i < num_payloads; i++, size++) {
struct _payload *i_payload;

i_payload = rpmsg_get_tx_payload_buffer(&lept, &max_size, 1);
if (!i_payload) {
LPERROR("Failed to get payload...\r\n");
break;
}

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 %lu\r\n",
i_payload->num,
(unsigned long)(2 * sizeof(unsigned long)) + size);

ret = rpmsg_send_nocopy(&lept, i_payload,
(2 * sizeof(unsigned long)) + size);

if (ret < 0) {
LPERROR("Failed to send data...\r\n");
break;
}
LPRINTF("echo test: sent : %lu\r\n",
(unsigned long)(2 * sizeof(unsigned long)) + size);

expect_rnum++;
do {
platform_poll(priv);
} while ((rnum < expect_rnum) && !err_cnt && !ept_deleted);

}

LPRINTF("**********************************\r\n");
LPRINTF(" Test Results: Error count = %d \r\n", err_cnt);
LPRINTF("**********************************\r\n");
/* Destroy the RPMsg endpoint */
rpmsg_destroy_ept(&lept);
LPRINTF("Quitting application .. Echo test end\r\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.\r\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.\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;
}

0 comments on commit e0f42a4

Please sign in to comment.