summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2021-04-15 16:10:23 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2021-04-15 16:10:23 +0200
commitebbd23fc2e1ebfe764350063259a27cc8e1b009e (patch)
tree663ee964642014343571286ee26189628875845f /lib
parent6bd652f1c2097ae228d20b14869e06cca439c07a (diff)
Prepare KRATOS support
Diffstat (limited to 'lib')
-rw-r--r--lib/harness.py38
-rw-r--r--lib/runner.py214
2 files changed, 221 insertions, 31 deletions
diff --git a/lib/harness.py b/lib/harness.py
index f329434..21bcd9e 100644
--- a/lib/harness.py
+++ b/lib/harness.py
@@ -37,6 +37,7 @@ class TransitionHarness:
repeat=0,
post_transition_delay_us=0,
energytrace_sync=None,
+ target=None,
):
"""
Create a new TransitionHarness
@@ -58,6 +59,7 @@ class TransitionHarness:
self.repeat = repeat
self.post_transition_delay_us = post_transition_delay_us
self.energytrace_sync = energytrace_sync
+ self.target = target
self.reset()
def copy(self):
@@ -387,6 +389,7 @@ class OnboardTimerHarness(TransitionHarness):
log_return_values=self.log_return_values,
repeat=self.repeat,
energytrace_sync=self.energytrace_sync,
+ target=self.target,
)
new_harness.traces = self.traces.copy()
new_harness.trace_id = self.trace_id
@@ -426,41 +429,16 @@ class OnboardTimerHarness(TransitionHarness):
ret = "#define PTALOG_TIMING\n"
ret += super().global_code()
if self.energytrace_sync == "led":
- # TODO Make nicer
- ret += """\nvoid runLASync(){
- // ======================= LED SYNC ================================
- #ifdef PTALOG_GPIO
- gpio.write(PTALOG_GPIO, 1);
- #endif
- gpio.led_on(0);
- gpio.led_on(1);
- #ifdef PTALOG_GPIO
- gpio.write(PTALOG_GPIO, 0);
- #endif
-
- for (unsigned char i = 0; i < 4; i++) {
- arch.sleep_ms(250);
- }
-
- #ifdef PTALOG_GPIO
- gpio.write(PTALOG_GPIO, 1);
- #endif
- gpio.led_off(0);
- gpio.led_off(1);
- #ifdef PTALOG_GPIO
- gpio.write(PTALOG_GPIO, 0);
- #endif
- // ======================= LED SYNC ================================
-}\n\n"""
+ ret += self.target.app_lasync_function()
return ret
def start_benchmark(self, benchmark_id=0):
ret = ""
if self.energytrace_sync == "led":
- ret += "runLASync();\n"
+ ret += self.target.app_lasync_call()
ret += "ptalog.passNop();\n"
if self.energytrace_sync == "led":
- ret += "arch.sleep_ms(250);\n"
+ ret += self.target.app_sleep(250)
ret += super().start_benchmark(benchmark_id)
return ret
@@ -468,10 +446,10 @@ class OnboardTimerHarness(TransitionHarness):
ret = ""
if self.energytrace_sync == "led":
ret += "counter.stop();\n"
- ret += "runLASync();\n"
+ ret += self.target.app_lasync_call()
ret += super().stop_benchmark()
if self.energytrace_sync == "led":
- ret += "arch.sleep_ms(250);\n"
+ ret += self.target.app_sleep(250)
return ret
def pass_transition(
diff --git a/lib/runner.py b/lib/runner.py
index f718180..ea3ee0d 100644
--- a/lib/runner.py
+++ b/lib/runner.py
@@ -352,12 +352,224 @@ class ShellMonitor:
pass
-class Arch:
+class KRATOS:
+ def __init__(self, opts=list()):
+ self.opts = opts
+
+ def app_header(self):
+ ret = (
+ '#include "AEMR.h"\n'
+ '#include "syscall/guarded_buzzer.h"\n'
+ '#include "drivers/counter.h"\n'
+ '#include "drivers/gpio.h"\n'
+ )
+ return ret
+
+ def app_function_start(self):
+ ret = (
+ "ImplementThread(EnergyBenchmarkApp, energyBenchmarkApp, 512);\n"
+ "void EnergyBenchmarkApp::action()\n"
+ "{\n"
+ "Guarded_Buzzer buz(500);\n"
+ )
+
+ return ret
+
+ def app_function_end(self):
+ return "}\n"
+
+ def app_delay(self, ms, comment=""):
+ return self.app_sleep(ms, comment)
+
+ def app_sleep(self, ms, comment=""):
+ if comment:
+ comment = f" // {comment}"
+ return f"buz.sleep({ms});{comment}\n"
+
+ def app_newlines(self):
+ return "uart << endl << endl;\n"
+
+ def app_lasync_call(self):
+ return "runLASync(buz);\n"
+
+ def app_lasync_function(self):
+ ret = """void runLASync(Guarded_Buzzer &buz){
+ setOutput(1, 0);
+ setOutput(1, 1);
+ pinHigh(1, 0);
+ pinHigh(1, 1);
+
+ buz.sleep(1000);
+
+ pinLow(1, 0);
+ pinLow(1, 1);
+}
+"""
+ return ret
+
+ def build(self, app, opts=list()):
+ command = ["make", "clean"]
+ command.extend(self.opts)
+ command.extend(opts)
+ logger.debug(f"Building: {' '.join(command)}")
+ res = subprocess.run(
+ command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ if res.returncode != 0:
+ raise RuntimeError(
+ "Build failure, executing {}:\n".format(command) + res.stderr
+ )
+ command = ["make"]
+ command.extend(self.opts)
+ command.extend(opts)
+ logger.debug(f"Building: {' '.join(command)}")
+ res = subprocess.run(
+ command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ if res.returncode != 0:
+ raise RuntimeError(
+ "Build failure, executing {}:\n ".format(command) + res.stderr
+ )
+ return command
+
+ def flash(self, app, opts=list()):
+ command = ["make", "flash"]
+ command.extend(self.opts)
+ command.extend(opts)
+ logger.debug(f"Flashing: {' '.join(command)}")
+ res = subprocess.run(
+ command,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ )
+ if res.returncode != 0:
+ raise RuntimeError("Flash failure")
+ return command
+
+ def get_monitor(self, **kwargs) -> object:
+ """
+ Return an appropriate monitor for arch, depending on "make info" output.
+
+ Port and Baud rate are taken from "make info".
+
+ :param energytrace: `EnergyTraceMonitor` options. Returns an EnergyTrace monitor if not None.
+ :param mimosa: `MIMOSAMonitor` options. Returns a MIMOSA monitor if not None.
+ """
+ if "mimosa" in kwargs and kwargs["mimosa"] is not None:
+ mimosa_kwargs = kwargs.pop("mimosa")
+ return MIMOSAMonitor("/dev/ttyACM1", "9600", **mimosa_kwargs, **kwargs)
+ elif "energytrace" in kwargs and kwargs["energytrace"] is not None:
+ energytrace_kwargs = kwargs.pop("energytrace").copy()
+ sync_mode = energytrace_kwargs.pop("sync")
+ if sync_mode == "la":
+ return EnergyTraceLogicAnalyzerMonitor(
+ "/dev/ttyACM1", "9600", **energytrace_kwargs, **kwargs
+ )
+ else:
+ return EnergyTraceMonitor(
+ "/dev/ttyACM1", "9600", **energytrace_kwargs, **kwargs
+ )
+ else:
+ kwargs.pop("energytrace", None)
+ kwargs.pop("mimosa", None)
+ return SerialMonitor("/dev/ttyACM1", "9600", **kwargs)
+
+ def sleep_ms(self, duration: int, opts=list()) -> str:
+ max_sleep = 250
+ if max_sleep is not None and duration > max_sleep:
+ sub_sleep_count = duration // max_sleep
+ tail_sleep = duration % max_sleep
+ ret = f"for (unsigned char i = 0; i < {sub_sleep_count}; i++) {{ buz.sleep({max_sleep}); }}\n"
+ if tail_sleep > 0:
+ ret += f"buz.sleep({tail_sleep});\n"
+ return ret
+ return f"buz.sleep({duration});\n"
+
+ def get_counter_limits_us(self, opts=list()) -> tuple:
+ """Return duration of one counter step and one counter overflow in us."""
+ cpu_freq = 16_000_000
+ overflow_value = 65536
+ max_overflow = 65535
+ return (
+ 1_000_000 / cpu_freq,
+ overflow_value * 1_000_000 / cpu_freq,
+ max_overflow,
+ )
+
+
+class Multipass:
def __init__(self, name, opts=list()):
self.name = name
self.opts = opts
self.info = self.get_info()
+ def app_header(self):
+ ret = '#include "arch.h"\n' '#include "driver/gpio.h"\n'
+ return ret
+
+ def app_function_start(self):
+ ret = "int main(void)\n{\n"
+
+ for driver in ("arch", "gpio", "kout"):
+ ret += f"{driver}.setup();\n"
+
+ return ret
+
+ def app_function_end(self):
+ return "while (1) { }\nreturn 0;\n}\n"
+
+ def app_delay(self, ms, comment=""):
+ if comment:
+ comment = f" // {comment}"
+ return f"arch.delay_ms({ms});{comment}\n"
+
+ def app_sleep(self, ms, comment=""):
+ if ms > 250:
+ # TODO build multiple sleep_ms calls
+ raise ValueError("msp430 does not support sleep longer than 250ms")
+ if comment:
+ comment = f" // {comment}"
+ return f"arch.sleep_ms({ms});{comment}\n"
+
+ def app_newlines(self):
+ return "kout << endl << endl;\n"
+
+ def app_lasync_call(self):
+ return "runLASync();\n"
+
+ def app_lasync_function(self):
+ ret = """void runLASync(){
+ #ifdef PTALOG_GPIO
+ gpio.write(PTALOG_GPIO, 1);
+ #endif
+ gpio.led_on(0);
+ gpio.led_on(1);
+ #ifdef PTALOG_GPIO
+ gpio.write(PTALOG_GPIO, 0);
+ #endif
+
+ for (unsigned char i = 0; i < 4; i++) {
+ arch.sleep_ms(250);
+ }
+
+ #ifdef PTALOG_GPIO
+ gpio.write(PTALOG_GPIO, 1);
+ #endif
+ gpio.led_off(0);
+ gpio.led_off(1);
+ #ifdef PTALOG_GPIO
+ gpio.write(PTALOG_GPIO, 0);
+ #endif
+}\n\n"""
+ return ret
+
def build(self, app, opts=list()):
command = ["make", "arch={}".format(self.name), "app={}".format(app), "clean"]
command.extend(self.opts)