Home | History | Annotate | Download | only in doc
      1 .. _modules:
      2 
      3 Modules
      4 =======
      5 
      6 Modules add additional functionality to the core :class:`Target` interface.
      7 Usually, it is support for specific subsystems on the target. Modules are
      8 instantiated as attributes of the :class:`Target` instance.
      9 
     10 hotplug
     11 -------
     12 
     13 Kernel ``hotplug`` subsystem allows offlining ("removing") cores from the
     14 system, and onlining them back in. The ``devlib`` module exposes a simple
     15 interface to this subsystem
     16 
     17 .. code:: python
     18 
     19    from devlib import LocalLinuxTarget
     20    target = LocalLinuxTarget()
     21 
     22    # offline cpus 2 and 3, "removing" them from the system
     23    target.hotplug.offline(2, 3)
     24 
     25    # bring CPU 2 back in
     26    target.hotplug.online(2)
     27 
     28    # Make sure all cpus are online
     29    target.hotplug.online_all()
     30 
     31 cpufreq
     32 -------
     33 
     34 ``cpufreq`` is the kernel subsystem for managing DVFS (Dynamic Voltage and
     35 Frequency Scaling). It allows controlling frequency ranges and switching
     36 policies (governors). The ``devlib`` module exposes the following interface
     37 
     38 .. note:: On ARM big.LITTLE systems, all cores on a cluster (usually all cores
     39           of the same type) are in the same frequency domain, so setting
     40           ``cpufreq`` state on one core on a cluster will affect all cores on
     41           that cluster. Because of this, some devices only expose cpufreq sysfs
     42           interface (which is what is used by the ``devlib`` module) on the
     43           first cpu in a cluster. So to keep your scripts portable, always use
     44           the fist (online) CPU in a cluster to set ``cpufreq`` state.
     45 
     46 .. method:: target.cpufreq.list_governors(cpu)
     47 
     48    List cpufreq governors available for the specified cpu. Returns a list of
     49    strings.
     50 
     51    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
     52                ``1`` or ``"cpu1"``).
     53 
     54 .. method:: target.cpufreq.list_governor_tunables(cpu)
     55 
     56    List the tunables for the specified cpu's current governor.
     57 
     58    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
     59        ``1`` or ``"cpu1"``).
     60 
     61 
     62 .. method:: target.cpufreq.get_governor(cpu)
     63 
     64    Returns the name of the currently set governor for the specified cpu.
     65 
     66    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
     67                ``1`` or ``"cpu1"``).
     68 
     69 .. method:: target.cpufreq.set_governor(cpu, governor, \*\*kwargs)
     70 
     71    Sets the governor for the specified cpu.
     72 
     73    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
     74         ``1`` or ``"cpu1"``).
     75    :param governor: The name of the governor. This must be one of the governors 
     76                 supported by the CPU (as returned by ``list_governors()``.
     77 
     78    Keyword arguments may be used to specify governor tunable values.
     79 
     80 
     81 .. method:: target.cpufreq.get_governor_tunables(cpu)
     82 
     83    Return a dict with the values of the specified CPU's current governor.
     84 
     85    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
     86        ``1`` or ``"cpu1"``).
     87 
     88 .. method:: target.cpufreq.set_governor_tunables(cpu, \*\*kwargs)
     89 
     90    Set the tunables for the current governor on the specified CPU.
     91 
     92    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
     93        ``1`` or ``"cpu1"``).
     94 
     95    Keyword arguments should be used to specify tunable values.
     96 
     97 .. method:: target.cpufreq.list_frequencies(cpu)
     98 
     99    List DVFS frequencies supported by the specified CPU. Returns a list of ints.
    100 
    101    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
    102        ``1`` or ``"cpu1"``).
    103 
    104 .. method:: target.cpufreq.get_min_frequency(cpu)
    105             target.cpufreq.get_max_frequency(cpu)
    106             target.cpufreq.set_min_frequency(cpu, frequency[, exact=True])
    107             target.cpufreq.set_max_frequency(cpu, frequency[, exact=True])
    108 
    109    Get and set min and max frequencies on the specified CPU. "set" functions are
    110    available with all governors other than ``userspace``.
    111 
    112    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
    113        ``1`` or ``"cpu1"``).
    114    :param frequency: Frequency to set.
    115 
    116 .. method:: target.cpufreq.get_frequency(cpu)
    117             target.cpufreq.set_frequency(cpu, frequency[, exact=True])
    118 
    119    Get and set current frequency on the specified CPU. ``set_frequency`` is only
    120    available if the current governor is ``userspace``.
    121 
    122    :param cpu: The cpu; could be a numeric or the corresponding string (e.g.
    123        ``1`` or ``"cpu1"``).
    124    :param frequency: Frequency to set.
    125 
    126 cpuidle
    127 -------
    128 
    129 ``cpufreq`` is the kernel subsystem for managing CPU low power (idle) states.
    130 
    131 .. method:: target.cpuidle.get_driver()
    132 
    133    Return the name current cpuidle driver.
    134 
    135 .. method:: target.cpuidle.get_governor()
    136 
    137    Return the name current cpuidle governor (policy).
    138 
    139 .. method:: target.cpuidle.get_states([cpu=0])
    140 
    141    Return idle states (optionally, for the specified CPU). Returns a list of
    142    :class:`CpuidleState` instances.
    143 
    144 .. method:: target.cpuidle.get_state(state[, cpu=0])
    145 
    146    Return :class:`CpuidleState` instance (optionally, for the specified CPU)
    147    representing the specified idle state. ``state`` can be either an integer
    148    index of the state or a string with the states ``name`` or ``desc``.
    149 
    150 .. method:: target.cpuidle.enable(state[, cpu=0])
    151             target.cpuidle.disable(state[, cpu=0])
    152             target.cpuidle.enable_all([cpu=0])
    153             target.cpuidle.disable_all([cpu=0])
    154 
    155     Enable or disable the specified or all states (optionally on the specified
    156     CPU.
    157 
    158 You can also call ``enable()`` or ``disable()`` on :class:`CpuidleState` objects 
    159 returned by get_state(s).
    160 
    161 cgroups
    162 -------
    163 
    164 TODO
    165 
    166 hwmon
    167 -----
    168 
    169 TODO
    170 
    171 API
    172 ---
    173 
    174 Generic Module API Description
    175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    176 
    177 Modules implement discrete, optional pieces of functionality ("optional" in the
    178 sense that the functionality may or may not be present on the target device, or
    179 that it may or may not be necessary for a particular application).
    180 
    181 Every module (ultimately) derives from :class:`Module` class.  A module must
    182 define the following class attributes:
    183 
    184 :name: A unique name for the module. This cannot clash with any of the existing
    185        names and must be a valid Python identifier, but is otherwise free-from.
    186 :kind: This identifies the type of functionality a module implements, which in
    187        turn determines the interface implemented by the module (all modules of
    188        the same kind must expose a consistent interface). This must be a valid
    189        Python identifier, but is otherwise free-form, though, where possible,
    190        one should try to stick to an already-defined kind/interface, lest we end
    191        up with a bunch of modules implementing similar functionality but
    192        exposing slightly different interfaces.
    193 
    194        .. note:: It is possible to omit ``kind`` when defining a module, in
    195                  which case the module's ``name`` will be treated as its
    196                  ``kind`` as well.
    197 
    198 :stage: This defines when the module will be installed into a :class:`Target`.
    199         Currently, the following values are allowed:
    200 
    201         :connected: The module is installed after a connection to the target has
    202                     been established. This is the default.
    203         :early: The module will be installed when a :class:`Target` is first
    204                 created. This should be used for modules that do not rely on a
    205                 live connection to the target.
    206 
    207 Additionally, a module must implement a static (or class) method :func:`probe`:
    208 
    209 .. method:: Module.probe(target)
    210 
    211     This method takes a :class:`Target` instance and returns ``True`` if this
    212     module is supported by that target, or ``False`` otherwise.
    213 
    214     .. note:: If the module ``stage`` is ``"early"``, this method cannot assume
    215               that a connection has been established (i.e. it can only access
    216               attributes of the Target that do not rely on a connection).
    217 
    218 Installation and invocation
    219 ***************************
    220 
    221 The default installation method will create an instance of a module (the
    222 :class:`Target` instance being the sole argument) and assign it to the target
    223 instance attribute named after the module's ``kind`` (or ``name`` if ``kind`` is
    224 ``None``).
    225 
    226 It is possible to change the installation procedure for a module by overriding
    227 the default :func:`install` method. The method must have the following
    228 signature:
    229 
    230 .. method:: Module.install(cls, target, **kwargs)
    231 
    232     Install the module into the target instance.
    233 
    234 
    235 Implementation and Usage Patterns
    236 *********************************
    237 
    238 There are two common ways to implement the above API, corresponding to the two
    239 common uses for modules:
    240 
    241 - If a module provides an interface to a particular set of functionality (e.g.
    242   an OS subsystem), that  module would typically derive directly form
    243   :class:`Module` and  would leave ``kind`` unassigned, so that it is accessed
    244   by it name. Its instance's methods and attributes provide the interface for
    245   interacting with its functionality. For examples of this type of module, see
    246   the subsystem modules listed above (e.g. ``cpufreq``).
    247 - If a module provides a platform- or infrastructure-specific implementation of
    248   a common function, the module would derive from one of :class:`Module`
    249   subclasses that define the interface for that function. In that case the
    250   module would be accessible via the common ``kind`` defined its super. The
    251   module would typically implement :func:`__call__` and be invoked directly. For
    252   examples of this type of module, see common function interface definitions
    253   below.
    254 
    255 
    256 Common Function Interfaces
    257 ~~~~~~~~~~~~~~~~~~~~~~~~~~
    258 
    259 This section documents :class:`Module` classes defining interface for common
    260 functions. Classes derived from them provide concrete implementations for
    261 specific platforms.
    262 
    263 
    264 HardResetModule
    265 ***************
    266 
    267 .. attribute:: HardResetModule.kind
    268 
    269     "hard_reset"
    270 
    271 .. method:: HardResetModule.__call__()
    272 
    273     Must be implemented by derived classes.
    274     
    275     Implements hard reset for a target devices. The equivalent of physically
    276     power cycling the device.  This may be used by client code in situations
    277     where the target becomes unresponsive and/or a regular reboot is not
    278     possible.
    279 
    280 
    281 BootModule
    282 **********
    283 
    284 .. attribute:: BootModule.kind
    285 
    286     "hard_reset"
    287 
    288 .. method:: BootModule.__call__()
    289 
    290     Must be implemented by derived classes.
    291 
    292     Implements a boot procedure. This takes the device from (hard or soft)
    293     reset to a booted state where the device is ready to accept connections. For
    294     a lot of commercial devices the process is entirely automatic, however some
    295     devices (e.g. development boards), my require additional steps, such as
    296     interactions with the bootloader, in order to boot into the OS.
    297 
    298 .. method:: Bootmodule.update(\*\*kwargs)
    299 
    300     Update the boot settings. Some boot sequences allow specifying settings
    301     that will be utilized during boot (e.g. linux kernel boot command line). The
    302     default implementation will set each setting in ``kwargs`` as an attribute of
    303     the boot module (or update the existing attribute).
    304 
    305 
    306 FlashModule
    307 ***********
    308 
    309 .. attribute:: FlashModule.kind
    310 
    311     "flash"
    312 
    313 .. method:: __call__(image_bundle=None, images=None, boot_config=None)
    314 
    315     Must be implemented by derived classes.
    316 
    317     Flash the target platform with the specified images.
    318 
    319     :param image_bundle: A compressed bundle of image files with any associated
    320                          metadata. The format of the bundle is specific to a
    321                          particular implementation.
    322     :param images: A dict mapping image names/identifiers to the path on the
    323                    host file system of the corresponding image file. If both
    324                    this and ``image_bundle`` are specified, individual images
    325                    will override those in the bundle.
    326     :param boot_config: Some platforms require specifying boot arguments at the
    327                         time of flashing the images, rather than during each
    328                         reboot. For other platforms, this will be ignored.
    329 
    330 
    331 Module Registration
    332 ~~~~~~~~~~~~~~~~~~~
    333 
    334 Modules are specified on :class:`Target` or :class:`Platform` creation by name.
    335 In order to find the class associated with the name, the module needs to be
    336 registered with ``devlib``. This is accomplished by passing the module class
    337 into :func:`register_module` method once it is defined.
    338 
    339 .. note:: If you're wiring a module to be included as part of ``devlib`` code
    340           base, you can place the file with the module class under
    341           ``devlib/modules/`` in the source and it will be automatically
    342           enumerated. There is no need to explicitly register it in that case.
    343 
    344 The code snippet below illustrates an implementation of a hard reset function
    345 for an "Acme" device.
    346 
    347 .. code:: python
    348 
    349     import os
    350     from devlib import HardResetModule, register_module
    351 
    352 
    353     class AcmeHardReset(HardResetModule):
    354 
    355         name = 'acme_hard_reset'
    356 
    357         def __call__(self):
    358             # Assuming Acme board comes with a "reset-acme-board" utility 
    359             os.system('reset-acme-board {}'.format(self.target.name))
    360 
    361     register_module(AcmeHardReset)
    362 
    363