From cbb220bc4c4fbc2e90c9a8a71fbdd1a561e27fed Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Thu, 15 Oct 2020 23:29:46 -0500 Subject: [PATCH 1/1] examples: Add rpmsg_char_simple example Add a very basic example application demonstrating the usage of the rpmsg_char API provided by the ti-rpmsg-char library. The application is a single-threaded application, communicating with a single rpmsg device on a remote processor using one local endpoint device. The example is added in a new 'examples' directory. An README file is also added in the examples folder with the usage instructions. The examples folder is not built automatically using top-level make, and requires a specific command to be built. The top-level README is also updated accordingly. Signed-off-by: Suman Anna --- README | 18 ++- configure.ac | 3 +- examples/.gitignore | 1 + examples/Makefile.am | 11 ++ examples/README | 28 +++++ examples/rpmsg_char_simple.c | 222 +++++++++++++++++++++++++++++++++++ 6 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 examples/.gitignore create mode 100644 examples/Makefile.am create mode 100644 examples/README create mode 100644 examples/rpmsg_char_simple.c diff --git a/README b/README index d42989b..94de97a 100644 --- a/README +++ b/README @@ -66,7 +66,15 @@ examples: cd autoreconf -i ./configure --host=aarch64-none-linux-gnu --prefix= - 4. Build and Install + 4. Build and Install Library + make + make install + 5. Build Examples, the top-level Makefile builds only the library by + default + make -C examples + make -C examples install + or + cd examples make make install @@ -75,5 +83,11 @@ examples: make clean : Erase the files built by make make distclean : clean + Erase the files created by the configure step make uninstall : Erase the installed libraries and executables - 2. Use git clean to get the repo back to a pristine state + 2. Cleaning up examples specifically needs separate commands. It is all + similar to the commands in #1, but invoked with -C examples, or invoke + normally from within the examples folder + eg: make -C examples uninstall + or + cd examples; make uninstall + 3. Use git clean to get the repo back to a pristine state git clean -dfx diff --git a/configure.ac b/configure.ac index 227c442..d3a2d45 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,8 @@ AC_SUBST([AM_LDFLAGS]) # Generate Makefile(s) AC_CONFIG_FILES([Makefile src/Makefile - src/ti_rpmsg_char.pc]) + src/ti_rpmsg_char.pc + examples/Makefile]) AC_OUTPUT echo \ diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..1973b26 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +rpmsg_char_simple diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100644 index 0000000..5a9bedb --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,11 @@ +INCLUDE = -I${includedir} + +AM_CFLAGS = -Wall -g -O2 $(INCLUDE) + +bin_PROGRAMS = rpmsg_char_simple + +# rpmsg_char_simple program +rpmsg_char_simple_SOURCES = rpmsg_char_simple.c +rpmsg_char_simple_CPPFLAGS = $(AM_CFLAGS) +rpmsg_char_simple_LDADD = -lpthread -lti_rpmsg_char +rpmsg_char_simple_LDFLAGS = -L${libdir} diff --git a/examples/README b/examples/README new file mode 100644 index 0000000..72caec8 --- /dev/null +++ b/examples/README @@ -0,0 +1,28 @@ +rpmsg-char-simple application +============================= + +rpmsg-char-simple is a very basic single-threaded application +demonstrating the usage of the API provided by the ti-rpmsg-char +library to communicate messages to a remote processor exercising +the kernel rpmsg_char driver and virtio-rpmsg transport. + +Usage: + rpmsg_char_simple [-r ] [-n ] [-d ] [-p ] + + Where: + -r remote processor id to be used. + Valid values are 0 to RPROC_ID_MAX + -n Number of messages to exchange (default 100) + -d rpmsg device name + (defaults to NULL, translates to rpmsg_chrdev) + -p remote end-point address of the rpmsg device + (default 14 based on current example firmwares) + +Examples: +1. rpmsg_char_simple -r 2 -d ti.ipc4.ping-pong -p 13 + Runs the example using device "ti.ipc4.ping-pong" and remote port 13 + with rproc_id value of 2 (R5F_MAIN0_0), exchanges 100 messages +2. rpmsg_char_simple -r 4 -n 10 + Runs the example using default rpmsg device "rpmsg_chrdev", + remote port 14 with rproc_id value of 4 (R5F_MAIN1_0), exchanges + 10 messages diff --git a/examples/rpmsg_char_simple.c b/examples/rpmsg_char_simple.c new file mode 100644 index 0000000..96219b1 --- /dev/null +++ b/examples/rpmsg_char_simple.c @@ -0,0 +1,222 @@ +/* + * rpmsg_char_simple.c + * + * Simple Example application using rpmsg-char library + * + * Copyright (c) 2020 Texas Instruments Incorporated - https://www.ti.com + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define NUM_ITERATIONS 100 +#define REMOTE_ENDPT 14 + +int send_msg(int fd, char *msg, int len) +{ + int ret = 0; + + ret = write(fd, msg, len); + if (ret < 0) { + perror("Can't write to rpmsg endpt device\n"); + return -1; + } + + return ret; +} + +int recv_msg(int fd, int len, char *reply_msg, int *reply_len) +{ + int ret = 0; + + /* Note: len should be max length of response expected */ + ret = read(fd, reply_msg, len); + if (ret < 0) { + perror("Can't read from rpmsg endpt device\n"); + return -1; + } else { + *reply_len = ret; + } + + return 0; +} + +/* single thread communicating with a single endpoint */ +int rpmsg_char_ping(int rproc_id, char *dev_name, int remote_endpt, + int num_msgs) +{ + int ret = 0; + int i = 0; + int packet_len; + char eptdev_name[32] = { 0 }; + char packet_buf[512] = { 0 }; + rpmsg_char_dev_t *rcdev; + int flags = 0; + + /* + * Open the remote rpmsg device identified by dev_name and bind the + * device to a local end-point used for receiving messages from + * remote processor + */ + sprintf(eptdev_name, "rpmsg-char-%d-%d", rproc_id, getpid()); + rcdev = rpmsg_char_open(rproc_id, dev_name, remote_endpt, + eptdev_name, flags); + if (!rcdev) { + perror("Can't create an endpoint device"); + return -EPERM; + } + printf("Created endpt device %s, fd = %d port = %d\n", eptdev_name, + rcdev->fd, rcdev->endpt); + + printf("Exchanging %d messages with rpmsg device ti.ipc4.ping-pong on rproc id %d ...\n\n", + num_msgs, rproc_id); + + for (i = 0; i < num_msgs; i++) { + memset(packet_buf, 0, sizeof(packet_buf)); + sprintf(packet_buf, "hello there %d!", i); + packet_len = strlen(packet_buf); + printf("Sending message #%d: %s\n", i, packet_buf); + ret = send_msg(rcdev->fd, (char *)packet_buf, packet_len); + if (ret < 0) { + printf("send_msg failed for iteration %d, ret = %d\n", i, ret); + goto out; + } + if (ret != packet_len) { + printf("bytes written does not match send request, ret = %d, packet_len = %d\n", + i, ret); + goto out; + } + + printf("Receiving message #%d: ", i); + ret = recv_msg(rcdev->fd, 256, (char *)packet_buf, &packet_len); + if (ret < 0) { + printf("recv_msg failed for iteration %d, ret = %d\n", i, ret); + goto out; + } + /* TODO: Verify data integrity */ + + /* TODO: Reduce number of prints */ + printf("%s\n", packet_buf); + } + + printf("\nCommunicated %d messages successfully on %s\n\n", + num_msgs, eptdev_name); + +out: + ret = rpmsg_char_close(rcdev); + if (ret < 0) + perror("Can't delete the endpoint device\n"); + + return ret; +} + +void usage() +{ + printf("Usage: rpmsg_char_simple [-r ] [-n ] [-d = RPROC_ID_MAX) { + printf("Invalid rproc id %d, should be less than %d\n", + rproc_id, RPROC_ID_MAX); + usage(); + return 1; + } + + /* Use auto-detection for SoC */ + ret = rpmsg_char_init(NULL); + if (ret) { + printf("rpmsg_char_init failed, ret = %d\n", ret); + return ret; + } + + status = rpmsg_char_ping(rproc_id, dev_name, remote_endpt, num_msgs); + + rpmsg_char_exit(); + + if (status < 0) { + printf("TEST STATUS: FAILED\n"); + } else { + printf("TEST STATUS: PASSED\n"); + } + + return 0; +} -- 2.39.2