Skip to content

Commit 279e37c

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 <georgios.vasilakis@nordicsemi.no>
1 parent 458cc62 commit 279e37c

File tree

2 files changed

+119
-41
lines changed

2 files changed

+119
-41
lines changed

nrf_rpc/include/nrf_rpc.h

+14
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

+105-41
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 */
@@ -1091,23 +1114,18 @@ void nrf_rpc_set_bound_handler(nrf_rpc_group_bound_handler_t bound_handler)
10911114
global_bound_handler = bound_handler;
10921115
}
10931116

1094-
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
1117+
static int nrf_rpc_prepare_init(void)
10951118
{
10961119
int err;
1097-
int i;
10981120
void *iter;
10991121
const struct nrf_rpc_group *group;
11001122
uint8_t group_id = 0;
11011123
uint8_t wait_count = 0;
11021124

1103-
NRF_RPC_DBG("Initializing nRF RPC module");
1104-
11051125
if (is_initialized) {
11061126
return 0;
11071127
}
11081128

1109-
global_err_handler = err_handler;
1110-
11111129
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array,
11121130
const struct nrf_rpc_group)) {
11131131
struct nrf_rpc_group_data *data = group->data;
@@ -1144,20 +1162,66 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
11441162
return err;
11451163
}
11461164

1147-
for (i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) {
1165+
for (size_t i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) {
11481166
cmd_ctx_pool[i].id = i;
11491167
err = nrf_rpc_os_msg_init(&cmd_ctx_pool[i].recv_msg);
11501168
if (err < 0) {
11511169
return err;
11521170
}
11531171
}
11541172

1155-
err = transport_init(receive_handler);
1173+
global_err_handler = default_err_handler;
1174+
1175+
is_initialized = true;
1176+
1177+
return 0;
1178+
}
1179+
1180+
int nrf_rpc_init_group(const struct nrf_rpc_group *group)
1181+
{
1182+
int err = nrf_rpc_prepare_init();
1183+
if (err < 0) {
1184+
return err;
1185+
}
1186+
1187+
err = transport_init_single(receive_handler, group);
1188+
if (err < 0) {
1189+
return err;
1190+
}
1191+
1192+
NRF_RPC_ASSERT(group_count > 0);
1193+
if (initialized_group_count == group_count - 1) {
1194+
return groups_init_event_wait();
1195+
}
1196+
1197+
return 0;
1198+
}
1199+
1200+
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler)
1201+
{
1202+
int err;
1203+
1204+
/* Everything is initialized, nothing to do here */
1205+
if (group_count > 0 && group_count == initialized_group_count) {
1206+
return 0;
1207+
}
1208+
1209+
NRF_RPC_DBG("Initializing nRF RPC module");
1210+
1211+
err = nrf_rpc_prepare_init();
1212+
if (err < 0) {
1213+
return err;
1214+
}
1215+
1216+
/* The nrf_rpc_prepare_init sets a default error handler,
1217+
* override it here with the one passed as parameter */
1218+
global_err_handler = err_handler;
1219+
1220+
err = transport_init_all(receive_handler);
11561221
if (err < 0) {
11571222
return err;
11581223
}
11591224

1160-
is_initialized = true;
11611225
NRF_RPC_DBG("Done initializing nRF RPC module");
11621226

11631227
return err;

0 commit comments

Comments
 (0)