• A controller is a piece of hardware that does something: a GPIO, a UART, an I2C controller, etc.

  • A naïve device (NDev) is one that just does what it has to when someone tells it to.

  • A shareable device (SDev) is a wrapper around a naïve device to allow it to be shared between different uses, but only for one purpose at a time.

    Some use-cases for shareable devices

    * A UART can be connected to two different external devices, with hardware to switch
      between the two. One of two different software modules will control the UART, depending on which
      external device it is connected to at the time
    
    • A bus device (BDev) is a driver that

      • An external I2C device needs to be powered down; the I2C pins need to be controlled in a way that does not conform to the I2C specification. The I2C controller module will talk to the UART, but only one at a time, depending on which
  • users at different times.

There are two type of shareable device

  • Exclusive access shareable, where only one device can use it at at time. If another device is using it, any other device is refused access. Most hardware device can only be used by one thing at a time.

    To use an exclusive access shareable device

    • for each naïve device that must be shareable, the system creates a shareable device and links it to the naïve device

    • each user registers with the shareable device it needs; this gives the user a virtual device

    • to use a virtual device, the user

      • claims() the device; if the device is already in use, the claim is denied.
      • accesses the device, using any of the the methods and attributes of the underlying naïve device. If the user has not successfully claimed the device, the access is denied.
      • release() the device, to allow another use to use it. It it not an error to release a device that you have not claimed.
  • Bus shareable device, where any number of users can request access to the device. When no-one is using it, the device is ‘off’. Any number of users can request access and use it simulataneously. When the last user has finished, it turns ‘off’ again.

    This type of device is often used for power-buses or network interfaces.

    To use a bus shareable device

    • the system creates a bus shareable device

    • each user registers with the shareable device; this gives them each a virtual device

    • to use a bus shareable virtual device, the user

      • request() the bus shareable device; this will return the device status, which is one of

        • ‘wait’ (if the device needs to turn on) or
        • ‘on’ (if the device is already on and can be used immediately.)
      • if the bus shared device is off, it starts the turn-on process:

        • notifies all registrants that it is ‘turning on’
        • do whatever it needs
        • when the device is finally on, it notifies registrants that it is ‘on’.
      • if the request() was to wait, the user can either

        • request() again
        • wait for the ‘on’ notification
        • read the status
      • use the bus shareable device. If it is not ‘on’,

        • do nothing
        • block until on
        • access denied
      • when the user has finished, it release() the device

      • when the last user has release() the bus shareable device, it starts the power-off process

        • notify all registrants that it is ‘turning off’
        • does whatever it needs
        • when the device is off, it notifies registrants that it is ‘off’
      • every user should be prepared for the bus device to turn off unexpectedly; note that, the system will always do the power-off process

      • a user can use a device without request() it. However, if the device it not already on, or turns off, it will either do nothing, or block or deny access; the user must be prepared for this.