1 /*
2 * Copyright (c) 2018, NXP
3 * Copyright (c) 2018-2019, Linaro Limited
4 * Copyright (c) 2018-2021, Nordic Semiconductor ASA
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #include <zephyr.h>
10 #include <drivers/ipm.h>
11 #include <sys/printk.h>
12 #include <device.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <init.h>
17
18 #include <ipc/rpmsg_service.h>
19
20 #define APP_TASK_STACK_SIZE (1024)
21 K_THREAD_STACK_DEFINE(thread_stack, APP_TASK_STACK_SIZE);
22 static struct k_thread thread_data;
23
24 static volatile unsigned int received_data;
25
26 static K_SEM_DEFINE(data_rx_sem, 0, 1);
27
endpoint_cb(struct rpmsg_endpoint * ept,void * data,size_t len,uint32_t src,void * priv)28 int endpoint_cb(struct rpmsg_endpoint *ept, void *data,
29 size_t len, uint32_t src, void *priv)
30 {
31 received_data = *((unsigned int *) data);
32
33 k_sem_give(&data_rx_sem);
34
35 return RPMSG_SUCCESS;
36 }
37
38 static int ep_id;
39 struct rpmsg_endpoint my_ept;
40 struct rpmsg_endpoint *ep = &my_ept;
41
receive_message(void)42 static unsigned int receive_message(void)
43 {
44 k_sem_take(&data_rx_sem, K_FOREVER);
45 return received_data;
46 }
47
send_message(unsigned int message)48 static int send_message(unsigned int message)
49 {
50 return rpmsg_service_send(ep_id, &message, sizeof(message));
51 }
52
app_task(void * arg1,void * arg2,void * arg3)53 void app_task(void *arg1, void *arg2, void *arg3)
54 {
55 ARG_UNUSED(arg1);
56 ARG_UNUSED(arg2);
57 ARG_UNUSED(arg3);
58 int status = 0;
59 unsigned int message = 0U;
60
61 printk("\r\nRPMsg Service [master] demo started\r\n");
62
63 /* Since we are using name service, we need to wait for a response
64 * from NS setup and than we need to process it
65 */
66 while (!rpmsg_service_endpoint_is_bound(ep_id)) {
67 k_sleep(K_MSEC(1));
68 }
69
70 while (message < 100) {
71 status = send_message(message);
72 if (status < 0) {
73 printk("send_message(%d) failed with status %d\n",
74 message, status);
75 break;
76 }
77
78 message = receive_message();
79 printk("Master core received a message: %d\n", message);
80
81 message++;
82 }
83
84 printk("RPMsg Service demo ended.\n");
85 }
86
main(void)87 void main(void)
88 {
89 printk("Starting application thread!\n");
90 k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE,
91 (k_thread_entry_t)app_task,
92 NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
93
94 #if defined(CONFIG_SOC_MPS2_AN521) || \
95 defined(CONFIG_SOC_V2M_MUSCA_B1)
96 wakeup_cpu1();
97 k_msleep(500);
98 #endif /* #if defined(CONFIG_SOC_MPS2_AN521) */
99 }
100
101 /* Make sure we register endpoint before RPMsg Service is initialized. */
register_endpoint(const struct device * arg)102 int register_endpoint(const struct device *arg)
103 {
104 int status;
105
106 status = rpmsg_service_register_endpoint("demo", endpoint_cb);
107
108 if (status < 0) {
109 printk("rpmsg_create_ept failed %d\n", status);
110 return status;
111 }
112
113 ep_id = status;
114
115 return 0;
116 }
117
118 SYS_INIT(register_endpoint, POST_KERNEL, CONFIG_RPMSG_SERVICE_EP_REG_PRIORITY);
119