Skip to content

Commit bc5b39e

Browse files
committed
[nrf fromlist] modules: hal_nordic: nrfs: improve error handling
Added option to retry message send over ipc when for example there is -ENOMEM error (shared memory buffer full). Number of max retries and delay between them are Kconfigs. Fixed nrfs error reporting when sending directly over ipc service, status was not correct when negative value was returned from ipc service send function. Upstream PR #: 84499 Signed-off-by: Łukasz Stępnicki <[email protected]>
1 parent 954583a commit bc5b39e

File tree

3 files changed

+71
-17
lines changed

3 files changed

+71
-17
lines changed

modules/hal_nordic/nrfs/backends/Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,19 @@ config NRFS_BACKEND_TX_MSG_QUEUE_SIZE
2525
range 1 16
2626
default 8
2727

28+
config NRFS_SEND_RETRY_DELAY
29+
int "Delay in us"
30+
range 1 100
31+
default 1
32+
help
33+
Delay when waiting for next message send retry in case of send error.
34+
35+
config NRFS_SEND_RETRY_MAX_COUNT
36+
int "Max number of send retries"
37+
range 0 100
38+
default 5
39+
help
40+
How many times nrfs will try to send message over ipc service until
41+
error will be reported. For example when shared ipc memory is full.
42+
2843
endmenu

modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.c

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(NRFS_BACKEND, CONFIG_NRFS_BACKEND_LOG_LEVEL);
2020
#define MAX_PACKET_DATA_SIZE (CONFIG_NRFS_MAX_BACKEND_PACKET_SIZE)
2121

2222
K_MSGQ_DEFINE(ipc_transmit_msgq, sizeof(struct ipc_data_packet),
23-
CONFIG_NRFS_BACKEND_TX_MSG_QUEUE_SIZE, 4);
23+
CONFIG_NRFS_BACKEND_TX_MSG_QUEUE_SIZE, 4);
2424

2525
static struct k_work backend_send_work;
2626

@@ -41,18 +41,17 @@ struct ipc_channel_config {
4141

4242
static struct ipc_ept_cfg ipc_sysctrl_ept_cfg = {
4343
.name = "ipc_to_sysctrl",
44-
.cb = {
45-
.bound = ipc_sysctrl_ept_bound,
46-
.received = ipc_sysctrl_ept_recv,
47-
},
44+
.cb = {
45+
.bound = ipc_sysctrl_ept_bound,
46+
.received = ipc_sysctrl_ept_recv,
47+
},
4848
};
4949

5050
static struct ipc_channel_config ipc_cpusys_channel_config = {
51-
.ipc_instance = DEVICE_DT_GET(DT_ALIAS(ipc_to_cpusys)),
51+
.ipc_instance = DEVICE_DT_GET(DT_ALIAS(ipc_to_cpusys)),
5252
.endpoint_config = &ipc_sysctrl_ept_cfg,
53-
.status = ATOMIC_INIT(NOT_CONNECTED),
54-
.enabled = true
55-
};
53+
.status = ATOMIC_INIT(NOT_CONNECTED),
54+
.enabled = true};
5655

5756
/**
5857
* @brief nrfs backend error handler
@@ -80,6 +79,14 @@ __weak void nrfs_backend_error_handler(enum nrfs_backend_error error_id, int err
8079
LOG_ERR("IPC register endpoint failure with error: %d", error);
8180
break;
8281

82+
case NRFS_ERROR_SEND_DATA_FROM_QUEUE:
83+
if (error >= 0) {
84+
LOG_ERR("IPC not all data sent from queue, bytes sent: %d", error);
85+
} else {
86+
LOG_ERR("IPC backend sent with error %d", error);
87+
}
88+
break;
89+
8390
default:
8491
LOG_ERR("Undefined error id: %d, error cause: %d", error_id, error);
8592
break;
@@ -108,7 +115,7 @@ static void ipc_sysctrl_ept_recv(const void *data, size_t size, void *priv)
108115
__ASSERT(size <= MAX_PACKET_DATA_SIZE, "Received data is too long. Config error.");
109116
if (size <= MAX_PACKET_DATA_SIZE) {
110117
rx_data.channel_id = IPC_CPUSYS_CHANNEL_ID;
111-
rx_data.size = size;
118+
rx_data.size = size;
112119
if (data) {
113120
memcpy(rx_data.data, (uint8_t *)data, size);
114121
nrfs_dispatcher_notify(&rx_data.data, rx_data.size);
@@ -120,14 +127,44 @@ static void ipc_sysctrl_ept_recv(const void *data, size_t size, void *priv)
120127
}
121128
}
122129

130+
/**
131+
* @brief This function will try to send data directly using ipc service
132+
* In case of errors it will retry if configured.
133+
*
134+
* @param message Pointer to the buffer to send.
135+
* @param size Number of bytes to send.
136+
* @return see function @ref ipc_service_send
137+
*/
138+
static int nrfs_backend_try_send_directly_over_ipc_service(void *message, size_t size)
139+
{
140+
size_t retry_count = CONFIG_NRFS_SEND_RETRY_MAX_COUNT;
141+
int ret = ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, message, size);
142+
143+
while (retry_count--) {
144+
if (ret < (int)size) {
145+
k_usleep(CONFIG_NRFS_SEND_RETRY_DELAY);
146+
ret = ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, message, size);
147+
} else {
148+
return ret;
149+
}
150+
}
151+
152+
return ret;
153+
}
154+
123155
static void nrfs_backend_send_work(struct k_work *item)
124156
{
125157
struct ipc_data_packet data_to_send;
126158

127159
LOG_DBG("Sending data from workqueue");
128160
while (k_msgq_get(&ipc_transmit_msgq, &data_to_send, K_NO_WAIT) == 0) {
129-
ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, &data_to_send.data,
130-
data_to_send.size);
161+
162+
int ret = nrfs_backend_try_send_directly_over_ipc_service(&data_to_send.data,
163+
data_to_send.size);
164+
165+
if (ret < (int)data_to_send.size) {
166+
nrfs_backend_error_handler(NRFS_ERROR_SEND_DATA_FROM_QUEUE, ret, true);
167+
}
131168
}
132169
}
133170

@@ -156,8 +193,7 @@ static int ipc_channel_init(void)
156193

157194
LOG_DBG("ipc_service_open_instance() done.");
158195

159-
ret = ipc_service_register_endpoint(ch_cfg->ipc_instance,
160-
&ch_cfg->ipc_ept,
196+
ret = ipc_service_register_endpoint(ch_cfg->ipc_instance, &ch_cfg->ipc_ept,
161197
ch_cfg->endpoint_config);
162198
if (ret < 0) {
163199
nrfs_backend_error_handler(NRFS_ERROR_IPC_REGISTER_ENDPOINT, ret, false);
@@ -177,14 +213,16 @@ nrfs_err_t nrfs_backend_send(void *message, size_t size)
177213
nrfs_err_t nrfs_backend_send_ex(void *message, size_t size, k_timeout_t timeout, bool high_prio)
178214
{
179215
if (!k_is_in_isr() && nrfs_backend_connected()) {
180-
return ipc_service_send(&ipc_cpusys_channel_config.ipc_ept, message, size) ?
181-
NRFS_SUCCESS : NRFS_ERR_IPC;
216+
int ret = nrfs_backend_try_send_directly_over_ipc_service(message, size);
217+
218+
return ret < (int)size ? NRFS_ERR_IPC : NRFS_SUCCESS;
219+
182220
} else if (size <= MAX_PACKET_DATA_SIZE) {
183221
int err;
184222
struct ipc_data_packet tx_data;
185223

186224
tx_data.channel_id = IPC_CPUSYS_CHANNEL_ID;
187-
tx_data.size = size;
225+
tx_data.size = size;
188226
memcpy(tx_data.data, (uint8_t *)message, size);
189227

190228
err = k_msgq_put(&ipc_transmit_msgq, &tx_data, timeout);

modules/hal_nordic/nrfs/backends/nrfs_backend_ipc_service.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum nrfs_backend_error {
3636
NRFS_ERROR_IPC_OPEN_INSTANCE,
3737
NRFS_ERROR_IPC_REGISTER_ENDPOINT,
3838
NRFS_ERROR_BACKEND_NOT_CONNECTED,
39+
NRFS_ERROR_SEND_DATA_FROM_QUEUE,
3940
NRFS_ERROR_COUNT
4041
};
4142

0 commit comments

Comments
 (0)