2015-03-10 13:09:31 +00:00
|
|
|
# Copyright 2013-2015 ARM Limited
|
|
|
|
#
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
|
|
|
#
|
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
#
|
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
#
|
|
|
|
|
|
|
|
|
|
|
|
# pylint: disable=W0613,E1101
|
|
|
|
from __future__ import division
|
|
|
|
from collections import OrderedDict
|
|
|
|
|
|
|
|
from wlauto import Parameter, Instrument
|
|
|
|
from wlauto.exceptions import InstrumentError, ConfigError
|
|
|
|
from wlauto.utils.hwmon import discover_sensors
|
|
|
|
from wlauto.utils.types import list_of_strs
|
|
|
|
|
|
|
|
|
|
|
|
# sensor_kind: (report_type, units, conversion)
|
|
|
|
HWMON_SENSORS = {
|
|
|
|
'energy': ('diff', 'Joules', lambda x: x / 10 ** 6),
|
|
|
|
'temp': ('before/after', 'Celsius', lambda x: x / 10 ** 3),
|
|
|
|
}
|
|
|
|
|
|
|
|
HWMON_SENSOR_PRIORITIES = ['energy', 'temp']
|
|
|
|
|
|
|
|
|
|
|
|
class HwmonInstrument(Instrument):
|
|
|
|
|
|
|
|
name = 'hwmon'
|
|
|
|
description = """
|
|
|
|
Hardware Monitor (hwmon) is a generic Linux kernel subsystem,
|
|
|
|
providing access to hardware monitoring components like temperature or
|
|
|
|
voltage/current sensors.
|
|
|
|
|
|
|
|
The following web page has more information:
|
|
|
|
|
|
|
|
http://blogs.arm.com/software-enablement/925-linux-hwmon-power-management-and-arm-ds-5-streamline/
|
|
|
|
|
|
|
|
You can specify which sensors HwmonInstrument looks for by specifying
|
|
|
|
hwmon_sensors in your config.py, e.g. ::
|
|
|
|
|
|
|
|
hwmon_sensors = ['energy', 'temp']
|
|
|
|
|
|
|
|
If this setting is not specified, it will look for all sensors it knows about.
|
|
|
|
Current valid values are::
|
|
|
|
|
|
|
|
:energy: Collect energy measurements and report energy consumed
|
|
|
|
during run execution (the diff of before and after readings)
|
|
|
|
in Joules.
|
|
|
|
:temp: Collect temperature measurements and report the before and
|
|
|
|
after readings in degrees Celsius.
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
parameters = [
|
|
|
|
Parameter('sensors', kind=list_of_strs, default=['energy', 'temp'],
|
2015-06-04 15:50:23 +08:00
|
|
|
global_alias='hwmon_sensors',
|
2016-05-06 13:52:38 +01:00
|
|
|
allowed_values=HWMON_SENSORS.keys(),
|
2015-03-10 13:09:31 +00:00
|
|
|
description='The kinds of sensors hwmon instrument will look for')
|
|
|
|
]
|
|
|
|
|
|
|
|
def __init__(self, device, **kwargs):
|
|
|
|
super(HwmonInstrument, self).__init__(device, **kwargs)
|
|
|
|
|
|
|
|
if self.sensors:
|
|
|
|
self.sensor_kinds = {}
|
|
|
|
for kind in self.sensors:
|
2016-05-06 13:52:38 +01:00
|
|
|
self.sensor_kinds[kind] = HWMON_SENSORS[kind]
|
2015-03-10 13:09:31 +00:00
|
|
|
else:
|
|
|
|
self.sensor_kinds = HWMON_SENSORS
|
|
|
|
|
|
|
|
self.sensors = []
|
|
|
|
|
2015-05-07 09:39:33 +01:00
|
|
|
def initialize(self, context):
|
2015-03-10 13:09:31 +00:00
|
|
|
self.sensors = []
|
|
|
|
self.logger.debug('Searching for HWMON sensors.')
|
|
|
|
discovered_sensors = discover_sensors(self.device, self.sensor_kinds.keys())
|
|
|
|
for sensor in sorted(discovered_sensors, key=lambda s: HWMON_SENSOR_PRIORITIES.index(s.kind)):
|
|
|
|
self.logger.debug('Adding {}'.format(sensor.filepath))
|
|
|
|
self.sensors.append(sensor)
|
2015-05-07 09:39:33 +01:00
|
|
|
|
|
|
|
def setup(self, context):
|
2015-03-10 13:09:31 +00:00
|
|
|
for sensor in self.sensors:
|
|
|
|
sensor.clear_readings()
|
|
|
|
|
|
|
|
def fast_start(self, context):
|
|
|
|
for sensor in reversed(self.sensors):
|
|
|
|
sensor.take_reading()
|
|
|
|
|
|
|
|
def fast_stop(self, context):
|
|
|
|
for sensor in self.sensors:
|
|
|
|
sensor.take_reading()
|
|
|
|
|
|
|
|
def update_result(self, context):
|
|
|
|
for sensor in self.sensors:
|
|
|
|
try:
|
|
|
|
report_type, units, conversion = HWMON_SENSORS[sensor.kind]
|
|
|
|
if report_type == 'diff':
|
|
|
|
before, after = sensor.readings
|
|
|
|
diff = conversion(after - before)
|
2016-05-06 14:04:29 +01:00
|
|
|
context.result.add_metric(sensor.label, diff, units,
|
|
|
|
classifiers={"hwmon_device": sensor.device_name})
|
2015-03-10 13:09:31 +00:00
|
|
|
elif report_type == 'before/after':
|
|
|
|
before, after = sensor.readings
|
hwmon: print both before/after and mean temperatures
Print both before/after and mean temperatures of DCC and MCC
Example:
mp_a7bc_w01,bbench_with_audio,1,"arm,vexpress-temp DCC",34.062,Celsius mp_a7bc_w01,bbench_with_audio,1,"arm,vexpress-temp DCC before",33.849,Celsius mp_a7bc_w01,bbench_with_audio,1,"arm,vexpress-temp DCC after",34.275,Celsius mp_a7bc_w01,bbench_with_audio,1,"arm,vexpress-temp MCC",45.432,Celsius mp_a7bc_w01,bbench_with_audio,1,"arm,vexpress-temp MCC before",45.432,Celsius mp_a7bc_w01,bbench_with_audio,1,"arm,vexpress-temp MCC after",45.432,Celsius
Signed-off-by: Naresh Kamboju <naresh.kamboju@linaro.org>
2015-07-06 14:09:50 +01:00
|
|
|
mean = conversion((after + before) / 2)
|
2016-05-06 14:04:29 +01:00
|
|
|
context.result.add_metric(sensor.label, mean, units,
|
|
|
|
classifiers={"hwmon_device": sensor.device_name})
|
|
|
|
context.result.add_metric(sensor.label + ' before', conversion(before), units,
|
|
|
|
classifiers={"hwmon_device": sensor.device_name})
|
|
|
|
context.result.add_metric(sensor.label + ' after', conversion(after), units,
|
|
|
|
classifiers={"hwmon_device": sensor.device_name})
|
2015-03-10 13:09:31 +00:00
|
|
|
else:
|
|
|
|
raise InstrumentError('Unexpected report_type: {}'.format(report_type))
|
|
|
|
except ValueError, e:
|
|
|
|
self.logger.error('Could not collect all {} readings for {}'.format(sensor.kind, sensor.label))
|
|
|
|
self.logger.error('Got: {}'.format(e))
|