Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions modules/hal_nordic/nrfs/backends/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,19 @@ config NRFS_BACKEND_TX_MSG_QUEUE_SIZE
range 1 16
default 8

config NRFS_SEND_RETRY_DELAY
int "Delay in us"
range 1 100
default 1
help
Delay when waiting for next message send retry in case of send error.

config NRFS_SEND_RETRY_MAX_COUNT
int "Max number of send retries"
range 0 100
default 5
help
How many times nrfs will try to send message over ipc service until
error will be reported. For example when shared ipc memory is full.

endmenu
43 changes: 39 additions & 4 deletions modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ __weak void nrfs_backend_error_handler(enum nrfs_backend_error error_id, int err
LOG_ERR("IPC register endpoint failure with error: %d", error);
break;

case NRFS_ERROR_SEND_DATA_FROM_QUEUE:
LOG_ERR("IPC backend sent data failed.");
break;

default:
LOG_ERR("Undefined error id: %d, error cause: %d", error_id, error);
break;
Expand Down Expand Up @@ -120,14 +124,45 @@ static void ipc_sysctrl_ept_recv(const void *data, size_t size, void *priv)
}
}

/**
* @brief This function will try to send data directly using ipc service
* In case of errors it will retry if configured.
*
* @param message Pointer to the buffer to send.
* @param size Number of bytes to send.
* @retval NRFS_SUCCESS Message sent successfully.
* @retval NRFS_ERR_IPC Backend returned error during message sending.
*/
static nrfs_err_t nrfs_backend_try_send_directly_over_ipc_service(void *message, size_t size)
{
size_t retry_count = CONFIG_NRFS_SEND_RETRY_MAX_COUNT + 1;
int ret = 0;

do {
ret = ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, message, size);
if (ret < (int)size) {
k_usleep(CONFIG_NRFS_SEND_RETRY_DELAY);
} else {
return NRFS_SUCCESS;
}
} while (--retry_count);

return NRFS_ERR_IPC;
}

static void nrfs_backend_send_work(struct k_work *item)
{
struct ipc_data_packet data_to_send;

LOG_DBG("Sending data from workqueue");
while (k_msgq_get(&ipc_transmit_msgq, &data_to_send, K_NO_WAIT) == 0) {
ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, &data_to_send.data,
data_to_send.size);

nrfs_err_t ret = nrfs_backend_try_send_directly_over_ipc_service(&data_to_send.data,
data_to_send.size);

if (ret != NRFS_SUCCESS) {
nrfs_backend_error_handler(NRFS_ERROR_SEND_DATA_FROM_QUEUE, 0, true);
}
}
}

Expand Down Expand Up @@ -177,8 +212,8 @@ nrfs_err_t nrfs_backend_send(void *message, size_t size)
nrfs_err_t nrfs_backend_send_ex(void *message, size_t size, k_timeout_t timeout, bool high_prio)
{
if (!k_is_in_isr() && nrfs_backend_connected()) {
return ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, message, size) ?
NRFS_SUCCESS : NRFS_ERR_IPC;
return nrfs_backend_try_send_directly_over_ipc_service(message, size);

} else if (size <= MAX_PACKET_DATA_SIZE) {
int err;
struct ipc_data_packet tx_data;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum nrfs_backend_error {
NRFS_ERROR_IPC_OPEN_INSTANCE,
NRFS_ERROR_IPC_REGISTER_ENDPOINT,
NRFS_ERROR_BACKEND_NOT_CONNECTED,
NRFS_ERROR_SEND_DATA_FROM_QUEUE,
NRFS_ERROR_COUNT
};

Expand Down