summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2020-12-15 11:41:12 +0100
committerDaniel Friesel <daniel.friesel@uos.de>2020-12-15 11:41:12 +0100
commit758f5210f62468e233815f089432eb718071048d (patch)
tree791b7b4305465aec0d8b1be23f2d7d614070f0b3
parent1f3b8e7b216507f4bcbb65712013cba3e2c9d39c (diff)
add EnergyTrace++ support (hex annotations and state change indicators)
Use --with-hardware-states to enable it during measurement. It is automatically detected when loading an etlog file.
-rwxr-xr-xbin/msp430-etv58
1 files changed, 53 insertions, 5 deletions
diff --git a/bin/msp430-etv b/bin/msp430-etv
index 560bd2c..eaf9dc0 100755
--- a/bin/msp430-etv
+++ b/bin/msp430-etv
@@ -150,7 +150,7 @@ class PELT:
return changepoints
-def measure_data(filename, duration):
+def measure_data(filename, duration, energytrace_cmd="energytrace"):
# libmsp430.so must be available
if not "LD_LIBRARY_PATH" in os.environ:
os.environ[
@@ -158,10 +158,9 @@ def measure_data(filename, duration):
] = "{}/var/projects/msp430/MSP430Flasher_1.3.15".format(os.environ["HOME"])
# https://ess.cs.uos.de/git/df/energytrace-util must be available
- energytrace_cmd = "energytrace"
if which(energytrace_cmd) is None:
- energytrace_cmd = "{}/var/source/energytrace-util/energytrace".format(
- os.environ["HOME"]
+ energytrace_cmd = "{}/var/source/energytrace-util/{}".format(
+ os.environ["HOME"], energytrace_cmd
)
if filename is not None:
@@ -310,6 +309,11 @@ def main():
help="Draw histograms of reported energy values per measurement interval (i.e., the differences between each pair of consecutive total energy readings), measurement interval duration, and mean power values per measurement interval (calculated from energy difference and duration). Each histogram uses N buckets",
)
parser.add_argument(
+ "--with-hardware-states",
+ action="store_true",
+ help="Log CPU and peripheral states as well as energy readings. Requires EnergyTrace++ support. Reduces the sample rate to about 1 kHz.",
+ )
+ parser.add_argument(
"duration", type=int, nargs="?", help="Measurement duration in seconds"
)
@@ -331,6 +335,10 @@ def main():
else:
with open(args.load, "r") as f:
log_data = f.read()
+ elif args.with_hardware_states:
+ log_data = measure_data(
+ args.save, args.duration, energytrace_cmd="energytracepp"
+ )
else:
log_data = measure_data(args.save, args.duration)
@@ -339,6 +347,7 @@ def main():
data_lines = filter(lambda x: len(x) > 0 and x[0] != "#", lines)
data = np.empty((data_count, 4))
+ annotations = [None for i in range(data_count)]
skip_offset = 0
limit_index = data_count
@@ -349,7 +358,7 @@ def main():
if len(fields) == 4:
timestamp, current, voltage, total_energy = map(int, fields)
elif len(fields) == 5:
- cpustate = fields[0]
+ annotations[i] = fields[0]
timestamp, current, voltage, total_energy = map(int, fields[1:])
else:
raise RuntimeError('cannot parse line "{}"'.format(line))
@@ -369,6 +378,7 @@ def main():
data[i] = [timestamp, current, voltage, total_energy]
data = data[skip_offset:limit_index]
+ annotations = annotations[skip_offset:limit_index]
m_duration_us = data[-1, 0] - data[0, 0]
m_energy_nj = data[-1, 3] - data[0, 3]
@@ -549,6 +559,43 @@ def main():
if args.plot:
import matplotlib.pyplot as plt
+ if annotations[0]:
+ fig, ax = plt.subplots()
+ annotationbox = ax.annotate(
+ "",
+ xy=(0, 0),
+ xytext=(20, 20),
+ textcoords="offset points",
+ bbox=dict(boxstyle="round", fc="w"),
+ arrowprops=dict(arrowstyle="->"),
+ )
+ annotationbox.set_visible(True)
+
+ def hover(event):
+ if event.xdata and event.ydata:
+ annotationbox.set_visible(False)
+ annotationbox.xy = (event.xdata, event.ydata)
+ for i, timestamp in enumerate(data[1:, 0] * 1e-6):
+ if timestamp >= event.xdata:
+ annotationbox.set_text(annotations[i])
+ break
+ annotationbox.get_bbox_patch().set_alpha(0.4)
+ annotationbox.set_visible(True)
+ fig.canvas.draw_idle()
+
+ fig.canvas.mpl_connect("motion_notify_event", hover)
+
+ prev_annotation = "0000000000000000"
+ for i, annotation in enumerate(annotations):
+ if (
+ annotation != prev_annotation
+ and annotation != "0000000000000000"
+ and prev_annotation != "0000000000000000"
+ ):
+ plt.axvline(data[i, 0] * 1e-6, color="green")
+ if annotation != "0000000000000000":
+ prev_annotation = annotation
+
if args.plot == "U":
# mV
(energyhandle,) = plt.plot(
@@ -638,6 +685,7 @@ def main():
plt.grid(True)
if args.load:
plt.title(args.load)
+
plt.show()
if args.histogram: