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