.. _modules:

Modules
=======

Modules add additional functionality to the core :class:`Target` interface.
Usually, it is support for specific subsystems on the target. Modules are
instantiated as attributes of the :class:`Target` instance.

hotplug
-------

Kernel ``hotplug`` subsystem allows offlining ("removing") cores from the
system, and onlining them back in. The ``devlib`` module exposes a simple
interface to this subsystem

.. code:: python

   from devlib import LocalLinuxTarget
   target = LocalLinuxTarget()

   # offline cpus 2 and 3, "removing" them from the system
   target.hotplug.offline(2, 3)

   # bring CPU 2 back in
   target.hotplug.online(2)

   # Make sure all cpus are online
   target.hotplug.online_all()

cpufreq
-------

``cpufreq`` is the kernel subsystem for managing DVFS (Dynamic Voltage and
Frequency Scaling). It allows controlling frequency ranges and switching
policies (governors). The ``devlib`` module exposes the following interface

.. note:: On ARM big.LITTLE systems, all cores on a cluster (usually all cores
          of the same type) are in the same frequency domain, so setting
          ``cpufreq`` state on one core on a cluster will affect all cores on
          that cluster. Because of this, some devices only expose cpufreq sysfs
          interface (which is what is used by the ``devlib`` module) on the
          first cpu in a cluster. So to keep your scripts portable, always use
          the fist (online) CPU in a cluster to set ``cpufreq`` state.

.. method:: target.cpufreq.list_governors(cpu)

   List cpufreq governors available for the specified cpu. Returns a list of
   strings.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
               ``1`` or ``"cpu1"``).

.. method:: target.cpufreq.list_governor_tunables(cpu)

   List the tunables for the specified cpu's current governor.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
       ``1`` or ``"cpu1"``).


.. method:: target.cpufreq.get_governor(cpu)

   Returns the name of the currently set governor for the specified cpu.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
               ``1`` or ``"cpu1"``).

.. method:: target.cpufreq.set_governor(cpu, governor, \*\*kwargs)

   Sets the governor for the specified cpu.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
        ``1`` or ``"cpu1"``).
   :param governor: The name of the governor. This must be one of the governors 
                supported by the CPU (as returned by ``list_governors()``.

   Keyword arguments may be used to specify governor tunable values.


.. method:: target.cpufreq.get_governor_tunables(cpu)

   Return a dict with the values of the specified CPU's current governor.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
       ``1`` or ``"cpu1"``).

.. method:: target.cpufreq.set_governor_tunables(cpu, \*\*kwargs)

   Set the tunables for the current governor on the specified CPU.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
       ``1`` or ``"cpu1"``).

   Keyword arguments should be used to specify tunable values.

.. method:: target.cpufreq.list_frequencies(cpu)

   List DVFS frequencies supported by the specified CPU. Returns a list of ints.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
       ``1`` or ``"cpu1"``).

.. method:: target.cpufreq.get_min_frequency(cpu)
            target.cpufreq.get_max_frequency(cpu)
            target.cpufreq.set_min_frequency(cpu, frequency[, exact=True])
            target.cpufreq.set_max_frequency(cpu, frequency[, exact=True])

   Get and set min and max frequencies on the specified CPU. "set" functions are
   available with all governors other than ``userspace``.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
       ``1`` or ``"cpu1"``).
   :param frequency: Frequency to set.

.. method:: target.cpufreq.get_frequency(cpu)
            target.cpufreq.set_frequency(cpu, frequency[, exact=True])

   Get and set current frequency on the specified CPU. ``set_frequency`` is only
   available if the current governor is ``userspace``.

   :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
       ``1`` or ``"cpu1"``).
   :param frequency: Frequency to set.

cpuidle
-------

``cpufreq`` is the kernel subsystem for managing CPU low power (idle) states.

.. method:: target.cpuidle.get_driver()

   Return the name current cpuidle driver.

.. method:: target.cpuidle.get_governor()

   Return the name current cpuidle governor (policy).

.. method:: target.cpuidle.get_states([cpu=0])

   Return idle states (optionally, for the specified CPU). Returns a list of
   :class:`CpuidleState` instances.

.. method:: target.cpuidle.get_state(state[, cpu=0])

   Return :class:`CpuidleState` instance (optionally, for the specified CPU)
   representing the specified idle state. ``state`` can be either an integer
   index of the state or a string with the states ``name`` or ``desc``.

.. method:: target.cpuidle.enable(state[, cpu=0])
            target.cpuidle.disable(state[, cpu=0])
            target.cpuidle.enable_all([cpu=0])
            target.cpuidle.disable_all([cpu=0])

    Enable or disable the specified or all states (optionally on the specified
    CPU.

You can also call ``enable()`` or ``disable()`` on :class:`CpuidleState` objects 
returned by get_state(s).

cgroups
-------

TODO

hwmon
-----

TODO

API
---

Generic Module API Description
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Modules implement discrete, optional pieces of functionality ("optional" in the
sense that the functionality may or may not be present on the target device, or
that it may or may not be necessary for a particular application).

Every module (ultimately) derives from :class:`Module` class.  A module must
define the following class attributes:

:name: A unique name for the module. This cannot clash with any of the existing
       names and must be a valid Python identifier, but is otherwise free-from.
:kind: This identifies the type of functionality a module implements, which in
       turn determines the interface implemented by the module (all modules of
       the same kind must expose a consistent interface). This must be a valid
       Python identifier, but is otherwise free-form, though, where possible,
       one should try to stick to an already-defined kind/interface, lest we end
       up with a bunch of modules implementing similar functionality but
       exposing slightly different interfaces.

       .. note:: It is possible to omit ``kind`` when defining a module, in
                 which case the module's ``name`` will be treated as its
                 ``kind`` as well.

:stage: This defines when the module will be installed into a :class:`Target`.
        Currently, the following values are allowed:

        :connected: The module is installed after a connection to the target has
                    been established. This is the default.
        :early: The module will be installed when a :class:`Target` is first
                created. This should be used for modules that do not rely on a
                live connection to the target.

Additionally, a module must implement a static (or class) method :func:`probe`:

.. method:: Module.probe(target)

    This method takes a :class:`Target` instance and returns ``True`` if this
    module is supported by that target, or ``False`` otherwise.

    .. note:: If the module ``stage`` is ``"early"``, this method cannot assume
              that a connection has been established (i.e. it can only access
              attributes of the Target that do not rely on a connection).

Installation and invocation
***************************

The default installation method will create an instance of a module (the
:class:`Target` instance being the sole argument) and assign it to the target
instance attribute named after the module's ``kind`` (or ``name`` if ``kind`` is
``None``).

It is possible to change the installation procedure for a module by overriding
the default :func:`install` method. The method must have the following
signature:

.. method:: Module.install(cls, target, **kwargs)

    Install the module into the target instance.


Implementation and Usage Patterns
*********************************

There are two common ways to implement the above API, corresponding to the two
common uses for modules:

- If a module provides an interface to a particular set of functionality (e.g.
  an OS subsystem), that  module would typically derive directly form
  :class:`Module` and  would leave ``kind`` unassigned, so that it is accessed
  by it name. Its instance's methods and attributes provide the interface for
  interacting with its functionality. For examples of this type of module, see
  the subsystem modules listed above (e.g. ``cpufreq``).
- If a module provides a platform- or infrastructure-specific implementation of
  a common function, the module would derive from one of :class:`Module`
  subclasses that define the interface for that function. In that case the
  module would be accessible via the common ``kind`` defined its super. The
  module would typically implement :func:`__call__` and be invoked directly. For
  examples of this type of module, see common function interface definitions
  below.


Common Function Interfaces
~~~~~~~~~~~~~~~~~~~~~~~~~~

This section documents :class:`Module` classes defining interface for common
functions. Classes derived from them provide concrete implementations for
specific platforms.


HardResetModule
***************

.. attribute:: HardResetModule.kind

    "hard_reset"

.. method:: HardResetModule.__call__()

    Must be implemented by derived classes.
    
    Implements hard reset for a target devices. The equivalent of physically
    power cycling the device.  This may be used by client code in situations
    where the target becomes unresponsive and/or a regular reboot is not
    possible.


BootModule
**********

.. attribute:: BootModule.kind

    "hard_reset"

.. method:: BootModule.__call__()

    Must be implemented by derived classes.

    Implements a boot procedure. This takes the device from (hard or soft)
    reset to a booted state where the device is ready to accept connections. For
    a lot of commercial devices the process is entirely automatic, however some
    devices (e.g. development boards), my require additional steps, such as
    interactions with the bootloader, in order to boot into the OS.

.. method:: Bootmodule.update(\*\*kwargs)

    Update the boot settings. Some boot sequences allow specifying settings
    that will be utilized during boot (e.g. linux kernel boot command line). The
    default implementation will set each setting in ``kwargs`` as an attribute of
    the boot module (or update the existing attribute).


FlashModule
***********

.. attribute:: FlashModule.kind

    "flash"

.. method:: __call__(image_bundle=None, images=None, boot_config=None)

    Must be implemented by derived classes.

    Flash the target platform with the specified images.

    :param image_bundle: A compressed bundle of image files with any associated
                         metadata. The format of the bundle is specific to a
                         particular implementation.
    :param images: A dict mapping image names/identifiers to the path on the
                   host file system of the corresponding image file. If both
                   this and ``image_bundle`` are specified, individual images
                   will override those in the bundle.
    :param boot_config: Some platforms require specifying boot arguments at the
                        time of flashing the images, rather than during each
                        reboot. For other platforms, this will be ignored.


Module Registration
~~~~~~~~~~~~~~~~~~~

Modules are specified on :class:`Target` or :class:`Platform` creation by name.
In order to find the class associated with the name, the module needs to be
registered with ``devlib``. This is accomplished by passing the module class
into :func:`register_module` method once it is defined.

.. note:: If you're wiring a module to be included as part of ``devlib`` code
          base, you can place the file with the module class under
          ``devlib/modules/`` in the source and it will be automatically
          enumerated. There is no need to explicitly register it in that case.

The code snippet below illustrates an implementation of a hard reset function
for an "Acme" device.

.. code:: python

    import os
    from devlib import HardResetModule, register_module


    class AcmeHardReset(HardResetModule):

        name = 'acme_hard_reset'

        def __call__(self):
            # Assuming Acme board comes with a "reset-acme-board" utility 
            os.system('reset-acme-board {}'.format(self.target.name))

    register_module(AcmeHardReset)

