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