diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2021-04-15 16:10:23 +0200 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2021-04-15 16:10:23 +0200 |
commit | ebbd23fc2e1ebfe764350063259a27cc8e1b009e (patch) | |
tree | 663ee964642014343571286ee26189628875845f /lib | |
parent | 6bd652f1c2097ae228d20b14869e06cca439c07a (diff) |
Prepare KRATOS support
Diffstat (limited to 'lib')
-rw-r--r-- | lib/harness.py | 38 | ||||
-rw-r--r-- | lib/runner.py | 214 |
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) |