@@ -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
2222K_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
2525static struct k_work backend_send_work ;
2626
@@ -41,18 +41,17 @@ struct ipc_channel_config {
4141
4242static 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
5050static 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+
123155static 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)
177213nrfs_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 );
0 commit comments