22// SPDX-License-Identifier: MPL-2.0
33#include " RPC.h"
44
5- #define ENDPOINT_ID_RAW 0
6- #define ENDPOINT_ID_RPC 1
7-
8- #define MSGPACK_TYPE_REQUEST 0
9- #define MSGPACK_TYPE_RESPONSE 1
10- #define MSGPACK_TYPE_NOTIFY 2
5+ typedef struct {
6+ const char *name;
7+ bool ready;
8+ struct rpmsg_endpoint rpmsg;
9+ } endpoint_t ;
10+
11+ typedef enum {
12+ ENDPOINT_ID_RAW,
13+ ENDPOINT_ID_RPC,
14+ ENDPOINT_ID_MAX
15+ } endpoint_id_t ;
16+
17+ typedef enum {
18+ MSGPACK_ID_REQUEST,
19+ MSGPACK_ID_RESPONSE,
20+ MSGPACK_ID_NOTIFY,
21+ } msgpack_id_t ;
22+
23+ static endpoint_t endpoints[ENDPOINT_ID_MAX] = {
24+ [ENDPOINT_ID_RAW] = { .name = " raw" , .ready = false , .rpmsg = { 0 } },
25+ [ENDPOINT_ID_RPC] = { .name = " rpc" , .ready = false , .rpmsg = { 0 } },
26+ };
1127
1228arduino::RPCClass RPC;
13-
14- osThreadId eventHandlerThreadId;
1529static rtos::Mutex mutex;
16- static struct rpmsg_endpoint endpoints[2 ];
17- #ifdef CORE_CM4
18- static bool endpoints_init[2 ] = { 0 };
19- #endif
30+ osThreadId eventHandlerThreadId;
2031
2132void RPCClass::new_service_cb (struct rpmsg_device *rdev, const char *name, uint32_t dest) {
2233 uint8_t buffer[1 ] = {0 };
23- struct rpmsg_endpoint *ept = NULL ;
24-
25- if (strcmp (name, " rpc" ) == 0 ) {
26- ept = &endpoints[ENDPOINT_ID_RPC];
27- } else if (strcmp (name, " raw" ) == 0 ) {
28- ept = &endpoints[ENDPOINT_ID_RAW];
29- }
30-
31- if (ept) {
32- OPENAMP_create_endpoint (ept, name, dest, rpmsg_recv_callback, NULL );
33- OPENAMP_send (ept, buffer, sizeof (buffer));
34+ for (size_t i=0 ; i<ENDPOINT_ID_MAX; i++) {
35+ endpoint_t *ep = &endpoints[i];
36+ if (strcmp (name, ep->name ) == 0 ) {
37+ OPENAMP_create_endpoint (&ep->rpmsg , name, dest, rpmsg_recv_callback, NULL );
38+ OPENAMP_send (&ep->rpmsg , buffer, sizeof (buffer));
39+ break ;
40+ }
3441 }
3542}
3643
3744int RPCClass::rpmsg_recv_callback (struct rpmsg_endpoint *ept, void *data, size_t len, uint32_t src, void *priv) {
3845 #ifdef CORE_CM4
39- if (!endpoints_init[ENDPOINT_ID_RPC] && ept == &endpoints[ENDPOINT_ID_RPC] ) {
40- endpoints_init[ENDPOINT_ID_RPC] = true ;
41- return 0 ;
42- } else if (!endpoints_init[ENDPOINT_ID_RAW] && ept == &endpoints[ENDPOINT_ID_RAW]) {
43- endpoints_init[ENDPOINT_ID_RAW] = true ;
44- return 0 ;
46+ for ( size_t i= 0 ; i<ENDPOINT_ID_MAX; i++ ) {
47+ endpoint_t *ep = &endpoints[i] ;
48+ if (ept == &ep-> rpmsg && !ep-> ready ) {
49+ ep-> ready = true ;
50+ return 0 ;
51+ }
4552 }
4653 #endif
4754
48- if (ept == &endpoints[ENDPOINT_ID_RAW]) {
55+ if (ept == &endpoints[ENDPOINT_ID_RAW]. rpmsg ) {
4956 // data on raw endpoint
5057 if (RPC.raw_callback ) {
5158 RPC.raw_callback .call ((uint8_t *) data, len);
@@ -59,11 +66,11 @@ int RPCClass::rpmsg_recv_callback(struct rpmsg_endpoint *ept, void *data, size_t
5966
6067 uint8_t msgpack_type = ((uint8_t *) data)[1 ];
6168 switch (msgpack_type) {
62- case MSGPACK_TYPE_REQUEST :
63- case MSGPACK_TYPE_NOTIFY :
69+ case MSGPACK_ID_REQUEST :
70+ case MSGPACK_ID_NOTIFY :
6471 RPC.request ((uint8_t *) data, len);
6572 break ;
66- case MSGPACK_TYPE_RESPONSE :
73+ case MSGPACK_ID_RESPONSE :
6774 RPC.response ((uint8_t *) data, len);
6875 break ;
6976 }
@@ -144,15 +151,18 @@ int RPCClass::begin() {
144151 return 0 ;
145152 }
146153
147- // Initialize rpmsg endpoints.
148- memset (endpoints, 0 , sizeof (endpoints));
149-
150154 // Boot the CM4.
151155 cm4_kick ();
152156
153157 // Wait for the remote to announce the services with a timeout.
154- uint32_t millis_start = millis ();
155- while (endpoints[ENDPOINT_ID_RPC].rdev == NULL || endpoints[ENDPOINT_ID_RAW].rdev == NULL ) {
158+ for (uint32_t millis_start = millis (); ; ) {
159+ size_t ep_count = 0 ;
160+ for (size_t i=0 ; i<ENDPOINT_ID_MAX; i++) {
161+ ep_count += (endpoints[i].rdev != NULL );
162+ }
163+ if (ep_count == ENDPOINT_ID_MAX) {
164+ break ;
165+ }
156166 if ((millis () - millis_start) >= 5000 ) {
157167 return 0 ;
158168 }
@@ -203,20 +213,24 @@ int RPCClass::begin() {
203213 return 0 ;
204214 }
205215
206- // Create RAW endpoint.
207- if (OPENAMP_create_endpoint (&endpoints[ENDPOINT_ID_RAW], " raw" , RPMSG_ADDR_ANY, rpmsg_recv_callback, NULL ) < 0 ) {
208- return 0 ;
209- }
210-
211- // Create RPC endpoint.
212- if (OPENAMP_create_endpoint (&endpoints[ENDPOINT_ID_RPC], " rpc" , RPMSG_ADDR_ANY, rpmsg_recv_callback, NULL ) < 0 ) {
213- return 0 ;
216+ // Create endpoints.
217+ for (size_t i=0 ; i<ENDPOINT_ID_MAX; i++) {
218+ endpoint_t *ep = &endpoints[i];
219+ if (OPENAMP_create_endpoint (&ep->rpmsg , ep->name , RPMSG_ADDR_ANY, rpmsg_recv_callback, NULL ) < 0 ) {
220+ return 0 ;
221+ }
214222 }
215223
216- // Wait for endpoints to be initialized first by the host before allowing
224+ // Wait for endpoints to be ready first by the host before allowing
217225 // the remote to use the endpoints.
218- uint32_t millis_start = millis ();
219- while (!endpoints_init[ENDPOINT_ID_RPC] || !endpoints_init[ENDPOINT_ID_RAW]) {
226+ for (uint32_t millis_start = millis (); ; ) {
227+ size_t ep_count = 0 ;
228+ for (size_t i=0 ; i<ENDPOINT_ID_MAX; i++) {
229+ ep_count += endpoints[i].ready ;
230+ }
231+ if (ep_count == ENDPOINT_ID_MAX) {
232+ break ;
233+ }
220234 if ((millis () - millis_start) >= 5000 ) {
221235 return 0 ;
222236 }
@@ -267,7 +281,8 @@ void RPCClass::request(uint8_t *buf, size_t len) {
267281 auto resp = rpc::detail::dispatcher::dispatch (msg, false );
268282 auto data = resp.get_data ();
269283 if (!resp.is_empty ()) {
270- OPENAMP_send (&endpoints[ENDPOINT_ID_RPC], data.data (), data.size ());
284+ endpoint_t *ep = &endpoints[ENDPOINT_ID_RPC];
285+ OPENAMP_send (&ep->rpmsg , data.data (), data.size ());
271286 }
272287 }
273288}
@@ -282,7 +297,7 @@ void rpc::client::write(RPCLIB_MSGPACK::sbuffer *buffer) {
282297
283298size_t RPCClass::write (const uint8_t *buf, size_t len, bool raw) {
284299 mutex.lock ();
285- OPENAMP_send (&endpoints[raw ? ENDPOINT_ID_RAW : ENDPOINT_ID_RPC], buf, len);
300+ OPENAMP_send (&endpoints[raw ? ENDPOINT_ID_RAW : ENDPOINT_ID_RPC]. rpmsg , buf, len);
286301 mutex.unlock ();
287302 return len;
288303}
0 commit comments