diff --git a/samples/basic/blinky/boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay b/samples/basic/blinky/boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay new file mode 100644 index 00000000000..1c59420d055 --- /dev/null +++ b/samples/basic/blinky/boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +&led0 { + gpios = <&egpio 7 GPIO_ACTIVE_HIGH>; +}; diff --git a/samples/basic/blinky/sample.yaml b/samples/basic/blinky/sample.yaml index de711910dad..729afca0e7f 100644 --- a/samples/basic/blinky/sample.yaml +++ b/samples/basic/blinky/sample.yaml @@ -1,12 +1,70 @@ sample: name: Blinky Sample +common: + tags: + - LED + - gpio + depends_on: gpio tests: sample.basic.blinky: - tags: - - LED - - gpio filter: dt_enabled_alias_with_parent_compat("led0", "gpio-leds") - depends_on: gpio harness: led integration_platforms: - frdm_k64f + + sample.basic.blinky.egpio_icmsg: + sysbuild: true + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp + extra_args: blinky_SNIPPET=emulated-gpio-icmsg + SB_CONFIG_SDP=y + SB_CONFIG_EGPIO_FLPR_APPLICATION=y + SB_CONFIG_PARTITION_MANAGER=n + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay" + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "LED state: ON" + - "LED state: OFF" + + sample.basic.blinky.egpio_mbox: + sysbuild: true + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp + extra_args: blinky_SNIPPET=emulated-gpio-mbox + SB_CONFIG_SDP=y + SB_CONFIG_EGPIO_FLPR_APPLICATION=y + SB_CONFIG_PARTITION_MANAGER=n + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay" + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "LED state: ON" + - "LED state: OFF" + + sample.basic.blinky.egpio_icbmsg: + sysbuild: true + platform_allow: + - nrf54l15dk/nrf54l15/cpuapp + integration_platforms: + - nrf54l15dk/nrf54l15/cpuapp + extra_args: blinky_SNIPPET=emulated-gpio-icbmsg + SB_CONFIG_SDP=y + SB_CONFIG_EGPIO_FLPR_APPLICATION=y + SB_CONFIG_PARTITION_MANAGER=n + EXTRA_DTC_OVERLAY_FILE="./boards/nrf54l15dk_nrf54l15_cpuapp_egpio.overlay" + harness: console + harness_config: + type: multi_line + ordered: true + regex: + - "LED state: ON" + - "LED state: OFF" 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..03f1065fd04 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" diff --git a/subsys/ipc/ipc_service/backends/ipc_icbmsg.c b/subsys/ipc/ipc_service/backends/ipc_icbmsg.c index 4f3830b4633..5a53b5bb2c2 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,11 @@ 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 +469,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 +520,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 +703,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 +711,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 +752,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 +774,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 +911,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 +1000,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 } /** @@ -1045,7 +1091,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; } } @@ -1070,8 +1120,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 +1241,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 +1253,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;