-
Notifications
You must be signed in to change notification settings - Fork 294
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
apps: add msg-test-rpmsg-nocopy-ping test
to demo the usage of zero copy API Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
- Loading branch information
1 parent
94eb6ad
commit e0f42a4
Showing
2 changed files
with
202 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|