-
Notifications
You must be signed in to change notification settings - Fork 6.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ipc: add dynamically allocated buffers to icmsg
The icmsg and icmsg_me backends has limitations in context of concurrent access to single instance. Some limitations are: * sending by more thread at the same time may cause -EBUSY * allocating TX buffer will cause errors in other threads that want to allocate before first thread sent the message, * during no-copy receive, when RX buffer is on hold receiving is totally blocked. This backend resolves those limitations by adding dynamically allocated buffers on shared memory next to ICmsg circular buffer. The data is passed using those buffers, so concurrency is not a problem. The ICmsg is used only to pass short 2-byte messages containing references to those buffers. The backend also supports multiple endpoint. The ipc/icmsg_me sample was modified to support this backend. Signed-off-by: Dominik Kilian <[email protected]>
- Loading branch information
1 parent
a3ff19a
commit 28df449
Showing
8 changed files
with
1,452 additions
and
0 deletions.
There are no files selected for viewing
83 changes: 83 additions & 0 deletions
83
doc/services/ipc/ipc_service/backends/ipc_service_icbmsg.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
.. _ipc_service_backend_icbmsg: | ||
|
||
ICMsg with dynamically allocated buffers backend | ||
################################################ | ||
|
||
This backend is built on top of the :ref:`ipc_service_backend_icmsg`. | ||
Data transferred over this backend travels in dynamically allocated buffers on shared memory. | ||
The ICMsg just sends references to the buffers. | ||
It also supports multiple endpoints. | ||
|
||
This architecture allows for overcoming some common problems with other backends (mostly related to multithread access and zero-copy). | ||
This backend provides an alternative with no significant limitations. | ||
|
||
Overview | ||
======== | ||
|
||
The shared memory is divided into two parts. | ||
One is reserved for the ICMsg and the other contains equal-sized blocks. | ||
The number of blocks is configured in the devicetree. | ||
|
||
The data sending process is following: | ||
|
||
* The sender allocates one or more blocks. | ||
If there are not enough sequential blocks, it waits using the timeout provided in the parameter that also includes K_FOREVER and K_NO_WAIT. | ||
* The allocated blocks are filled with data. | ||
For the zero-copy case, this is done by the caller, otherwise, it is copied automatically. | ||
During this time other threads are not blocked in any way as long as there are enough free blocks for them. | ||
They can allocate, send data and receive data. | ||
* A message containing the block index is sent over ICMsg to the receiver. | ||
The size of the ICMsg queue is large enough to hold messages for all blocks, so it will never overflow. | ||
* The receiver can hold the data as long as desired. | ||
Again, other threads are not blocked as long as there are enough free blocks for them. | ||
* When data is no longer needed, the backend sends a release message over ICMsg. | ||
* When the backend receives this message, it deallocates all blocks. | ||
It is done internally by the backend and it is invisible to the caller. | ||
|
||
Configuration | ||
============= | ||
|
||
The backend is configured using Kconfig and devicetree. | ||
When configuring the backend, do the following: | ||
|
||
* Define two memory regions and assign them to ``tx-region`` and ``rx-region`` of an instance. | ||
Ensure that the memory regions used for data exchange are unique (not overlapping any other region) and accessible by both domains (or CPUs). | ||
* Define the number of allocable blocks for each region with ``tx-blocks`` and ``rx-blocks``. | ||
* Define MBOX devices for sending a signal that informs the other domain (or CPU) of the written data. | ||
Ensure that the other domain (or CPU) can receive the signal. | ||
|
||
See the following configuration example for one of the instances: | ||
|
||
.. code-block:: devicetree | ||
reserved-memory { | ||
tx: memory@20070000 { | ||
reg = <0x20070000 0x0800>; | ||
}; | ||
rx: memory@20078000 { | ||
reg = <0x20078000 0x0800>; | ||
}; | ||
}; | ||
ipc { | ||
ipc0: ipc0 { | ||
compatible = "zephyr,ipc-icbmsg"; | ||
tx-region = <&tx>; | ||
rx-region = <&rx>; | ||
tx-blocks = <16>; | ||
rx-blocks = <32>; | ||
mboxes = <&mbox 0>, <&mbox 1>; | ||
mbox-names = "tx", "rx"; | ||
status = "okay"; | ||
}; | ||
}; | ||
You must provide a similar configuration for the other side of the communication (domain or CPU). | ||
Swap the MBOX channels, memory regions (``tx-region`` and ``rx-region``), and block count (``tx-blocks`` and ``rx-blocks``). | ||
|
||
Samples | ||
======= | ||
|
||
* :ref:`ipc_multi_endpoint_sample` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# | ||
# Copyright (c) 2023 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
||
description: Inter-core messaging backend with dynamically allocated buffers | ||
|
||
compatible: "zephyr,ipc-icbmsg" | ||
|
||
include: zephyr,ipc-icmsg.yaml | ||
|
||
properties: | ||
tx-blocks: | ||
description: number of allocable TX blocks | ||
required: true | ||
type: int | ||
|
||
rx-blocks: | ||
description: number of allocable RX blocks | ||
required: true | ||
type: int |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright (c) 2023 Nordic Semiconductor ASA | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
menuconfig IPC_SERVICE_BACKEND_ICBMSG | ||
bool "ICMSG backend with dynamically allocated buffers" | ||
default y | ||
depends on MBOX | ||
depends on DT_HAS_ZEPHYR_IPC_ICBMSG_ENABLED | ||
select IPC_SERVICE_ICMSG | ||
help | ||
Choosing this backend results in multi endpoint implementation based | ||
on dynamically allocated buffers. References to them are send over | ||
ICMsg circular buffer. | ||
|
||
if IPC_SERVICE_BACKEND_ICBMSG | ||
|
||
config IPC_SERVICE_BACKEND_ICBMSG_NUM_EP | ||
int "Endpoints count" | ||
range 1 254 | ||
default 4 | ||
help | ||
Number of endpoints supported by the ICBMsg IPC service | ||
backend. The number of endpoints are applied to all the instances, | ||
so this value should be maximum number among all the instances. | ||
|
||
module = IPC_SERVICE_BACKEND_ICBMSG | ||
module-str = ICMSG backend with separate buffers | ||
module-help = Sets log level for ICMsg backend with buffers | ||
source "subsys/logging/Kconfig.template.log_config" | ||
|
||
endif # IPC_SERVICE_BACKEND_ICBMSG |
Oops, something went wrong.