Skip to content

Commit 2814a25

Browse files
committed
nrf_rpc: Add function for single group initialization
Adds the function nrf_rpc_init_group to allow initializing an nrf_rpc group individually. This is useful when groups need to be initialized in different boot stages. nrf_rpc_init now takes into account that a group could could be initialized using the nrf_rpc_init_group and avoids initializiting again. Signed-off-by: Georgios Vasilakis <[email protected]>
1 parent fb9c116 commit 2814a25

File tree

2 files changed

+135
-41
lines changed

2 files changed

+135
-41
lines changed

nrf_rpc/include/nrf_rpc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,20 @@ void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler);
357357
*/
358358
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler);
359359

360+
/** @brief Initialize a single nRF RPC group
361+
*
362+
* Initialize a single nRF RPC group. It can be used to initialize all groups using this function
363+
* and avoid calling nrf_rpc_init. It is also possible to initialize a subset of the groups and
364+
* then call nrf_rpc_init.
365+
* This function doesn't support providing an error handler, a default error handler will be used
366+
* if an erorr occurs. If a custom error handler is needed, use nrf_rpc_init.
367+
*
368+
* @param group Group to initialize
369+
*
370+
* @return 0 on success or negative error code.
371+
*/
372+
int nrf_rpc_init_group(const struct nrf_rpc_group *group);
373+
360374
/** @brief Send a command and provide callback to handle response.
361375
*
362376
* @param group Group that command belongs to.

nrf_rpc/nrf_rpc.c

Lines changed: 121 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -411,49 +411,51 @@ static void internal_tx_handler(void)
411411
}
412412
}
413413

414-
static int transport_init(nrf_rpc_tr_receive_handler_t receive_cb)
414+
static int transport_init_single(nrf_rpc_tr_receive_handler_t receive_cb, const struct nrf_rpc_group *group)
415415
{
416-
int err = 0;
417-
void *iter;
418-
const struct nrf_rpc_group *group;
416+
const struct nrf_rpc_tr *transport = group->transport;
417+
struct nrf_rpc_group_data *data = group->data;
418+
int err;
419419

420-
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
421-
const struct nrf_rpc_group)) {
422-
const struct nrf_rpc_tr *transport = group->transport;
423-
struct nrf_rpc_group_data *data = group->data;
420+
NRF_RPC_ASSERT(transport != NULL);
424421

425-
NRF_RPC_ASSERT(transport != NULL);
422+
if (group->data->transport_initialized) {
423+
return 0;
424+
}
426425

427-
/* Initialize all dependencies of `receive_handler` before calling the transport
428-
* init to avoid possible data race if `receive_handler` was invoked before this
429-
* function was completed. */
430-
if (auto_free_rx_buf(transport)) {
431-
err = nrf_rpc_os_event_init(&data->decode_done_event);
432-
if (err < 0) {
433-
continue;
434-
}
426+
/* Initialize all dependencies of `receive_handler` before calling the transport
427+
* init to avoid possible data race if `receive_handler` was invoked before this
428+
* function was completed. */
429+
if (auto_free_rx_buf(transport)) {
430+
err = nrf_rpc_os_event_init(&data->decode_done_event);
431+
if (err < 0) {
432+
return err;
435433
}
434+
}
436435

437-
err = transport->api->init(transport, receive_cb, NULL);
438-
if (err) {
439-
NRF_RPC_ERR("Failed to initialize transport, err: %d", err);
440-
continue;
441-
}
436+
err = transport->api->init(transport, receive_cb, NULL);
437+
if (err) {
438+
NRF_RPC_ERR("Failed to initialize transport, err: %d", err);
439+
return err;
440+
}
442441

443-
group->data->transport_initialized = true;
442+
group->data->transport_initialized = true;
444443

445-
if (group->flags & NRF_RPC_FLAGS_INITIATOR) {
446-
err = group_init_send(group);
447-
if (err) {
448-
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s err: %d",
449-
data->src_group_id, group->strid, err);
450-
continue;
451-
}
444+
if (group->flags & NRF_RPC_FLAGS_INITIATOR) {
445+
err = group_init_send(group);
446+
if (err) {
447+
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s err: %d",
448+
data->src_group_id, group->strid, err);
449+
return err;
452450
}
453451
}
454452

455-
/* Group initialization errors are not propagated to the caller. */
456-
err = 0;
453+
return 0;
454+
}
455+
456+
static int groups_init_event_wait(void)
457+
{
458+
int err = 0;
457459

458460
if (waiting_group_count > 0) {
459461
err = nrf_rpc_os_event_wait(&groups_init_event, CONFIG_NRF_RPC_GROUP_INIT_WAIT_TIME);
@@ -465,6 +467,27 @@ static int transport_init(nrf_rpc_tr_receive_handler_t receive_cb)
465467
return err;
466468
}
467469

470+
static int transport_init_all(nrf_rpc_tr_receive_handler_t receive_cb)
471+
{
472+
void *iter;
473+
const struct nrf_rpc_group *group;
474+
475+
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
476+
const struct nrf_rpc_group)) {
477+
478+
transport_init_single(receive_cb, group);
479+
}
480+
481+
/* Group initialization errors are not propagated to the caller. */
482+
return groups_init_event_wait();
483+
}
484+
485+
static void default_err_handler(const struct nrf_rpc_err_report *report)
486+
{
487+
NRF_RPC_ERR("nRF RPC error %d ocurred. See nRF RPC logs for more details", report->code);
488+
nrf_rpc_os_fatal_error();
489+
}
490+
468491
/* ======================== Receiving Packets ======================== */
469492

470493
/* Find in array and execute command or event handler */
@@ -1098,23 +1121,18 @@ void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler)
10981121
global_bound_handler = bound_handler;
10991122
}
11001123

1101-
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
1124+
static int nrf_rpc_prepare_init(void)
11021125
{
11031126
int err;
1104-
int i;
11051127
void *iter;
11061128
const struct nrf_rpc_group *group;
11071129
uint8_t group_id = 0;
11081130
uint8_t wait_count = 0;
11091131

1110-
NRF_RPC_DBG("Initializing nRF RPC module");
1111-
11121132
if (is_initialized) {
11131133
return 0;
11141134
}
11151135

1116-
global_err_handler = err_handler;
1117-
11181136
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
11191137
const struct nrf_rpc_group)) {
11201138
struct nrf_rpc_group_data *data = group->data;
@@ -1151,20 +1169,82 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11511169
return err;
11521170
}
11531171

1154-
for (i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) {
1172+
for (size_t i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) {
11551173
cmd_ctx_pool[i].id = i;
11561174
err = nrf_rpc_os_msg_init(&cmd_ctx_pool[i].recv_msg);
11571175
if (err < 0) {
11581176
return err;
11591177
}
11601178
}
11611179

1162-
err = transport_init(receive_handler);
1180+
global_err_handler = default_err_handler;
1181+
1182+
is_initialized = true;
1183+
1184+
return 0;
1185+
}
1186+
1187+
static bool all_groups_transport_finished(void){
1188+
void *iter;
1189+
const struct nrf_rpc_group *group;
1190+
1191+
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
1192+
const struct nrf_rpc_group)) {
1193+
if (!group->data->transport_initialized) {
1194+
return false;
1195+
}
1196+
}
1197+
1198+
return true;
1199+
}
1200+
1201+
int nrf_rpc_init_group(const struct nrf_rpc_group *group)
1202+
{
1203+
int err = nrf_rpc_prepare_init();
1204+
if (err < 0) {
1205+
return err;
1206+
}
1207+
1208+
err = transport_init_single(receive_handler, group);
1209+
if (err < 0) {
1210+
return err;
1211+
}
1212+
1213+
/* If all the groups have the their transport initialized this is the last call
1214+
* to nrf_rpc_init_group.
1215+
*/
1216+
if (all_groups_transport_finished()) {
1217+
return groups_init_event_wait();
1218+
}
1219+
1220+
return 0;
1221+
}
1222+
1223+
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
1224+
{
1225+
int err;
1226+
1227+
/* Everything is initialized, nothing to do here */
1228+
if (group_count > 0 && group_count == initialized_group_count) {
1229+
return 0;
1230+
}
1231+
1232+
NRF_RPC_DBG("Initializing nRF RPC module");
1233+
1234+
err = nrf_rpc_prepare_init();
1235+
if (err < 0) {
1236+
return err;
1237+
}
1238+
1239+
/* The nrf_rpc_prepare_init sets a default error handler,
1240+
* override it here with the one passed as parameter */
1241+
global_err_handler = err_handler;
1242+
1243+
err = transport_init_all(receive_handler);
11631244
if (err < 0) {
11641245
return err;
11651246
}
11661247

1167-
is_initialized = true;
11681248
NRF_RPC_DBG("Done initializing nRF RPC module");
11691249

11701250
return err;

0 commit comments

Comments
 (0)