From 29a8e6cd1f902f88182482bf24d5ff729fb2a504 Mon Sep 17 00:00:00 2001 From: Magdalena Pastula Date: Mon, 9 Sep 2024 18:24:22 +0200 Subject: [PATCH 1/3] [nrf fromtree] ipc: align icbmsg to no-multithreading Modify ICBMSG so that it could be used in no-multithreading appliactions. Signed-off-by: Magdalena Pastula (cherry picked from commit 5de1c092b7d75d132ca5ddd68cf678fe280d5979) --- subsys/ipc/ipc_service/backends/ipc_icbmsg.c | 53 ++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/subsys/ipc/ipc_service/backends/ipc_icbmsg.c b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c index 4f3830b4633..135d2c8aca9 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icbmsg.c +++ b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c @@ -174,11 +174,13 @@ struct ept_data { struct backend_data { const struct icbmsg_config *conf;/* Backend instance config. */ struct icmsg_data_t control_data;/* ICMsg data. */ +#ifdef CONFIG_MULTITHREADING struct k_mutex mutex; /* Mutex to protect: ICMsg send call and * waiting_bound field. */ struct k_work ep_bound_work; /* Work item for bounding processing. */ struct k_sem block_wait_sem; /* Semaphore for waiting for free blocks. */ +#endif struct ept_data ept[NUM_EPT]; /* Array of registered endpoints. */ uint8_t ept_map[NUM_EPT]; /* Array that maps endpoint address to index. */ uint16_t waiting_bound[NUM_EPT];/* The bound messages waiting to be registered. */ @@ -209,8 +211,10 @@ struct control_message { BUILD_ASSERT(NUM_EPT <= EPT_ADDR_INVALID, "Too many endpoints"); +#ifdef CONFIG_MULTITHREADING /* Work queue for bounding processing. */ static struct k_work_q ep_bound_work_q; +#endif /** * Calculate pointer to block from its index and channel configuration (RX or TX). @@ -327,12 +331,15 @@ static int alloc_tx_buffer(struct backend_data *dev_data, uint32_t *size, size_t total_size = *size + BLOCK_HEADER_SIZE; size_t num_blocks = DIV_ROUND_UP(total_size, conf->tx.block_size); struct block_content *block; +#ifdef CONFIG_MULTITHREADING bool sem_taken = false; +#endif size_t tx_block_index; size_t next_bit; int prev_bit_val; int r; +#ifdef CONFIG_MULTITHREADING do { /* Try to allocate specified number of blocks. */ r = sys_bitarray_alloc(conf->tx_usage_bitmap, num_blocks, @@ -358,6 +365,10 @@ static int alloc_tx_buffer(struct backend_data *dev_data, uint32_t *size, if (sem_taken) { k_sem_give(&dev_data->block_wait_sem); } +#else + /* Try to allocate specified number of blocks. */ + r = sys_bitarray_alloc(conf->tx_usage_bitmap, num_blocks, &tx_block_index); +#endif if (r < 0) { if (r != -ENOSPC && r != -EAGAIN) { @@ -457,8 +468,10 @@ static int release_tx_blocks(struct backend_data *dev_data, size_t tx_block_inde return r; } +#ifdef CONFIG_MULTITHREADING /* Wake up all waiting threads. */ k_sem_give(&dev_data->block_wait_sem); +#endif } return tx_block_index; @@ -506,10 +519,14 @@ static int send_control_message(struct backend_data *dev_data, enum msg_type msg }; int r; +#ifdef CONFIG_MULTITHREADING k_mutex_lock(&dev_data->mutex, K_FOREVER); +#endif r = icmsg_send(&conf->control_config, &dev_data->control_data, &message, sizeof(message)); +#ifdef CONFIG_MULTITHREADING k_mutex_unlock(&dev_data->mutex); +#endif if (r < sizeof(message)) { LOG_ERR("Cannot send over ICMsg, err %d", r); } @@ -685,6 +702,7 @@ static int send_bound_message(struct backend_data *dev_data, struct ept_data *ep return r; } +#ifdef CONFIG_MULTITHREADING /** * Put endpoint bound processing into system workqueue. */ @@ -692,14 +710,21 @@ static void schedule_ept_bound_process(struct backend_data *dev_data) { k_work_submit_to_queue(&ep_bound_work_q, &dev_data->ep_bound_work); } +#endif /** * Work handler that is responsible to start bounding when ICMsg is bound. */ +#ifdef CONFIG_MULTITHREADING static void ept_bound_process(struct k_work *item) +#else +static void ept_bound_process(struct backend_data *dev_data) +#endif { +#ifdef CONFIG_MULTITHREADING struct backend_data *dev_data = CONTAINER_OF(item, struct backend_data, ep_bound_work); +#endif struct ept_data *ept = NULL; size_t i; int r = 0; @@ -726,13 +751,19 @@ static void ept_bound_process(struct k_work *item) } } else { /* Walk over all waiting bound messages and match to local endpoints. */ +#ifdef CONFIG_MULTITHREADING k_mutex_lock(&dev_data->mutex, K_FOREVER); +#endif for (i = 0; i < NUM_EPT; i++) { if (dev_data->waiting_bound[i] != WAITING_BOUND_MSG_EMPTY) { +#ifdef CONFIG_MULTITHREADING k_mutex_unlock(&dev_data->mutex); +#endif r = match_bound_msg(dev_data, dev_data->waiting_bound[i], i); +#ifdef CONFIG_MULTITHREADING k_mutex_lock(&dev_data->mutex, K_FOREVER); +#endif if (r != 0) { dev_data->waiting_bound[i] = WAITING_BOUND_MSG_EMPTY; @@ -742,7 +773,9 @@ static void ept_bound_process(struct k_work *item) } } } +#ifdef CONFIG_MULTITHREADING k_mutex_unlock(&dev_data->mutex); +#endif } /* Check if any endpoint is ready to rebound and call the callback if it is. */ @@ -877,12 +910,20 @@ static int received_bound(struct backend_data *dev_data, size_t rx_block_index, } /* Put message to waiting array. */ +#ifdef CONFIG_MULTITHREADING k_mutex_lock(&dev_data->mutex, K_FOREVER); +#endif dev_data->waiting_bound[ept_addr] = rx_block_index; +#ifdef CONFIG_MULTITHREADING k_mutex_unlock(&dev_data->mutex); +#endif +#ifdef CONFIG_MULTITHREADING /* Schedule processing the message. */ schedule_ept_bound_process(dev_data); +#else + ept_bound_process(dev_data); +#endif return 0; } @@ -958,7 +999,11 @@ static void control_bound(void *priv) /* Set flag that ICMsg is bounded and now, endpoint bounding may start. */ atomic_or(&dev_data->flags, CONTROL_BOUNDED); +#ifdef CONFIG_MULTITHREADING schedule_ept_bound_process(dev_data); +#else + ept_bound_process(dev_data); +#endif } /** @@ -1070,8 +1115,12 @@ static int register_ept(const struct device *instance, void **token, /* Keep endpoint address in token. */ *token = ept; +#ifdef CONFIG_MULTITHREADING /* Rest of the bounding will be done in the system workqueue. */ schedule_ept_bound_process(dev_data); +#else + ept_bound_process(dev_data); +#endif return r; } @@ -1187,6 +1236,7 @@ static int backend_init(const struct device *instance) { const struct icbmsg_config *conf = instance->config; struct backend_data *dev_data = instance->data; +#ifdef CONFIG_MULTITHREADING static K_THREAD_STACK_DEFINE(ep_bound_work_q_stack, EP_BOUND_WORK_Q_STACK_SIZE); static bool is_work_q_started; @@ -1198,12 +1248,15 @@ static int backend_init(const struct device *instance) is_work_q_started = true; } +#endif dev_data->conf = conf; dev_data->is_initiator = (conf->rx.blocks_ptr < conf->tx.blocks_ptr); +#ifdef CONFIG_MULTITHREADING k_mutex_init(&dev_data->mutex); k_work_init(&dev_data->ep_bound_work, ept_bound_process); k_sem_init(&dev_data->block_wait_sem, 0, 1); +#endif memset(&dev_data->waiting_bound, 0xFF, sizeof(dev_data->waiting_bound)); memset(&dev_data->ept_map, EPT_ADDR_INVALID, sizeof(dev_data->ept_map)); return 0; From 0cc37d096b83451acb7734ffc0f2046edc40ee9e Mon Sep 17 00:00:00 2001 From: Magdalena Pastula Date: Mon, 9 Sep 2024 18:25:34 +0200 Subject: [PATCH 2/3] [nrf fromtree] samples: subsys: ipc: add testcases for icbmsg on nRF54L15 Add testcases for ICBMSG on nRF54L15 with only one endpoint, including non-multithreading case. Signed-off-by: Magdalena Pastula (cherry picked from commit 495207668e51ef4ae45e7765fa3cb686bff57254) --- ...nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay | 43 ++++++++++ ...rf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay | 47 +++++++++++ .../subsys/ipc/ipc_service/icmsg/sample.yaml | 78 +++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay create mode 100644 samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay diff --git a/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay new file mode 100644 index 00000000000..74bdf07915b --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + sram_rx: memory@20018000 { + reg = <0x20018000 0x0800>; + }; + + sram_tx: memory@20020000 { + reg = <0x20020000 0x0800>; + }; + }; + }; + + ipc { + ipc0: ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&sram_tx>; + rx-region = <&sram_rx>; + tx-blocks = <16>; + rx-blocks = <18>; + mboxes = <&cpuapp_vevif_rx 15>, <&cpuapp_vevif_tx 16>; + mbox-names = "rx", "tx"; + status = "okay"; + }; + }; +}; + +&cpuapp_vevif_rx { + status = "okay"; +}; + +&cpuapp_vevif_tx { + status = "okay"; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay new file mode 100644 index 00000000000..56ea0e6a5e4 --- /dev/null +++ b/samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + soc { + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + sram_tx: memory@20018000 { + reg = <0x20018000 0x0800>; + }; + + sram_rx: memory@20020000 { + reg = <0x20020000 0x0800>; + }; + }; + }; + + ipc { + ipc0: ipc0 { + compatible = "zephyr,ipc-icbmsg"; + tx-region = <&sram_tx>; + rx-region = <&sram_rx>; + tx-blocks = <18>; + rx-blocks = <16>; + mboxes = <&cpuflpr_vevif_rx 16>, <&cpuflpr_vevif_tx 15>; + mbox-names = "rx", "tx"; + status = "okay"; + }; + }; +}; + +&cpuflpr_vevif_rx { + status = "okay"; +}; + +&cpuflpr_vevif_tx { + status = "okay"; +}; + +&uart30 { + /delete-property/ hw-flow-control; +}; diff --git a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml index 3df06a80a42..b981c1b8215 100644 --- a/samples/subsys/ipc/ipc_service/icmsg/sample.yaml +++ b/samples/subsys/ipc/ipc_service/icmsg/sample.yaml @@ -84,3 +84,81 @@ tests: - "host: Sent" - "host: Received" - "host: IPC-service HOST demo ended" + + sample.ipc.icbmsg.nrf54l15: + platform_allow: nrf54l15pdk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15pdk/nrf54l15/cpuapp + tags: ipc + extra_args: + icmsg_SNIPPET=nordic-flpr + icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 + icmsg_DTC_OVERLAY_FILE="boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay" + remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 + remote_DTC_OVERLAY_FILE="boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay" + sysbuild: true + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "host: IPC-service HOST demo started" + - "host: Ep bounded" + - "host: Perform sends for" + - "host: Sent" + - "host: Received" + - "host: IPC-service HOST demo ended" + + sample.ipc.icbmsg.nrf54l15_no_multithreading: + platform_allow: nrf54l15pdk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15pdk/nrf54l15/cpuapp + tags: ipc + extra_args: + icmsg_SNIPPET=nordic-flpr + icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 + icmsg_DTC_OVERLAY_FILE="boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay" + icmsg_CONFIG_MULTITHREADING=n + icmsg_CONFIG_LOG_MODE_MINIMAL=y + remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 + remote_DTC_OVERLAY_FILE="boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay" + remote_CONFIG_MULTITHREADING=n + remote_CONFIG_LOG_MODE_MINIMAL=y + sysbuild: true + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "host: IPC-service HOST demo started" + - "host: Ep bounded" + - "host: Perform sends for" + - "host: Sent" + - "host: Received" + - "host: IPC-service HOST demo ended" + + sample.ipc.icbmsg.nrf54l15_remote_no_multithreading: + platform_allow: nrf54l15pdk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15pdk/nrf54l15/cpuapp + tags: ipc + extra_args: + icmsg_SNIPPET=nordic-flpr + icmsg_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 + icmsg_DTC_OVERLAY_FILE="boards/nrf54l15pdk_nrf54l15_cpuapp_icbmsg.overlay" + remote_CONFIG_IPC_SERVICE_BACKEND_ICBMSG_NUM_EP=1 + remote_DTC_OVERLAY_FILE="boards/nrf54l15pdk_nrf54l15_cpuflpr_icbmsg.overlay" + remote_CONFIG_MULTITHREADING=n + remote_CONFIG_LOG_MODE_MINIMAL=y + sysbuild: true + harness: console + harness_config: + type: multi_line + ordered: false + regex: + - "host: IPC-service HOST demo started" + - "host: Ep bounded" + - "host: Perform sends for" + - "host: Sent" + - "host: Received" + - "host: IPC-service HOST demo ended" From ed9919efda39eb692a8f78f601bdc4d60332b0b7 Mon Sep 17 00:00:00 2001 From: Magdalena Pastula Date: Thu, 3 Oct 2024 19:04:31 +0200 Subject: [PATCH 3/3] [nrf fromlist] ipc: align icbmsg deregistration to no-multithreading Align icbmsg deregistration modification to no-multithreading. Upstream PR: zephyrproject-rtos/zephyr#79382 Signed-off-by: Magdalena Pastula --- subsys/ipc/ipc_service/backends/ipc_icbmsg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/ipc/ipc_service/backends/ipc_icbmsg.c b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c index 135d2c8aca9..70c4c4c362f 100644 --- a/subsys/ipc/ipc_service/backends/ipc_icbmsg.c +++ b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c @@ -1090,7 +1090,11 @@ static int register_ept(const struct device *instance, void **token, if (!matching_state) { return -EINVAL; } +#ifdef CONFIG_MULTITHREADING schedule_ept_bound_process(dev_data); +#else + ept_bound_process(dev_data); +#endif return 0; } }