RPC Interface for I2C Driver

Christian Helmuth christian.helmuth at genode-labs.com
Thu Feb 25 14:48:32 CET 2021

Hello Jean-Adrien,

first please note that I'm far from an export for I2C but nevertheless
like to share my thoughts from an architectural perspective on Genode.

On Thu, Feb 25, 2021 at 10:57:21 CET, Jean-Adrien Domage wrote:
> We would like to introduce an i2c driver for imx8q_evk to Genode. Thanks to
> the hints from Sebastian, I now have a prototype component that can
> send/receive data via the i2c bus of the imx8q_evk. The next task is to
> design the RPC interface for the driver.

My first impulse was to respond with: Why don't you reuse an existing
RPC interface as there are quite many use cases covered with these.
But thinking about the task more I could not find a fit in the current
arsenal myself ;-)

> What would be a good kind of interface? Do you have driver(s)/component(s)
> to recommend as example? Or any specific guidelines?

In my opinion there are two design questions to answer.

1. What is the nature of I2C and how should it be reflected in Genode?

According to Wikipedia [1], I2C is a master-slave bus comparable to
USB on a high level but far less complex. The master may request read
or write transactions from/to a slave peripheral. I can't derive the
requirement for an interrupt scheme resp. asynchronous operation from
this information. Naturally, peripherals are addressed in some way by
a _bus address_.

As I've limited to no hands-on experience with I2C hardware, I'd start
with a design that considers the Genode host's I2C bus driver as the
bus master, which sends request transactions to a bunch of slave
peripherals on the bus. Each peripheral is a distinct hardware
resource possibly used by distinct Genode components. Therefore, the
permission to address requests to _one_ I2C peripheral should be
expressed by a session. Multiple peripherals can be accessed via
multiple sessions each one dedicated to one device on the I2C bus. The
bus driver can then be configured by policies that match session
labels to bus addresses and, thereby, the permission to interact with
one specific peripheral.

A rough example of a Genode configuration may look like follows.

  <start name="i2c_bus_drv">
    <provides> <service name="I2c"/> </provides>
      <policy label_prefix="sensor"     bus_address="1"/>
      <policy label_prefix="motor"      bus_address="2"/>
      <policy label_prefix="peripheral" bus_address="5"/>
      <!-- allow the bus driver to access required I/O resources -->

  <start name="combined_drv">
      <!-- driver requests 2 sessions - "sensor" and "motor" -->
      <service name="I2c" label="sensor"> <child name="i2c_bus_drv" label="sensor"/> </service>
      <service name="I2c" label="motor">  <child name="i2c_bus_drv" label="motor"/>  </service>

  <start name="single_drv">
      <service name="I2c"> <child name="i2c_bus_drv" label="peripheral"/> </service>

2. How should an appropriate functional session interface look like?

According to what I learned from Wikipedia, the most simple operations
required are like follows.

  uint8_t read_byte()
  void    write_byte(uint8_t)

The functions do not need a bus address parameter as the session
hard-wires the access to one peripheral. The sketched operations may
not suffice if I2C supports multi-byte transactions and those are
required by the peripherals too. These could be added easily later.

[1] https://en.wikipedia.org/wiki/I%C2%B2C

I hope this helps you starting your design and are curious which
solution you are going to propose.

Christian Helmuth
Genode Labs

https://www.genode-labs.com/ · https://genode.org/
https://twitter.com/GenodeLabs · /ˈdʒiː.nəʊd/

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth

More information about the users mailing list