1.. _ipc_service_backend_icmsg: 2 3ICMsg backend 4############# 5 6The inter core messaging backend (ICMsg) is a lighter alternative to the 7heavier RPMsg static vrings backend. It offers a minimal feature set in a small 8memory footprint. The ICMsg backend is build on top of :ref:`spsc_pbuf`. 9 10Overview 11======== 12 13The ICMsg backend uses shared memory and MBOX devices for exchanging data. 14Shared memory is used to store the data, MBOX devices are used to signal that 15the data has been written. 16 17The backend supports the registration of a single endpoint on a single 18instance. If the application requires more than one communication channel, you 19must define multiple instances, each having its own dedicated endpoint. 20 21Configuration 22============= 23 24The backend is configured via Kconfig and devicetree. 25When configuring the backend, do the following: 26 27* If at least one of the cores uses data cache on shared memory, set the ``dcache-alignment`` value. 28 This must be the largest value of the invalidation or the write-back size for both sides of the communication. 29 You can skip it if none of the communication sides is using data cache on shared memory. 30* Define two memory regions and assign them to ``tx-region`` and ``rx-region`` 31 of an instance. Ensure that the memory regions used for data exchange are 32 unique (not overlapping any other region) and accessible by both domains 33 (or CPUs). 34* Define MBOX devices which are used to send the signal that informs the other 35 domain (or CPU) that data has been written. Ensure that the other domain 36 (or CPU) is able to receive the signal. 37 38.. caution:: 39 40 Make sure that you set correct value of the ``dcache-alignment``. 41 At first, wrong value may not show any signs, which may give a false impression that everything works. 42 Unstable behavior will appear sooner or later. 43 44See the following configuration example for one of the instances: 45 46.. code-block:: devicetree 47 48 reserved-memory { 49 tx: memory@20070000 { 50 reg = <0x20070000 0x0800>; 51 }; 52 53 rx: memory@20078000 { 54 reg = <0x20078000 0x0800>; 55 }; 56 }; 57 58 ipc { 59 ipc0: ipc0 { 60 compatible = "zephyr,ipc-icmsg"; 61 dcache-alignment = <32>; 62 tx-region = <&tx>; 63 rx-region = <&rx>; 64 mboxes = <&mbox 0>, <&mbox 1>; 65 mbox-names = "tx", "rx"; 66 status = "okay"; 67 }; 68 }; 69 }; 70 71 72You must provide a similar configuration for the other side of the 73communication (domain or CPU) but you must swap the MBOX channels and memory 74regions (``tx-region`` and ``rx-region``). 75 76Bonding 77======= 78 79When the endpoint is registered, the following happens on each domain (or CPU) 80connected through the IPC instance: 81 821. The domain (or CPU) writes a magic number to its ``tx-region`` of the shared 83 memory. 84#. It then sends a signal to the other domain or CPU, informing that the data 85 has been written. Sending the signal to the other domain or CPU is repeated 86 with timeout specified by 87 :kconfig:option:`CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS` option. 88#. When the signal from the other domain or CPU is received, the magic number 89 is read from ``rx-region``. If it is correct, the bonding process is finished 90 and the backend informs the application by calling 91 :c:member:`ipc_service_cb.bound` callback. 92 93Samples 94======= 95 96 - :zephyr:code-sample:`ipc-icmsg` 97 98Detailed Protocol Specification 99=============================== 100 101The ICMsg uses two shared memory regions and two MBOX channels. 102The region and channel pair are used to transfer messages in one direction. 103The other pair is symmetric and transfers messages in the opposite direction. 104For this reason, the specification below focuses on one such pair. 105The other pair is identical. 106 107The ICMsg provides just one endpoint per instance. 108 109Shared Memory Region Organization 110--------------------------------- 111 112If data caching is enabled, the shared memory region provided to ICMsg must be aligned according to the cache requirement. 113If cache is not enabled, the required alignment is 4 bytes. 114 115The shared memory region is entirely used by a single FIFO. 116It contains read and write indexes followed by the data buffer. 117The detailed structure is contained in the following table: 118 119.. list-table:: 120 :header-rows: 1 121 122 * - Field name 123 - Size (bytes) 124 - Byte order 125 - Description 126 * - ``rd_idx`` 127 - 4 128 - little‑endian 129 - Index of the first incoming byte in the ``data`` field. 130 * - ``padding`` 131 - depends on cache alignment 132 - n/a 133 - Padding added to align ``wr_idx`` to the cache alignment. 134 * - ``wr_idx`` 135 - 4 136 - little‑endian 137 - Index of the byte after the last incoming byte in the ``data`` field. 138 * - ``data`` 139 - everything to the end of the region 140 - n/a 141 - Circular buffer containing actual bytes to transfer. 142 143This is usual FIFO with a circular buffer: 144 145* The Indexes (``rd_idx`` and ``wr_idx``) are wrapped around when they reach the end of the ``data`` buffer. 146* The FIFO is empty if ``rd_idx == wr_idx``. 147* The FIFO has one byte less capacity than the ``data`` buffer length. 148 149Packets 150------- 151 152Packets are sent over the FIFO described in the above section. 153One packet can be wrapped around if it occurs at the end of the FIFO buffer. 154 155The following is the packet structure: 156 157.. list-table:: 158 :header-rows: 1 159 160 * - Field name 161 - Size (bytes) 162 - Byte order 163 - Description 164 * - ``len`` 165 - 2 166 - big‑endian 167 - Length of the ``data`` field. 168 * - ``reserved`` 169 - 2 170 - n/a 171 - Reserved for the future use. 172 It must be 0 for the current protocol version. 173 * - ``data`` 174 - ``len`` 175 - n/a 176 - Packet data. 177 * - ``padding`` 178 - 0‑3 179 - n/a 180 - Padding is added to align the total packet size to 4 bytes. 181 182The packet send procedure is the following: 183 184#. Check if the packet fits into the buffer. 185#. Write the packet to ``data`` FIFO buffer starting at ``wr_idx``. 186 Wrap it if needed. 187#. Write a new value of the ``wr_idx``. 188#. Notify the receiver over the MBOX channel. 189 190Initialization 191-------------- 192 193The initialization sequence is the following: 194 195#. Set the ``wr_idx`` and ``rd_idx`` to zero. 196#. Push a single packet to FIFO containing magic data: ``45 6d 31 6c 31 4b 30 72 6e 33 6c 69 34``. 197 The MBOX is not used yet. 198#. Initialize the MBOX. 199#. Repeat the notification over the MBOX channel using some interval, for example, 1 ms. 200#. Wait for an incoming packet containing the magic data. 201 It will arrive over the other pair (shared memory region and MBOX). 202#. Stop repeating the MBOX notification. 203 204After this, the ICMsg is bound, and it is ready to transfer packets. 205