1 /*
2 * Copyright (c) 2021 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr.h>
8 #include <drivers/ipm.h>
9 #include <sys/printk.h>
10 #include <device.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <ipc/ipc_service.h>
16
17 #define APP_TASK_STACK_SIZE 1024
18
19 K_THREAD_STACK_DEFINE(thread_stack_1, APP_TASK_STACK_SIZE);
20 K_THREAD_STACK_DEFINE(thread_stack_2, APP_TASK_STACK_SIZE);
21
22 static struct k_thread thread_data_1;
23 static struct k_thread thread_data_2;
24
25 static volatile uint8_t received_data_1;
26 static volatile uint8_t received_data_2;
27
28 static K_SEM_DEFINE(bound_ept1_sem, 0, 1);
29 static K_SEM_DEFINE(bound_ept2_sem, 0, 1);
30
31 static K_SEM_DEFINE(data_rx1_sem, 0, 1);
32 static K_SEM_DEFINE(data_rx2_sem, 0, 1);
33
34 static struct ipc_ept *ept_1;
35 static struct ipc_ept *ept_2;
36
ept_bound_1(void * priv)37 static void ept_bound_1(void *priv)
38 {
39 k_sem_give(&bound_ept1_sem);
40 }
41
ept_recv_1(const void * data,size_t len,void * priv)42 static void ept_recv_1(const void *data, size_t len, void *priv)
43 {
44 received_data_1 = *((uint8_t *) data);
45 k_sem_give(&data_rx1_sem);
46 }
47
ept_error_1(const char * message,void * priv)48 static void ept_error_1(const char *message, void *priv)
49 {
50 printk("Endpoint [1] error: %s", message);
51 }
52
ept_bound_2(void * priv)53 static void ept_bound_2(void *priv)
54 {
55 k_sem_give(&bound_ept2_sem);
56 }
57
ept_recv_2(const void * data,size_t len,void * priv)58 static void ept_recv_2(const void *data, size_t len, void *priv)
59 {
60 received_data_2 = *((uint8_t *) data);
61 k_sem_give(&data_rx2_sem);
62 }
63
ept_error_2(const char * message,void * priv)64 static void ept_error_2(const char *message, void *priv)
65 {
66 printk("Endpoint [2] error: %s", message);
67 }
68
app_task_1(void * arg1,void * arg2,void * arg3)69 void app_task_1(void *arg1, void *arg2, void *arg3)
70 {
71 ARG_UNUSED(arg1);
72 ARG_UNUSED(arg2);
73 ARG_UNUSED(arg3);
74 int status = 0;
75 uint8_t message = 0U;
76
77 printk("\r\nIPC Service [remote 1] demo started\r\n");
78
79 static struct ipc_ept_cfg ept_cfg = {
80 .name = "ep_1",
81 .prio = 0,
82 .priv = NULL,
83 .cb = {
84 .bound = ept_bound_1,
85 .received = ept_recv_1,
86 .error = ept_error_1,
87 },
88 };
89
90 status = ipc_service_register_endpoint(&ept_1, &ept_cfg);
91 if (status < 0) {
92 printk("ipc_service_register_endpoint failed %d\n", status);
93 return;
94 }
95
96 k_sem_take(&bound_ept1_sem, K_FOREVER);
97
98 while (message < 99) {
99 k_sem_take(&data_rx1_sem, K_FOREVER);
100 message = received_data_1;
101 printk("Remote [1] received a message: %d\n", message);
102
103 message++;
104 status = ipc_service_send(ept_1, &message, sizeof(message));
105 if (status < 0) {
106 printk("send_message(%d) failed with status %d\n",
107 message, status);
108 break;
109 }
110 }
111
112 printk("IPC Service [remote 1] demo ended.\n");
113 }
114
app_task_2(void * arg1,void * arg2,void * arg3)115 void app_task_2(void *arg1, void *arg2, void *arg3)
116 {
117 ARG_UNUSED(arg1);
118 ARG_UNUSED(arg2);
119 ARG_UNUSED(arg3);
120 int status = 0;
121 uint8_t message = 0U;
122
123 printk("\r\nIPC Service [remote 2] demo started\r\n");
124
125 static struct ipc_ept_cfg ept_cfg = {
126 .name = "ep_2",
127 .prio = 0,
128 .priv = NULL,
129 .cb = {
130 .bound = ept_bound_2,
131 .received = ept_recv_2,
132 .error = ept_error_2,
133 },
134 };
135
136 status = ipc_service_register_endpoint(&ept_2, &ept_cfg);
137
138 if (status < 0) {
139 printk("ipc_service_register_endpoint failed %d\n", status);
140 return;
141 }
142
143 k_sem_take(&bound_ept2_sem, K_FOREVER);
144
145 while (message < 99) {
146 k_sem_take(&data_rx2_sem, K_FOREVER);
147 message = received_data_2;
148 printk("Remote [2] received a message: %d\n", message);
149
150 message++;
151 status = ipc_service_send(ept_2, &message, sizeof(message));
152 if (status < 0) {
153 printk("send_message(%d) failed with status %d\n",
154 message, status);
155 break;
156 }
157 }
158
159 printk("IPC Service [remote 2] demo ended.\n");
160 }
161
main(void)162 void main(void)
163 {
164 k_thread_create(&thread_data_1, thread_stack_1, APP_TASK_STACK_SIZE,
165 (k_thread_entry_t)app_task_1,
166 NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
167
168 k_thread_create(&thread_data_2, thread_stack_2, APP_TASK_STACK_SIZE,
169 (k_thread_entry_t)app_task_2,
170 NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);
171 }
172