[CF/DF] Are drivers components? Or are devices components?

19 views
Skip to first unread message

Hunter Freyer

unread,
Feb 23, 2021, 7:20:19 PM2/23/21
to Abdulla Kamar, Suraj Malhotra, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
The design doc says it's Drivers, but I've heard contradictory reports here. 

Specifically, I've heard that we can assume that each component will only ever implement a single instance of each protocol, which would seem to imply devices-as-components, not driver-as-components, right?

Hunter

Shai Barack

unread,
Feb 23, 2021, 7:24:22 PM2/23/21
to Hunter Freyer, Abdulla Kamar, Suraj Malhotra, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
Maybe devices are capabilities?
Maybe drivers are components that use the driver runner? 

--
All posts must follow the Fuchsia Code of Conduct https://fuchsia.dev/fuchsia-src/CODE_OF_CONDUCT or may be removed.
---
You received this message because you are subscribed to the Google Groups "component-framework-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to component-framewo...@fuchsia.dev.
To view this discussion on the web visit https://groups.google.com/a/fuchsia.dev/d/msgid/component-framework-dev/CAMkOBfv2tdF3o4cFibG_GD4Vu1DeZhqGinXNFt4qXMv6dXP1pQ%40mail.gmail.com.

Suraj Malhotra

unread,
Feb 23, 2021, 7:37:15 PM2/23/21
to Shai Barack, Hunter Freyer, Abdulla Kamar, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
Drivers are components for certain. I think of devices as "resources". Today each device is a capability, but I've heard people interested in the idea of having a single device which offers multiple capabilities, each routed to different clients. I'm a bit partial to keeping routing done purely on the device level, so even if a device has multiple protocols/services (each one a unique capability?), you always get access to all of them in one go. The use case where this is less than ideal is power - where you may want to offer a power capability to the power manager, but all IO related services from a device elsewhere.

Carlos Pizano

unread,
Feb 23, 2021, 7:38:51 PM2/23/21
to Shai Barack, Hunter Freyer, Abdulla Kamar, Suraj Malhotra, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
A driver is code designed to interface and expose hardware as devices.

For example a driver can be the "serial driver", it understands how to peek and poke registers for a serial controller. Your PC might have 1 serial port, or maybe 12, so accordingly you will see
the COM1 device exposed or COM1, COM2 .... COM12 exposed.

-cpu

To unsubscribe from this group and stop receiving emails from it, send an email to drivers-dev...@fuchsia.dev.

Suraj Malhotra

unread,
Feb 23, 2021, 10:21:40 PM2/23/21
to Aaron Wood, Carlos Pizano, Shai Barack, Hunter Freyer, Abdulla Kamar, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
Device is a really ambiguous term which honestly means different things in different contexts, they are similar, but not quite the same. In fact, we've straight up replaced the concept of a device with the term "node" instead in our FIDL definitions for the component based driver architecture.

If we look at our current usages of "device" in our existing driver framework, it more or less expresses this idea of something that takes one or more resources and transforms them into one or more resources. Those resources may be interrupts, regions of memory, spi devices, clocks, a partition, a microphone, etc. Most resources are exposed via a standard interface described by banjo or FIDL, but mmio and interrupts are notable exceptions. Resources exposed outside of the driver framework are only exposed as interfaces in the form of FIDL protocols.

We have what I consider an elegant system for composing these resources together in a way other OS do not, and trying to model your understanding based on those OS may be confusing.


On Tue, Feb 23, 2021 at 6:14 PM Aaron Wood <aaro...@google.com> wrote:
I think "Drivers are components" is straightforward, but devices are messy, especially compound devices.  Is a multi-port I/O device a single device, or multiple devices?  (or is a single capability or multiple capabilities which are offered by the driver component?)

Leaning harder into the I/O example:  some multi-port I/O hardware changes shape based on how it's used.  It might be multiple ports implementing different buses (SPI, I2C), or it might be a parallel synchronous bus (ie bit-banged).  It may need to change which it is at runtime, too (I've built products that had to do that with I/O peripherals depending on what, exactly, was going on).  There's a lot of I/O multiplexing...

A less IoT-focused, but still I/O-ish example that I can think of, that's worth discussing is storage:
- raw device
- block device interface
- partition interface
- filesystem

The raw device is a big composite that's exposed in a bunch of different ways by successive layers of drivers.  Which I think maps well to the I/O port.  There's a low-level hardware-specific driver that knows how to talk to the device over its bus, and drive the configuration registers, and then there are the higher-level "protocols" that can then be exposed.  I2C and SPI might still be fairly hardware-specific in their implementation, but there could be a component which parcels out SPI ports (or onboard temperature sensors that are wired to the processor via I2C).




Abdulla Kamar

unread,
Feb 23, 2021, 10:34:00 PM2/23/21
to Suraj Malhotra, Aaron Wood, Carlos Pizano, Shai Barack, Hunter Freyer, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
We often interchangeably refer to devices and drivers, and we probably should be more strict with that so there's less confusion. Hence renaming "device" to "node", and referring to the "driver topology". But while we have the old and the new system around, I think it's inevitable to have some amount of confusion.

It might be worth asking where you're hearing these contradictory reports (and maybe the reply should be outside of this thread), to help us better understand what we can do to improve everyone's understanding. I'm hoping to write some more documentation, and it sounds like this is a topic we should cover.

Aaron Wood

unread,
Feb 24, 2021, 1:12:14 PM2/24/21
to Carlos Pizano, Shai Barack, Hunter Freyer, Abdulla Kamar, Suraj Malhotra, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
I think "Drivers are components" is straightforward, but devices are messy, especially compound devices.  Is a multi-port I/O device a single device, or multiple devices?  (or is a single capability or multiple capabilities which are offered by the driver component?)

Leaning harder into the I/O example:  some multi-port I/O hardware changes shape based on how it's used.  It might be multiple ports implementing different buses (SPI, I2C), or it might be a parallel synchronous bus (ie bit-banged).  It may need to change which it is at runtime, too (I've built products that had to do that with I/O peripherals depending on what, exactly, was going on).  There's a lot of I/O multiplexing...

A less IoT-focused, but still I/O-ish example that I can think of, that's worth discussing is storage:
- raw device
- block device interface
- partition interface
- filesystem

The raw device is a big composite that's exposed in a bunch of different ways by successive layers of drivers.  Which I think maps well to the I/O port.  There's a low-level hardware-specific driver that knows how to talk to the device over its bus, and drive the configuration registers, and then there are the higher-level "protocols" that can then be exposed.  I2C and SPI might still be fairly hardware-specific in their implementation, but there could be a component which parcels out SPI ports (or onboard temperature sensors that are wired to the processor via I2C).




On Tue, Feb 23, 2021 at 4:40 PM 'Carlos Pizano' via component-framework-dev <component-f...@fuchsia.dev> wrote:

Aaron Wood

unread,
Feb 24, 2021, 1:12:14 PM2/24/21
to Suraj Malhotra, Carlos Pizano, Shai Barack, Hunter Freyer, Abdulla Kamar, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
On Tue, Feb 23, 2021 at 7:21 PM Suraj Malhotra <surajm...@google.com> wrote:
Device is a really ambiguous term which honestly means different things in different contexts, they are similar, but not quite the same. In fact, we've straight up replaced the concept of a device with the term "node" instead in our FIDL definitions for the component based driver architecture.

If we look at our current usages of "device" in our existing driver framework, it more or less expresses this idea of something that takes one or more resources and transforms them into one or more resources. Those resources may be interrupts, regions of memory, spi devices, clocks, a partition, a microphone, etc. Most resources are exposed via a standard interface described by banjo or FIDL, but mmio and interrupts are notable exceptions. Resources exposed outside of the driver framework are only exposed as interfaces in the form of FIDL protocols.

We have what I consider an elegant system for composing these resources together in a way other OS do not, and trying to model your understanding based on those OS may be confusing.

If that's meant for me, my model here isn't other OS's, but the hardware devices that I've worked within the past, where down at the I/O port level, exactly _what_ a given set of pins is (to the higher layers) is a function of how it's configured.  And I agree that other OS's have had difficulties here.  Especially for complicated devices that are out over USB, where there are multiple driver layers involved (USB transport, the hardware-specific driver, and then the "normal" port driver above that, if one is used).

For something like an x86 with a standard BIOS, this is pretty hidden.  But on ARM, MIPS, and in more "embedded"-ish situations (RPi, purpose-built devices using an application processor, etc.), my experiences have been that there are a lot of I/O that both doesn't fit a standard mode, and is heavily multiplexed in terms of how it can be used.  Those products will need to change the modes of that I/O (not just at boot-time to configure it, but at runtime as well).

e.g. I've had to switch I/O that's usually UART into SPI when holding another chip on board in reset, so that I could update it's firmware image.  And then after the update, switch back to uart mode and continue communication with the device again.

Hunter Freyer

unread,
Feb 24, 2021, 1:52:44 PM2/24/21
to Abdulla Kamar, Suraj Malhotra, Aaron Wood, Carlos Pizano, Shai Barack, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
Heheh, I wrote this email in response to a conversation we had in a meeting, and reading it now I realize that without that context it sounds much more general than I meant it to. Sorry about that!

My question was specifically in the setting of the new drivers-as-components design. My thinking was that it might be more natural to have a component per node (aka device), as opposed to component per driver.

To see why, consider the ethernet driver. In my sherlock, it binds to nodes for both my WLAN adapter and my USB Ethernet adapter. So in its incoming namespace it will presumably have both /svc/fuchsia.drivers.EthernetImpl/id-for-wlan-ethernet-impl and /svc/fuchsia.drivers.EthernetImpl/id-for-usb-ethernet-impl. And in its outgoing directory, it will expose both /svc/fuchsia.drivers.Ethernet/id-for-wlan-ethernet and /svc/fuchsia.drivers.Ethernet/id-for-usb-ethernet.

The USB ethernet communication streams run entirely parallel to the WLAN communication streams, yeah? Like, getting a request on "id-for-usb-ethernet" will probably trigger a request to "id-for-usb-ethernet-impl" and likewise with WLAN, but a request on "id-for-usb-ethernet" would never result in a request for "id-for-wlan-ethernet-impl".

Whereas if each node had a component, it would just see /svc/fuchsia.drivers.EthernetImpl in its incoming namespace and would export /svc/fuchsia.drivers.Ethernet in its outgoing namespace, easy peasy.

So what's the trade-off here? Is there more interaction here than I'm aware of?

Hunter


Suraj Malhotra

unread,
Feb 24, 2021, 2:21:57 PM2/24/21
to Hunter Freyer, Abdulla Kamar, Aaron Wood, Carlos Pizano, Shai Barack, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
I think it's probably worth fixing a few assumptions:
  • There will be two instances of the ethernet driver loaded in the above case, each in a separate process (shared with it's parent)
    • As such, requests to each ethernet device from outside the driver collection will always get routed to the correct instance of the driver, and there will never be a place for it to accidentally cross paths
  • I don't believe we will place protocols for drivers which bind to a single device into service directories. Instead all offered protocols will sit directly under /svc. This makes the common case quite simple.
  • For drivers which bind to multiple devices (a composite device) - each device is referred to as a fragment. Each fragment has a specified name as part of it's bind contract. While it hasn't been designed just yet, my expectation is that the fragment name will be utilized as the instance id.
    • The driver providing a fragment is unaware of the fragment name tied to the device/service it exports. It only has properties assigned to the device, and the driver framework maps those properties to the fragment as part of bind evaluation.
    • The reason protocol name is not sufficient in of itself is because multiple fragments may implement the same protocol. For example, each clock resource a driver gets is a unique fragment device, and will provide exactly the same protocol. The fragment name gives each instance a meaning.
It's worth mentioning that we haven't actually built out support for binding to fidl protocols/services just yet. In fact for places where this is anticipated to occur (replacement for banjo proxying), I am expecting a single fidl protocol per fragment. I have some design docs forthcoming where more specific discussion on the details can get hashed out (although I'm targeting our current driver runtime rather than the component based one).

Hunter Freyer

unread,
Feb 24, 2021, 2:33:41 PM2/24/21
to Suraj Malhotra, Abdulla Kamar, Aaron Wood, Carlos Pizano, Shai Barack, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
Ahaaaa, okay, so it's not one-component-per-driver. It's one-component per "driver instance", I guess? Is there more correct terminology?

When does a "driver instance" get created? Each time a driver binds to a node?


Suraj Malhotra

unread,
Feb 24, 2021, 2:36:41 PM2/24/21
to Hunter Freyer, Abdulla Kamar, Aaron Wood, Carlos Pizano, Shai Barack, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev
If a component (same cml) is loaded into the static topology multiple times, do you consider each "instance" a separate component? That's more or less what's going on here.

Yes, each driver instance is created a driver binds to a node.

Mesch

unread,
Feb 27, 2021, 5:45:55 PM2/27/21
to component-framework-dev, Suraj Malhotra, Abdulla Kamar, Aaron Wood, Carlos Pizano, Shai Barack, Adam Lesinski, component-framework-dev, drive...@fuchsia.dev, Hunter Freyer
On Wednesday, 24 February 2021 at 11:36:41 UTC-8 Suraj Malhotra wrote:
If a component (same cml) is loaded into the static topology multiple times, do you consider each "instance" a separate component?

Each is a separate component instance. 

We conflate components (component "classes"  if you will) and component instances a lot, I personally find that endlessly confusing.
Reply all
Reply to author
Forward
0 new messages