mirror of
https://github.com/ARM-software/devlib.git
synced 2025-01-31 02:00:45 +00: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:
parent
72ded188fa
commit
92e16ee873
BIN
devlib/bin/arm64/get_clock_monotonic
Executable file
BIN
devlib/bin/arm64/get_clock_monotonic
Executable file
Binary file not shown.
BIN
devlib/bin/armeabi/get_clock_monotonic
Executable file
BIN
devlib/bin/armeabi/get_clock_monotonic
Executable file
Binary file not shown.
@ -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]
|
||||
|
6
src/get_clock_monotonic/Makefile
Normal file
6
src/get_clock_monotonic/Makefile
Normal 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 $@
|
18
src/get_clock_monotonic/get_clock_monotonic.c
Normal file
18
src/get_clock_monotonic/get_clock_monotonic.c
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user