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/init.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/drivers/ipm.h>
12 #include <zephyr/sys/printk.h>
13 #include <zephyr/device.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include <zephyr/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_sem, 0, 1);
27 static K_SEM_DEFINE(data_rx_sem, 0, 1);
28 
endpoint_cb(struct rpmsg_endpoint * ept,void * data,size_t len,uint32_t src,void * priv)29 int endpoint_cb(struct rpmsg_endpoint *ept, void *data,
30 		size_t len, uint32_t src, void *priv)
31 {
32 	received_data = *((unsigned int *) data);
33 
34 	k_sem_give(&data_rx_sem);
35 
36 	return RPMSG_SUCCESS;
37 }
38 
39 static int ep_id;
40 
receive_message(void)41 static unsigned int receive_message(void)
42 {
43 	k_sem_take(&data_rx_sem, K_FOREVER);
44 	return received_data;
45 }
46 
send_message(unsigned int message)47 static int send_message(unsigned int message)
48 {
49 	return rpmsg_service_send(ep_id, &message, sizeof(message));
50 }
51 
app_task(void * arg1,void * arg2,void * arg3)52 void app_task(void *arg1, void *arg2, void *arg3)
53 {
54 	ARG_UNUSED(arg1);
55 	ARG_UNUSED(arg2);
56 	ARG_UNUSED(arg3);
57 
58 	int status = 0;
59 	unsigned int message = 0U;
60 
61 	printk("\r\nRPMsg Service [remote] demo started\r\n");
62 
63 	while (message < 99) {
64 		message = receive_message();
65 		printk("Remote core received a message: %d\n", message);
66 
67 		message++;
68 		status = send_message(message);
69 		if (status < 0) {
70 			printk("send_message(%d) failed with status %d\n",
71 			       message, status);
72 			break;
73 		}
74 	}
75 
76 	printk("RPMsg Service demo ended.\n");
77 }
78 
main(void)79 int main(void)
80 {
81 	printk("Starting application thread!\n");
82 	k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE,
83 			app_task,
84 			NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
85 	return 0;
86 }
87 
88 /* Make sure we register endpoint before RPMsg Service is initialized. */
register_endpoint(void)89 int register_endpoint(void)
90 {
91 	int status;
92 
93 	status = rpmsg_service_register_endpoint("demo", endpoint_cb);
94 
95 	if (status < 0) {
96 		printk("rpmsg_create_ept failed %d\n", status);
97 		return status;
98 	}
99 
100 	ep_id = status;
101 
102 	return 0;
103 }
104 
105 SYS_INIT(register_endpoint, POST_KERNEL, CONFIG_RPMSG_SERVICE_EP_REG_PRIORITY);
106