Using the IPC API between two separate processors using I2C

Hi,

I have a custom board where I have an nrf9161 main processor and an nrf54L05 processor connected with each other via I2C.

In this case, I'd like to manage the communication between the both using the IPC API and backend provided by Zephyr. I read the information provided on https://docs.zephyrproject.org/latest/services/ipc/ipc_service/ipc_service.html and https://docs.zephyrproject.org/latest/services/ipc/ipc_service/backends/ipc_service_icmsg.html but there are many things that are still unclear to me when trying to set up both ends of the communication.

1) According to the documentation from the links posted above, there is a definition of the IPC as ipc0, which gets declared as a node and used moving forward. However, the description described there seems to use a shared memory allocation. Since I am communicating two different processors it does not make any sense to have such an approach. Should I make different nodes and definitions for each side making sure the nrf9161 acts as the host and the nrf54l05 as the remote? Should I take care of anything defining those memory regions?

2) When reading those sites for the documentation and also looking at the sample icmsg (used that because it is the zephyr backend for the ICP services) it is also unclear how should I set the system in a way that the messages are received from the I2C line, or how to set the I2C as the communication channel betwen the both.

I'd be thankful if I could get more documentation about this topic or information about any other protocol if the API for ICP was not valid for this approach.

Thank you very much,

Daniel

Parents
  • The built-in “icmsg” IPC Service is meant for two cores in one chip sharing RAM and Nordic mailboxes, so it can’t drive an I2C link between two separate modules. You have two practical paths:

    1. Write a small Zephyr driver that uses i2c_write() / i2c_read() plus a GPIO line as an “interrupt” to emulate the shared-RAM + mailbox model. Then hook it into Zephyr’s IPC Service API via a new devicetree compatible = "vendor,ipc-i2c" node.

    2. On the nRF9161 run as I2C master, on the nRF5340 register as I2C target/slave, and exchange packets directly with i2c_write_dt() and the i2c_target_callbacks. Use a spare GPIO from the remote to flag the host when there’s a response waiting.

    Both approaches give you a clean, event-driven bus over I2C without trying to shoehorn shared memory into two different chips.

Reply
  • The built-in “icmsg” IPC Service is meant for two cores in one chip sharing RAM and Nordic mailboxes, so it can’t drive an I2C link between two separate modules. You have two practical paths:

    1. Write a small Zephyr driver that uses i2c_write() / i2c_read() plus a GPIO line as an “interrupt” to emulate the shared-RAM + mailbox model. Then hook it into Zephyr’s IPC Service API via a new devicetree compatible = "vendor,ipc-i2c" node.

    2. On the nRF9161 run as I2C master, on the nRF5340 register as I2C target/slave, and exchange packets directly with i2c_write_dt() and the i2c_target_callbacks. Use a spare GPIO from the remote to flag the host when there’s a response waiting.

    Both approaches give you a clean, event-driven bus over I2C without trying to shoehorn shared memory into two different chips.

Children
Related