1
0
mirror of https://github.com/ARM-software/devlib.git synced 2024-10-05 18:30:50 +01:00

instrument/daq: Add an explicit time column to the DAQ measurements

Add the monotonic clock time to the energy measurements to help
correlate the measurement with those of other collectors, like
FtraceCollector or LogcatCollector.
This commit is contained in:
Javi Merino 2020-02-11 18:18:22 +00:00 committed by Marc Bonnici
parent 72ded188fa
commit 92e16ee873
5 changed files with 67 additions and 5 deletions

Binary file not shown.

Binary file not shown.

View File

@ -16,8 +16,10 @@
import os
import shutil
import tempfile
import time
from itertools import chain, zip_longest
from devlib.host import PACKAGE_BIN_DIRECTORY
from devlib.instrument import Instrument, MeasurementsCsv, CONTINUOUS
from devlib.exception import HostError
from devlib.utils.csvutil import csvwriter, create_reader
@ -45,7 +47,8 @@ class DaqInstrument(Instrument):
dv_range=0.2,
sample_rate_hz=10000,
channel_map=(0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23),
keep_raw=False
keep_raw=False,
time_as_clock_monotonic=True
):
# pylint: disable=no-member
super(DaqInstrument, self).__init__(target)
@ -53,6 +56,7 @@ class DaqInstrument(Instrument):
self._need_reset = True
self._raw_files = []
self.tempdir = None
self.target_monotonic_clock_at_start = 0.0
if DaqClient is None:
raise HostError('Could not import "daqpower": {}'.format(import_error_mesg))
if labels is None:
@ -76,11 +80,30 @@ class DaqInstrument(Instrument):
channel_map=channel_map,
labels=labels)
self.sample_rate_hz = sample_rate_hz
self.time_as_clock_monotonic = time_as_clock_monotonic
self.add_channel('Time', 'time')
for label in labels:
for kind in ['power', 'voltage']:
self.add_channel(label, kind)
if time_as_clock_monotonic:
host_path = os.path.join(PACKAGE_BIN_DIRECTORY, self.target.abi,
'get_clock_monotonic')
self.clock_monotonic_cmd = self.target.install_if_needed(host_path,
search_system_binaries=False)
def calculate_monotonic_offset(self):
time_before = time.time()
out = self.target.execute(self.clock_monotonic_cmd)
time_after = time.time()
remote_clock_monotonic = float(out)
propagation_delay = (time_after - time_before) / 2
monotonic_at_end = remote_clock_monotonic + propagation_delay
return time_after - monotonic_at_end
def reset(self, sites=None, kinds=None, channels=None):
super(DaqInstrument, self).reset(sites, kinds, channels)
self.daq_client.close()
@ -90,9 +113,19 @@ class DaqInstrument(Instrument):
def start(self):
if self._need_reset:
self.reset()
# Preserve channel order
self.reset(channels=self.channels.keys())
if self.time_as_clock_monotonic:
target_monotonic_offset = self.calculate_monotonic_offset()
time_start = time.time()
self.daq_client.start()
if self.time_as_clock_monotonic:
time_end = time.time()
self.target_monotonic_clock_at_start = (time_start + time_end) / 2 - target_monotonic_offset
def stop(self):
self.daq_client.stop()
self._need_reset = True
@ -118,11 +151,12 @@ class DaqInstrument(Instrument):
site_readers[site] = reader
file_handles.append(fh)
except KeyError:
if not site.startswith("Time"):
message = 'Could not get DAQ trace for {}; Obtained traces are in {}'
raise HostError(message.format(site, self.tempdir))
# The first row is the headers
channel_order = []
channel_order = ['Time_time']
for site, reader in site_readers.items():
channel_order.extend(['{}_{}'.format(site, kind)
for kind in next(reader)])
@ -131,7 +165,11 @@ class DaqInstrument(Instrument):
row_iter = zip_longest(*site_readers.values(), fillvalue=(None, None))
for raw_row in row_iter:
raw_row = list(chain.from_iterable(raw_row))
raw_row.insert(0, _read_rows.row_time_s)
yield raw_row
_read_rows.row_time_s += 1.0 / self.sample_rate_hz
_read_rows.row_time_s = self.target_monotonic_clock_at_start
with csvwriter(outfile) as writer:
field_names = [c.label for c in self.active_channels]

View File

@ -0,0 +1,6 @@
CFLAGS=-Wall --pedantic-errors -O2 -static
all: get_clock_monotonic
get_clock_monotonic: get_clock_monotonic.c
$(CC) $(CFLAGS) $^ -o $@

View File

@ -0,0 +1,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
int ret;
struct timespec tp;
ret = clock_gettime(CLOCK_MONOTONIC, &tp);
if (ret) {
perror("clock_gettime()");
return EXIT_FAILURE;
}
printf("%ld.%ld\n", tp.tv_sec, tp.tv_nsec);
return EXIT_SUCCESS;
}