-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
nrf_rpc: Add function for single group initialization #1593
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -411,49 +411,51 @@ static void internal_tx_handler(void) | |
} | ||
} | ||
|
||
static int transport_init(nrf_rpc_tr_receive_handler_t receive_cb) | ||
static int transport_init_single(nrf_rpc_tr_receive_handler_t receive_cb, const struct nrf_rpc_group *group) | ||
{ | ||
int err = 0; | ||
void *iter; | ||
const struct nrf_rpc_group *group; | ||
const struct nrf_rpc_tr *transport = group->transport; | ||
struct nrf_rpc_group_data *data = group->data; | ||
int err; | ||
|
||
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array, | ||
const struct nrf_rpc_group)) { | ||
const struct nrf_rpc_tr *transport = group->transport; | ||
struct nrf_rpc_group_data *data = group->data; | ||
NRF_RPC_ASSERT(transport != NULL); | ||
|
||
NRF_RPC_ASSERT(transport != NULL); | ||
if (group->data->transport_initialized) { | ||
return 0; | ||
} | ||
|
||
/* Initialize all dependencies of `receive_handler` before calling the transport | ||
* init to avoid possible data race if `receive_handler` was invoked before this | ||
* function was completed. */ | ||
if (auto_free_rx_buf(transport)) { | ||
err = nrf_rpc_os_event_init(&data->decode_done_event); | ||
if (err < 0) { | ||
continue; | ||
} | ||
/* Initialize all dependencies of `receive_handler` before calling the transport | ||
* init to avoid possible data race if `receive_handler` was invoked before this | ||
* function was completed. */ | ||
if (auto_free_rx_buf(transport)) { | ||
err = nrf_rpc_os_event_init(&data->decode_done_event); | ||
if (err < 0) { | ||
return err; | ||
} | ||
} | ||
|
||
err = transport->api->init(transport, receive_cb, NULL); | ||
if (err) { | ||
NRF_RPC_ERR("Failed to initialize transport, err: %d", err); | ||
continue; | ||
} | ||
err = transport->api->init(transport, receive_cb, NULL); | ||
if (err) { | ||
NRF_RPC_ERR("Failed to initialize transport, err: %d", err); | ||
return err; | ||
} | ||
|
||
group->data->transport_initialized = true; | ||
group->data->transport_initialized = true; | ||
|
||
if (group->flags & NRF_RPC_FLAGS_INITIATOR) { | ||
err = group_init_send(group); | ||
if (err) { | ||
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s err: %d", | ||
data->src_group_id, group->strid, err); | ||
continue; | ||
} | ||
if (group->flags & NRF_RPC_FLAGS_INITIATOR) { | ||
err = group_init_send(group); | ||
if (err) { | ||
NRF_RPC_ERR("Failed to send group init packet for group id: %d strid: %s err: %d", | ||
data->src_group_id, group->strid, err); | ||
return err; | ||
} | ||
} | ||
|
||
/* Group initialization errors are not propagated to the caller. */ | ||
err = 0; | ||
return 0; | ||
} | ||
|
||
static int groups_init_event_wait(void) | ||
{ | ||
int err = 0; | ||
|
||
if (waiting_group_count > 0) { | ||
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) | |
return err; | ||
} | ||
|
||
static int transport_init_all(nrf_rpc_tr_receive_handler_t receive_cb) | ||
{ | ||
void *iter; | ||
const struct nrf_rpc_group *group; | ||
|
||
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array, | ||
const struct nrf_rpc_group)) { | ||
|
||
transport_init_single(receive_cb, group); | ||
} | ||
|
||
/* Group initialization errors are not propagated to the caller. */ | ||
return groups_init_event_wait(); | ||
} | ||
|
||
static void default_err_handler(const struct nrf_rpc_err_report *report) | ||
Damian-Nordic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
NRF_RPC_ERR("nRF RPC error %d ocurred. See nRF RPC logs for more details", report->code); | ||
nrf_rpc_os_fatal_error(); | ||
} | ||
|
||
/* ======================== Receiving Packets ======================== */ | ||
|
||
/* 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) | |
global_bound_handler = bound_handler; | ||
} | ||
|
||
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler) | ||
static int nrf_rpc_prepare_init(void) | ||
{ | ||
int err; | ||
int i; | ||
void *iter; | ||
const struct nrf_rpc_group *group; | ||
uint8_t group_id = 0; | ||
uint8_t wait_count = 0; | ||
|
||
NRF_RPC_DBG("Initializing nRF RPC module"); | ||
|
||
if (is_initialized) { | ||
return 0; | ||
} | ||
|
||
global_err_handler = err_handler; | ||
|
||
for (NRF_RPC_AUTO_ARR_FOR(iter, group, &nrf_rpc_groups_array, | ||
const struct nrf_rpc_group)) { | ||
struct nrf_rpc_group_data *data = group->data; | ||
|
@@ -1144,20 +1162,66 @@ int nrf_rpc_init(nrf_rpc_err_handler_t err_handler) | |
return err; | ||
} | ||
|
||
for (i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) { | ||
for (size_t i = 0; i < CONFIG_NRF_RPC_CMD_CTX_POOL_SIZE; i++) { | ||
cmd_ctx_pool[i].id = i; | ||
err = nrf_rpc_os_msg_init(&cmd_ctx_pool[i].recv_msg); | ||
if (err < 0) { | ||
return err; | ||
} | ||
} | ||
|
||
err = transport_init(receive_handler); | ||
global_err_handler = default_err_handler; | ||
|
||
is_initialized = true; | ||
|
||
return 0; | ||
} | ||
|
||
int nrf_rpc_init_group(const struct nrf_rpc_group *group) | ||
{ | ||
int err = nrf_rpc_prepare_init(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that this code is not thread-safe. Is there an assumption that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right that this is not thread safe, but is it not the case that the whole nrf_pc is not thread safe? The variable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calling nRF RPC commands is thread-safe as far as I understand but the init is not. @doki-nordic has more background but my impression is that the authors originally assumed that that the init would be called once. If we now allow more flexibility it becomes harder to enforce this, especially if this is not documented. |
||
if (err < 0) { | ||
return err; | ||
} | ||
|
||
err = transport_init_single(receive_handler, group); | ||
if (err < 0) { | ||
return err; | ||
} | ||
|
||
NRF_RPC_ASSERT(group_count > 0); | ||
if (initialized_group_count == group_count - 1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't you use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I was trying to do here to here is to call the event_wait function only for the last group which was getting initialized. The function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, so another issue is that if you have two groups and you execute |
||
return groups_init_event_wait(); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int nrf_rpc_init(nrf_rpc_err_handler_t err_handler) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, I changed that. |
||
{ | ||
int err; | ||
|
||
/* Everything is initialized, nothing to do here */ | ||
if (group_count > 0 && group_count == initialized_group_count) { | ||
return 0; | ||
} | ||
|
||
NRF_RPC_DBG("Initializing nRF RPC module"); | ||
|
||
err = nrf_rpc_prepare_init(); | ||
if (err < 0) { | ||
return err; | ||
} | ||
|
||
/* The nrf_rpc_prepare_init sets a default error handler, | ||
* override it here with the one passed as parameter */ | ||
global_err_handler = err_handler; | ||
|
||
err = transport_init_all(receive_handler); | ||
if (err < 0) { | ||
return err; | ||
} | ||
|
||
is_initialized = true; | ||
NRF_RPC_DBG("Done initializing nRF RPC module"); | ||
|
||
return err; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error is not checked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is intentional though, because I saw in the previous implementation they didn't return an error when a single initialization failed.
The logic here:
sdk-nrfxlib/nrf_rpc/nrf_rpc.c
Line 420 in 4929937
Should be the same with the logic in the function transport_init_single basically.
The error that I return in this function is the logic which exists here:
sdk-nrfxlib/nrf_rpc/nrf_rpc.c
Line 458 in 4929937