summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: dd61d24)
raw | patch | inline | side by side (parent: dd61d24)
author | Wendy Liang <jliang@xilinx.com> | |
Fri, 20 Mar 2015 00:35:56 +0000 (10:35 +1000) | ||
committer | Wendy Liang <jliang@xilinx.com> | |
Mon, 6 Apr 2015 07:23:26 +0000 (17:23 +1000) |
Signed-off-by: Wendy Liang <jliang@xilinx.com>
diff --git a/apps/samples/master/linux/kernelspace/rpmsg_mat_mul_kern_app/rpmsg_mat_mul_kern_app.c b/apps/samples/master/linux/kernelspace/rpmsg_mat_mul_kern_app/rpmsg_mat_mul_kern_app.c
index 13cda8d1c114612e6b51be3cd329dc1531a49765..910004efdf635f48038b515d09402433d1d60a11 100644 (file)
/*
- * RPMSG Matrix Multiplication Kernel Driver
+ * RPMSG User Device Kernel Driver
*
* Copyright (C) 2014 Mentor Graphics Corporation
*
#include <linux/module.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>
-#include <linux/random.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+#include <linux/workqueue.h>
+
+#define MAX_RPMSG_BUFF_SIZE 512
+
+#define PAYLOAD_MIN_SIZE 1
+#define PAYLOAD_MAX_SIZE (MAX_RPMSG_BUFF_SIZE - sizeof(struct rpmsg_hdr) - 24)
+#define NUM_PAYLOADS (PAYLOAD_MAX_SIZE/PAYLOAD_MIN_SIZE)
-/* Application */
-#define MAX_SIZE 6
-#define NUM_MATRIX 2
/* Shutdown message ID */
#define SHUTDOWN_MSG 0xEF56A55A
-struct rpmsg_endpoint *ept;
-static const char init_msg[] = "init_msg";
+#define RPMG_INIT_MSG "init_msg"
-static const char *const shutdown_argv[]
- = { "/sbin/shutdown", "-h", "-P", "now", NULL };
+struct _rpmsg_dev_params {
+ struct device *rpmsg_dev;
+ struct mutex sync_lock;
+ struct rpmsg_channel *rpmsg_chnl;
+ char tx_buff[MAX_RPMSG_BUFF_SIZE]; /* buffer to keep the message to send */
+ u32 rpmsg_dst;
+ int err_cnt;
+ struct work_struct rpmsg_work;
+};
-struct _matrix {
- unsigned long size;
- unsigned long elements[MAX_SIZE][MAX_SIZE];
+struct _payload {
+ unsigned int num;
+ unsigned int size;
+ unsigned char data[];
};
-static struct _matrix *p_matrix;
+static const char *const shutdown_argv[]
+ = { "/sbin/shutdown", "-h", "-P", "now", NULL };
-static void matrix_print(struct _matrix *m)
+static int rpmsg_echo_test_kern_app_echo_test(struct _rpmsg_dev_params *rpmsg_dev)
{
- int i, j;
-
- /* Generate two random matrices */
- pr_err(" \r\n Master : Linux : Printing results \r\n");
-
- for (i = 0; i < m->size; ++i) {
- for (j = 0; j < m->size; ++j)
- pr_cont(" %d ", (unsigned int)m->elements[i][j]);
- pr_info("\r\n");
+ static int payload_num = 0;
+ static int next_payload_size = PAYLOAD_MIN_SIZE;
+ int payload_size = 0;
+ int i = 0;
+ struct _payload *payload;
+ int err = 0;
+ if (!rpmsg_dev) {
+ return -1;
+ }
+ //pr_info("%s\n", __func__);
+ if (next_payload_size > PAYLOAD_MAX_SIZE) {
+ *((unsigned int *)rpmsg_dev->tx_buff) = SHUTDOWN_MSG;
+ //pr_info("Sending shutdown message to remote.\n");
+ err = rpmsg_send(rpmsg_dev->rpmsg_chnl, rpmsg_dev->tx_buff, sizeof(unsigned int));
+ if (err) {
+ pr_err ("Shutdown message send failed.\n");
+ return -1;
+ }
+ } else {
+ payload_size = next_payload_size++;
+ payload = (struct _payload *)(rpmsg_dev->tx_buff);
+ payload->num = payload_num++;
+ payload->size = payload_size;
+ memset(payload->data, 0xA5, payload_size);
+ err = rpmsg_send(rpmsg_dev->rpmsg_chnl, rpmsg_dev->tx_buff, (payload_size + sizeof(struct _payload)));
+ if (err) {
+ pr_err("Failed to send echo test message to remote.\n");
+ return -1;
+ }
}
+ return payload_size;
}
-static void generate_matrices(int num_matrices, unsigned int matrix_size,
- void *p_data)
+static void rpmsg_echo_test_kern_app_work_func(struct work_struct *work)
{
- int i, j, k, val;
- struct _matrix *p_matrix = p_data;
-
- /* Generate two random matrices */
- pr_err(" \r\n Master : Linux : Generating random matrices \r\n");
-
- for (i = 0; i < num_matrices; i++) {
-
- /* Initialize workload */
- p_matrix[i].size = matrix_size;
-
- pr_err(" \r\n Master : Linux : Input matrix %d \r\n", i);
- for (j = 0; j < matrix_size; j++) {
-
- pr_info("\r\n");
- for (k = 0; k < matrix_size; k++) {
- get_random_bytes(&val, sizeof(val));
- p_matrix[i].elements[j][k] =
- ((val & 0x7F) % 10);
- pr_cont(" %d ",
- (unsigned int)p_matrix[i].elements[j][k]);
- }
- }
- pr_err("\r\n");
+ struct _rpmsg_dev_params *local = container_of(work, struct _rpmsg_dev_params, rpmsg_work);
+ //pr_info ("%s:%p.\n", __func__, local);
+ int local_err_cnt = 0;
+ if (rpmsg_echo_test_kern_app_echo_test(local) <= 0) {
+ mutex_lock(&local->sync_lock);
+ local_err_cnt = local->err_cnt;
+ mutex_unlock(&local->sync_lock);
+ pr_info("\r\n *******************************************\r\n");
+ pr_info("\r\n Echo Test Results: Error count = %d\r\n", local_err_cnt);
+ pr_info("\r\n *******************************************\r\n");
}
-
}
-static void rpmsg_mat_mul_kern_app_rx_cb(struct rpmsg_channel *rpdev,
- void *data, int len, void *priv, u32 src)
+static void rpmsg_echo_test_kern_app_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
{
- int err;
- int shutdown_msg = SHUTDOWN_MSG;
- pr_err(" \r\n Master : Linux : Received %d bytes of data", len);
- pr_err(" over rpmsg channel from remote \r\n");
+ struct _rpmsg_dev_params *local = dev_get_drvdata(&rpdev->dev);
+ struct _payload *payload = data;
+ int i = 0;
/* Shutdown Linux if such a message is received. Only applicable
- when Linux is a remoteproc remote. */
+ when Linux is a remoteproc remote. */
+
+ //pr_info ("%s\n", __func__);
+ if (!data) {
+ return;
+ }
+
if ((*(int *) data) == SHUTDOWN_MSG) {
+ dev_info(&rpdev->dev,"shutdown message is received. Shutting down...\n");
call_usermodehelper(shutdown_argv[0], shutdown_argv,
NULL, UMH_NO_WAIT);
} else {
- /* print results */
- matrix_print((struct _matrix *)data);
-
- /* Send payload to remote. */
- err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
- &shutdown_msg, sizeof(int));
-
- if (err)
- pr_err(" Shutdown send failed!\r\n");
-
- kzfree(p_matrix);
+ pr_info("\r\n Master : Linux Kernal Space : Received payload ");
+ pr_info("num %d of size %d, total len %d. \r\n", payload->num, payload->size,len);
+ for (i = 0; i < payload->size; i++) {
+ if (payload->data[i] != 0xA5) {
+ pr_err("\r\n Data corruption at index %d. \r\n", i);
+ mutex_lock(&local->sync_lock);
+ local->err_cnt++;
+ mutex_unlock(&local->sync_lock);
+ break;
+ }
+ }
+ schedule_work(&local->rpmsg_work);
}
}
-static int rpmsg_mat_mul_kern_app_probe(struct rpmsg_channel *rpdev)
+static int rpmsg_echo_test_kern_app_probe(struct rpmsg_channel *rpdev)
{
- int err;
-
- pr_err("\r\n Demo Start - Demo rpmsg driver got probed \r\n");
- pr_err("since the rpmsg device associated with driver was found !\r\n");
+ struct _rpmsg_dev_params *local;
+ dev_info(&rpdev->dev, "%s", __func__);
- pr_err("\r\n Create endpoint and register rx callback \r\n");
- /* Create endpoint for remote channel and register rx callabck */
- ept = rpmsg_create_ept(rpdev, rpmsg_mat_mul_kern_app_rx_cb, 0,
- RPMSG_ADDR_ANY);
-
- if (!ept) {
- pr_err(" Endpoint creation for failed!\r\n");
+ local = devm_kzalloc(&rpdev->dev, sizeof(struct _rpmsg_dev_params),
+ GFP_KERNEL);
+ if (!local) {
+ dev_err(&rpdev->dev, "Failed to allocate memory for rpmsg user dev.\n");
return -ENOMEM;
}
+ memset(local, 0x0, sizeof(struct _rpmsg_dev_params));
- /* Send init message to complete the connection loop */
- err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
- init_msg, sizeof(init_msg));
+ /* Initialize mutex */
+ mutex_init(&local->sync_lock);
- if (err) {
- pr_err(" Init messages send failed!\r\n");
- return err;
- }
+ local->rpmsg_chnl = rpdev;
- /* Allocate memory for random matrices */
- p_matrix = kzalloc(sizeof(struct _matrix)*2, GFP_KERNEL);
+ dev_set_drvdata(&rpdev->dev, local);
- /* Generate random matrices */
- generate_matrices(NUM_MATRIX, MAX_SIZE, p_matrix);
-
- /* Send matrices to remote for computation */
- err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
- p_matrix, sizeof(struct _matrix) * 2);
+ sprintf(local->tx_buff, RPMG_INIT_MSG);
+ if (rpmsg_sendto(local->rpmsg_chnl,
+ local->tx_buff,
+ sizeof(RPMG_INIT_MSG),
+ rpdev->dst)) {
+ dev_err(&rpdev->dev, "Failed to send init_msg to target 0x%x.", local->rpmsg_dst);
+ goto error0;
+ }
+ dev_info(&rpdev->dev, "Sent init_msg to target 0x%x.", local->rpmsg_dst);
- pr_err("\r\n Master : Linux : Sent %d bytes of data over rpmsg channel to remote \r\n",
- sizeof(struct _matrix) * 2);
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
- if (err) {
- pr_err(" send failed!\r\n");
- return err;
+ INIT_WORK(&local->rpmsg_work, rpmsg_echo_test_kern_app_work_func);
+#if 0
+ if (rpmsg_echo_test_kern_app_echo_test(local) <= 0) {
+ pr_err("Failed to send echo test message to remote.\n");
+ return -1;
}
-
+#else
+ schedule_work(&local->rpmsg_work);
+#endif
+
+ goto out;
+error0:
+ return -ENODEV;
+out:
return 0;
}
-static void rpmsg_mat_mul_kern_app_remove(struct rpmsg_channel *rpdev)
-{
- rpmsg_destroy_ept(ept);
-}
-
-static void rpmsg_cb(struct rpmsg_channel *rpdev, void *data,
- int len, void *priv, u32 src)
+static void rpmsg_echo_test_kern_app_remove(struct rpmsg_channel *rpdev)
{
-
+ struct _rpmsg_dev_params *local = dev_get_drvdata(&rpdev->dev);
+ flush_work(&local->rpmsg_work);
}
-static struct rpmsg_device_id rpmsg_mat_mul_kern_app_id_table[] = {
- { .name = "rpmsg-openamp-demo-channel" },
- { },
+static struct rpmsg_device_id rpmsg_echo_test_kern_app_id_table[] = {
+ { .name = "rpmsg-openamp-demo-channel" },
+ {},
};
-MODULE_DEVICE_TABLE(rpmsg, rpmsg_mat_mul_kern_app_id_table);
-
-static struct rpmsg_driver rpmsg_mat_mul_kern_app = {
- .drv.name = KBUILD_MODNAME,
- .drv.owner = THIS_MODULE,
- .id_table = rpmsg_mat_mul_kern_app_id_table,
- .probe = rpmsg_mat_mul_kern_app_probe,
- .callback = rpmsg_cb,
- .remove = rpmsg_mat_mul_kern_app_remove,
+
+static struct rpmsg_driver rpmsg_echo_test_kern_app_drv = {
+ .drv.name = "rpmsg_echo_test_kern_app",
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_echo_test_kern_app_id_table,
+ .probe = rpmsg_echo_test_kern_app_probe,
+ .remove = rpmsg_echo_test_kern_app_remove,
+ .callback = rpmsg_echo_test_kern_app_cb,
};
static int __init init(void)
{
- return register_rpmsg_driver(&rpmsg_mat_mul_kern_app);
+ return register_rpmsg_driver(&rpmsg_echo_test_kern_app_drv);
}
static void __exit fini(void)
{
- unregister_rpmsg_driver(&rpmsg_mat_mul_kern_app);
+ unregister_rpmsg_driver(&rpmsg_echo_test_kern_app_drv);
}
module_init(init);
module_exit(fini);
-MODULE_DESCRIPTION("Sample rpmsg matrix multiplication kernel application");
+
+MODULE_DESCRIPTION("Sample driver to exposes rpmsg svcs to userspace via a char device");
MODULE_LICENSE("GPL v2");
diff --git a/apps/samples/master/linux/kernelspace/rpmsg_user_dev_driver/rpmsg_user_dev_driver.c b/apps/samples/master/linux/kernelspace/rpmsg_user_dev_driver/rpmsg_user_dev_driver.c
index 2ef99ce4bc34b2dc945d27a753a6029b1e8b68c4..4a640eadf27c6295ddcc5bf29a82848a24f37cdb 100644 (file)
#include <linux/kthread.h>
#include <linux/ioctl.h>
#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/of_platform.h>
-#include <linux/sysfs.h>
#define MAX_RPMSG_BUFF_SIZE 512
#define RPMSG_KFIFO_SIZE (MAX_RPMSG_BUFF_SIZE * 4)
struct _rpmsg_dev_params *local = container_of(inode->i_cdev,
struct _rpmsg_dev_params, cdev);
p_file->private_data = local;
- pr_info("%s\n", __func__);
+
return 0;
}
.callback = rpmsg_user_dev_rpmsg_drv_cb,
};
-static ssize_t rpmsg_user_dev_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t status;
-
- status = sprintf(buf, "%s\n",
- rpmsg_user_dev_drv_id_table[0].name);
- return status;
-}
-
-static DEVICE_ATTR(rpmsg_id, 0444, rpmsg_user_dev_id_show, NULL);
-
-static const struct attribute *rpmsg_dev_attrs[] = {
- &dev_attr_rpmsg_id.attr,
- NULL,
-};
-
-static const struct attribute_group rpmsg_dev_attr_group = {
- .attrs = (struct attribute **) rpmsg_dev_attrs,
-};
-
static int rpmsg_user_dev_rpmsg_drv_probe(struct rpmsg_channel *rpdev)
{
struct _rpmsg_dev_params *local;
local->rpmsg_chnl = rpdev;
local->block_flag = 0;
+ dev_set_drvdata(&rpdev->dev, local);
+
sprintf(local->tx_buff, RPMG_INIT_MSG);
if (rpmsg_sendto(local->rpmsg_chnl,
local->tx_buff,
sizeof(RPMG_INIT_MSG),
rpdev->dst)) {
dev_err(&rpdev->dev, "Failed to send init_msg to target 0x%x.", local->rpmsg_dst);
- goto error0;
+ goto error1;
}
dev_info(&rpdev->dev, "Sent init_msg to target 0x%x.", local->rpmsg_dst);
- dev_set_drvdata(&rpdev->dev, local);
-
/* Create device file for the rpmsg user dev device */
if (rpmsg_dev_next_minor < RPMSG_USER_DEV_MAX_MINORS) {
local->rpmsg_minor = rpmsg_dev_next_minor++;
dev_err(&rpdev->dev, "Cannot create device file.\n");
goto error1;
}
- /* Create sysfs group */
- status = sysfs_create_group(&(rpdev->dev.kobj), &rpmsg_dev_attr_group);
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
rpdev->src, rpdev->dst);
diff --git a/apps/samples/master/linux/userspace/matrix_multiply/mat_mul_demo.c b/apps/samples/master/linux/userspace/matrix_multiply/mat_mul_demo.c
index 9176e2f56290885689424abe0cc8a9ca311b0a54..5f60e094ac8c4444216fb3ed16d9ad3118b000ab 100644 (file)
do {
bytes_rcvd = read(fd, &r_matrix, sizeof(r_matrix));
- } while (bytes_rcvd < sizeof(r_matrix));
+ } while ((bytes_rcvd < sizeof(r_matrix)) || (bytes_rcvd < 0));
printf("\r\n Received results! - %d bytes from ", bytes_rcvd);
printf("rpmsg device (transmitted from remote context) \r\n");
diff --git a/apps/tests/master/linux/kernelspace/rpmsg_echo_test_kern_app/rpmsg_echo_test_kern_app.c b/apps/tests/master/linux/kernelspace/rpmsg_echo_test_kern_app/rpmsg_echo_test_kern_app.c
index 19c99f7fbf12d59c3ddb98c2f98bf970097a0932..910004efdf635f48038b515d09402433d1d60a11 100644 (file)
/*
- * RPMSG Echo Test Kernel Driver
+ * RPMSG User Device Kernel Driver
*
* Copyright (C) 2014 Mentor Graphics Corporation
*
- * Test application that validates data integraty of inter processor
- * communication from linux userspace to a remote software
- * context. The application sends chunks of data to the
- * remote processor. The remote side echoes the data back
- * to application which then validates the data returned.
- *
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
#include <linux/module.h>
#include <linux/rpmsg.h>
#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/wait.h>
+#include <linux/device.h>
#include <linux/mutex.h>
-#include <linux/kthread.h>
-#include <linux/delay.h>
-
-static DECLARE_WAIT_QUEUE_HEAD(wait_queue);
-static int flag;
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+#include <linux/workqueue.h>
-struct _payload {
-unsigned long num;
-unsigned long size;
-char data[];
-};
+#define MAX_RPMSG_BUFF_SIZE 512
-#define MAX_RPMSG_BUFF_SIZE 512
#define PAYLOAD_MIN_SIZE 1
-#define PAYLOAD_MAX_SIZE (MAX_RPMSG_BUFF_SIZE - 24)
+#define PAYLOAD_MAX_SIZE (MAX_RPMSG_BUFF_SIZE - sizeof(struct rpmsg_hdr) - 24)
#define NUM_PAYLOADS (PAYLOAD_MAX_SIZE/PAYLOAD_MIN_SIZE)
-/* Shutdown message ID */
-#define SHUTDOWN_MSG 0xEF56A55A
-#define GIGA 1000000000L
-
-static const char * const shutdown_argv[]
- = { "/sbin/shutdown", "-h", "-P", "now", NULL };
+/* Shutdown message ID */
+#define SHUTDOWN_MSG 0xEF56A55A
+
+#define RPMG_INIT_MSG "init_msg"
+
+struct _rpmsg_dev_params {
+ struct device *rpmsg_dev;
+ struct mutex sync_lock;
+ struct rpmsg_channel *rpmsg_chnl;
+ char tx_buff[MAX_RPMSG_BUFF_SIZE]; /* buffer to keep the message to send */
+ u32 rpmsg_dst;
+ int err_cnt;
+ struct work_struct rpmsg_work;
+};
-struct rpmsg_endpoint *ept;
+struct _payload {
+ unsigned int num;
+ unsigned int size;
+ unsigned char data[];
+};
-struct _payload *p_payload;
+static const char *const shutdown_argv[]
+ = { "/sbin/shutdown", "-h", "-P", "now", NULL };
-static const char init_msg[] = "init_msg";
-int err_cnt;
+static int rpmsg_echo_test_kern_app_echo_test(struct _rpmsg_dev_params *rpmsg_dev)
+{
+ static int payload_num = 0;
+ static int next_payload_size = PAYLOAD_MIN_SIZE;
+ int payload_size = 0;
+ int i = 0;
+ struct _payload *payload;
+ int err = 0;
+ if (!rpmsg_dev) {
+ return -1;
+ }
+ //pr_info("%s\n", __func__);
+ if (next_payload_size > PAYLOAD_MAX_SIZE) {
+ *((unsigned int *)rpmsg_dev->tx_buff) = SHUTDOWN_MSG;
+ //pr_info("Sending shutdown message to remote.\n");
+ err = rpmsg_send(rpmsg_dev->rpmsg_chnl, rpmsg_dev->tx_buff, sizeof(unsigned int));
+ if (err) {
+ pr_err ("Shutdown message send failed.\n");
+ return -1;
+ }
+ } else {
+ payload_size = next_payload_size++;
+ payload = (struct _payload *)(rpmsg_dev->tx_buff);
+ payload->num = payload_num++;
+ payload->size = payload_size;
+ memset(payload->data, 0xA5, payload_size);
+ err = rpmsg_send(rpmsg_dev->rpmsg_chnl, rpmsg_dev->tx_buff, (payload_size + sizeof(struct _payload)));
+ if (err) {
+ pr_err("Failed to send echo test message to remote.\n");
+ return -1;
+ }
+ }
+ return payload_size;
+}
-static void rpmsg_echo_test_kern_app_rx_cb(struct rpmsg_channel *rpdev,
- void *data, int len, void *priv, u32 src)
+static void rpmsg_echo_test_kern_app_work_func(struct work_struct *work)
{
- struct _payload *local_payload = data;
- int i;
+ struct _rpmsg_dev_params *local = container_of(work, struct _rpmsg_dev_params, rpmsg_work);
+ //pr_info ("%s:%p.\n", __func__, local);
+ int local_err_cnt = 0;
+ if (rpmsg_echo_test_kern_app_echo_test(local) <= 0) {
+ mutex_lock(&local->sync_lock);
+ local_err_cnt = local->err_cnt;
+ mutex_unlock(&local->sync_lock);
+ pr_info("\r\n *******************************************\r\n");
+ pr_info("\r\n Echo Test Results: Error count = %d\r\n", local_err_cnt);
+ pr_info("\r\n *******************************************\r\n");
+ }
+}
- if (p_payload) {
+static void rpmsg_echo_test_kern_app_cb(struct rpmsg_channel *rpdev, void *data,
+ int len, void *priv, u32 src)
+{
- pr_err("\r\n Master : Linux Kernal Space : Received payload ");
- pr_err("num %d of size %d \r\n", local_payload->num, len);
+ struct _rpmsg_dev_params *local = dev_get_drvdata(&rpdev->dev);
+ struct _payload *payload = data;
+ int i = 0;
- /* Shutdown Linux if such a message is received.
- Only applicable when Linux is a remoteproc remote. */
- if ((*(int *) data) == SHUTDOWN_MSG) {
- call_usermodehelper(shutdown_argv[0], shutdown_argv,
- NULL, UMH_NO_WAIT);
- } else {
+ /* Shutdown Linux if such a message is received. Only applicable
+ when Linux is a remoteproc remote. */
- for (i = 0; i < local_payload->size; i++) {
+ //pr_info ("%s\n", __func__);
+ if (!data) {
+ return;
+ }
- if (local_payload->data[i] != 0xA5) {
- pr_err("\r\n Data corruption ");
- pr_cont("at index %d \r\n", i);
- err_cnt++;
- break;
- }
+ if ((*(int *) data) == SHUTDOWN_MSG) {
+ dev_info(&rpdev->dev,"shutdown message is received. Shutting down...\n");
+ call_usermodehelper(shutdown_argv[0], shutdown_argv,
+ NULL, UMH_NO_WAIT);
+ } else {
+ pr_info("\r\n Master : Linux Kernal Space : Received payload ");
+ pr_info("num %d of size %d, total len %d. \r\n", payload->num, payload->size,len);
+ for (i = 0; i < payload->size; i++) {
+ if (payload->data[i] != 0xA5) {
+ pr_err("\r\n Data corruption at index %d. \r\n", i);
+ mutex_lock(&local->sync_lock);
+ local->err_cnt++;
+ mutex_unlock(&local->sync_lock);
+ break;
}
-
- /* Free memory allocated to payload buffer. */
- kzfree(p_payload);
-
- /* Wake up the application. */
- flag = 1;
- wake_up_interruptible(&wait_queue);
}
+ schedule_work(&local->rpmsg_work);
}
}
static int rpmsg_echo_test_kern_app_probe(struct rpmsg_channel *rpdev)
{
- int err, i, size;
- int shutdown_msg = SHUTDOWN_MSG;
-
- pr_err("\r\n Echo Test Start! \r\n");
-
- /* Create endpoint for remote channel and register rx callabck */
- ept = rpmsg_create_ept(rpdev, rpmsg_echo_test_kern_app_rx_cb, 0,
- RPMSG_ADDR_ANY);
+ struct _rpmsg_dev_params *local;
+ dev_info(&rpdev->dev, "%s", __func__);
- if (!ept) {
- pr_err(" Endpoint creation for failed!\r\n");
+ local = devm_kzalloc(&rpdev->dev, sizeof(struct _rpmsg_dev_params),
+ GFP_KERNEL);
+ if (!local) {
+ dev_err(&rpdev->dev, "Failed to allocate memory for rpmsg user dev.\n");
return -ENOMEM;
}
+ memset(local, 0x0, sizeof(struct _rpmsg_dev_params));
- /* Send init message to complete the connection loop */
- err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
- init_msg, sizeof(init_msg));
+ /* Initialize mutex */
+ mutex_init(&local->sync_lock);
- if (err) {
- pr_err(" Init message send failed!\r\n");
- return err;
- }
-
- for (i = 0, size = PAYLOAD_MIN_SIZE; i < NUM_PAYLOADS; i++, size++) {
- p_payload = kzalloc(2 * sizeof(unsigned long) + size,
- GFP_KERNEL);
- p_payload->num = i;
- p_payload->size = size;
- memset(&(p_payload->data[0]), 0xA5, size);
-
- pr_err("\r\n Master : Linux Kernal Space : Sending payload num %d of size %d \r\n",
- p_payload->num, (2 * sizeof(unsigned long)) + size);
+ local->rpmsg_chnl = rpdev;
- /* Send payload to remote. */
- err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
- p_payload, (2 * sizeof(unsigned long)) + size);
+ dev_set_drvdata(&rpdev->dev, local);
- if (err) {
- pr_err(" send failed!\r\n");
- return err;
- }
-
- /* Wait till the data is echoed back. */
- wait_event_interruptible(wait_queue, flag != 0);
- flag = 0;
+ sprintf(local->tx_buff, RPMG_INIT_MSG);
+ if (rpmsg_sendto(local->rpmsg_chnl,
+ local->tx_buff,
+ sizeof(RPMG_INIT_MSG),
+ rpdev->dst)) {
+ dev_err(&rpdev->dev, "Failed to send init_msg to target 0x%x.", local->rpmsg_dst);
+ goto error0;
}
+ dev_info(&rpdev->dev, "Sent init_msg to target 0x%x.", local->rpmsg_dst);
- /* Send payload to remote. */
- err = rpmsg_send_offchannel(rpdev, ept->addr, rpdev->dst,
- &shutdown_msg, sizeof(int));
+ dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
+ rpdev->src, rpdev->dst);
- if (err) {
- pr_err(" Shutdown message send failed!\r\n");
- return err;
+ INIT_WORK(&local->rpmsg_work, rpmsg_echo_test_kern_app_work_func);
+#if 0
+ if (rpmsg_echo_test_kern_app_echo_test(local) <= 0) {
+ pr_err("Failed to send echo test message to remote.\n");
+ return -1;
}
-
- pr_err("\r\n *******************************************\r\n");
- pr_err("\r\n Echo Test Results: Error count = %d\r\n", err_cnt);
- pr_err("\r\n *******************************************\r\n");
-
+#else
+ schedule_work(&local->rpmsg_work);
+#endif
+
+ goto out;
+error0:
+ return -ENODEV;
+out:
return 0;
}
static void rpmsg_echo_test_kern_app_remove(struct rpmsg_channel *rpdev)
{
- rpmsg_destroy_ept(ept);
-}
-
-static void rpmsg_cb(struct rpmsg_channel *rpdev, void *data,
- int len, void *priv, u32 src)
-{
-
+ struct _rpmsg_dev_params *local = dev_get_drvdata(&rpdev->dev);
+ flush_work(&local->rpmsg_work);
}
static struct rpmsg_device_id rpmsg_echo_test_kern_app_id_table[] = {
- { .name = "rpmsg-openamp-demo-channel" },
- { },
+ { .name = "rpmsg-openamp-demo-channel" },
+ {},
};
-MODULE_DEVICE_TABLE(rpmsg, rpmsg_echo_test_kern_app_id_table);
-
-static struct rpmsg_driver rpmsg_echo_test_kern_app = {
- .drv.name = KBUILD_MODNAME,
- .drv.owner = THIS_MODULE,
- .id_table = rpmsg_echo_test_kern_app_id_table,
- .probe = rpmsg_echo_test_kern_app_probe,
- .callback = rpmsg_cb,
- .remove = rpmsg_echo_test_kern_app_remove,
+
+static struct rpmsg_driver rpmsg_echo_test_kern_app_drv = {
+ .drv.name = "rpmsg_echo_test_kern_app",
+ .drv.owner = THIS_MODULE,
+ .id_table = rpmsg_echo_test_kern_app_id_table,
+ .probe = rpmsg_echo_test_kern_app_probe,
+ .remove = rpmsg_echo_test_kern_app_remove,
+ .callback = rpmsg_echo_test_kern_app_cb,
};
static int __init init(void)
{
- return register_rpmsg_driver(&rpmsg_echo_test_kern_app);
+ return register_rpmsg_driver(&rpmsg_echo_test_kern_app_drv);
}
static void __exit fini(void)
{
- unregister_rpmsg_driver(&rpmsg_echo_test_kern_app);
+ unregister_rpmsg_driver(&rpmsg_echo_test_kern_app_drv);
}
module_init(init);
module_exit(fini);
-MODULE_DESCRIPTION("rpmsg echo test kernel application");
+
+MODULE_DESCRIPTION("Sample driver to exposes rpmsg svcs to userspace via a char device");
MODULE_LICENSE("GPL v2");
diff --git a/proxy/master/linux/kernelspace/rpmsg_proxy_dev_driver.c b/proxy/master/linux/kernelspace/rpmsg_proxy_dev_driver.c
index 117d5066f28c1ca3e8b968eb561d85a24e2f6c07..448af6e8e1bdffa402cfc3f623ccd518c9d31dae 100644 (file)
#include <linux/kthread.h>
#include <linux/ioctl.h>
#include <linux/errno.h>
-#include <linux/platform_device.h>
-#include <linux/of_platform.h>
-#include <linux/sysfs.h>
#define MAX_RPMSG_BUFF_SIZE 512
#define RPMSG_KFIFO_SIZE (MAX_RPMSG_BUFF_SIZE * 4)
.callback = rpmsg_proxy_dev_rpmsg_drv_cb,
};
-static ssize_t rpmsg_proxy_dev_id_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- ssize_t status;
-
- status = sprintf(buf, "%s\n",
- rpmsg_proxy_dev_drv_id_table[0].name);
- return status;
-}
-
-static DEVICE_ATTR(rpmsg_id, 0444, rpmsg_proxy_dev_id_show, NULL);
-
-static const struct attribute *rpmsg_dev_attrs[] = {
- &dev_attr_rpmsg_id.attr,
- NULL,
-};
-
-static const struct attribute_group rpmsg_dev_attr_group = {
- .attrs = (struct attribute **) rpmsg_dev_attrs,
-};
-
static int rpmsg_proxy_dev_rpmsg_drv_probe(struct rpmsg_channel *rpdev)
{
struct _rpmsg_dev_params *local;
dev_err(&rpdev->dev, "Cannot create device file.\n");
goto error2;
}
- /* Create sysfs group */
- status = sysfs_create_group(&(rpdev->dev.kobj), &rpmsg_dev_attr_group);
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
rpdev->src, rpdev->dst);
index f2956be32f0f7c514eaeedda0f88f86478db298f..78899ec37a978c8c28f9e76aabe43964e73ffcad 100644 (file)
#include <string.h>
#include <sys/ioctl.h>
#include <signal.h>
+#include <unistd.h>
#include "proxy_app.h"
#define RPC_BUFF_SIZE 512
+#define RPC_CHANNEL_READY_TO_CLOSE "rpc_channel_ready_to_close"
struct _proxy_data {
int active;
int handle_rpc(struct _sys_rpc *rpc)
{
int retval;
+ char *data = (char *)rpc;
+ if (!strcmp(data, RPC_CHANNEL_READY_TO_CLOSE)) {
+ proxy->active = 0;
+ return 0;
+ }
/* Handle RPC */
switch ((int)(rpc->id)) {
void exit_action_handler(int signum)
{
proxy->active = 0;
- printf("%s\n", __func__);
}
void kill_action_handler(int signum)
struct sigaction kill_action;
unsigned int bytes_rcvd;
int i = 0;
+ int ret = 0;
/* Initialize signalling infrastructure */
memset(&exit_action, 0, sizeof(struct sigaction));
/* Allocate memory for proxy data structure */
proxy = malloc(sizeof(struct _proxy_data));
+ if (proxy == 0) {
+ printf("\r\nMaster>Failed to allocate memory.\r\n");
+ return -1;
+ }
+ proxy->active = 1;
/* Open proxy rpmsg device */
printf("\r\nMaster>Opening rpmsg proxy device\r\n");
+ i = 0;
do {
proxy->rpmsg_proxy_fd = open("/dev/rpmsg_proxy0", O_RDWR);
+ sleep(1);
+ } while (proxy->rpmsg_proxy_fd < 0 && (i++ < 2));
- } while (proxy->rpmsg_proxy_fd < 0);
+ if (proxy->rpmsg_proxy_fd < 0) {
+ printf("\r\nMaster>Failed to open rpmsg proxy driver device file.\r\n");
+ ret = -1;
+ goto error0;
+ }
/* Allocate memory for rpc payloads */
- proxy->active = 1;
proxy->rpc = malloc(RPC_BUFF_SIZE);
proxy->rpc_response = malloc(RPC_BUFF_SIZE);
/* Free up resources */
free(proxy->rpc);
free(proxy->rpc_response);
+
+error0:
free(proxy);
/* Unload drivers */
system("modprobe -r virtio_ring");
system("modprobe -r virtio");
- return 0;
+ return ret;
}