Example #1
0
 def test_dfs_objects(self):
     pta = PTA(["IDLE", "TX"])
     pta.add_transition("UNINITIALIZED", "IDLE", "init")
     pta.add_transition("IDLE", "TX", "send")
     pta.add_transition("TX", "IDLE", "txComplete")
     traces = list(pta.dfs(2))
     self.assertEqual(len(traces), 1)
     trace = traces[0]
     self.assertEqual(len(trace), 3)
     self.assertEqual(trace[0][0].name, "init")
     self.assertEqual(trace[1][0].name, "send")
     self.assertEqual(trace[2][0].name, "txComplete")
     self.assertEqual(pta.get_transition_id(trace[0][0]), 0)
     self.assertEqual(pta.get_transition_id(trace[1][0]), 1)
     self.assertEqual(pta.get_transition_id(trace[2][0]), 2)
Example #2
0
 def test_dfs_with_sleep(self):
     pta = PTA(["IDLE", "TX"])
     pta.add_transition("UNINITIALIZED", "IDLE", "init")
     pta.add_transition("IDLE", "TX", "send")
     pta.add_transition("TX", "IDLE", "txComplete")
     traces = list(pta.dfs(2, sleep=10))
     self.assertEqual(len(traces), 1)
     trace = traces[0]
     self.assertEqual(len(trace), 6)
     self.assertIsNone(trace[0][0])
     self.assertEqual(trace[1][0].name, "init")
     self.assertIsNone(trace[2][0])
     self.assertEqual(trace[3][0].name, "send")
     self.assertIsNone(trace[4][0])
     self.assertEqual(trace[5][0].name, "txComplete")
     self.assertEqual(pta.get_transition_id(trace[1][0]), 0)
     self.assertEqual(pta.get_transition_id(trace[3][0]), 1)
     self.assertEqual(pta.get_transition_id(trace[5][0]), 2)
Example #3
0
def benchmark_from_runs(
    pta: PTA,
    runs: list,
    harness: OnboardTimerHarness,
    benchmark_id: int = 0,
    dummy=False,
    repeat=0,
) -> io.StringIO:
    outbuf = io.StringIO()

    outbuf.write(target.app_header())

    if dummy:
        outbuf.write('#include "driver/dummy.h"\n')
    elif "includes" in pta.codegen:
        for include in pta.codegen["includes"]:
            outbuf.write('#include "{}"\n'.format(include))
    outbuf.write(harness.global_code())

    outbuf.write(target.app_function_start())

    # There is a race condition between flashing the code and starting the UART log.
    # When starting the log before flashing, output from a previous benchmark may cause bogus data to be added.
    # When flashing first and then starting the log, the first log lines may be lost.
    # To work around this, we flash first, then start the log, and use this delay statement to ensure that no output is lost.
    # This is also useful to faciliate MIMOSA calibration after flashing
    # For MIMOSA, the DUT is disconnected from power during calibration, so
    # it must be set up after the calibration delay.
    # For energytrace, the device is connected to VCC and set up before
    # the initialization delay to -- this puts it into a well-defined state and
    # decreases pre-sync power consumption
    if "energytrace" not in opt:
        if "mimosa" in opt:
            outbuf.write(target.app_delay(12000))
        else:
            outbuf.write(target.app_delay(2000))
        # Output some newlines to ensure the parser can determine the start of the first real output line
        outbuf.write(target.app_newlines())

    if "setup" in pta.codegen:
        for call in pta.codegen["setup"]:
            outbuf.write(call)

    if "energytrace" in opt:
        outbuf.write("for (unsigned char j = 0; j < 10; j++) {\n")
        outbuf.write(target.app_sleep(250))
        outbuf.write("}\n")
        # Output some newlines to ensure the parser can determine the start of the first real output line
        outbuf.write(target.app_newlines())

    if repeat:
        outbuf.write("unsigned char i = 0;\n")
        outbuf.write("while (i++ < {}) {{\n".format(repeat))
    else:
        outbuf.write("while (1) {\n")

    outbuf.write(harness.start_benchmark())

    class_prefix = ""
    if "instance" in opt:
        class_prefix = "{}.".format(opt["instance"])
    elif "instance" in pta.codegen:
        class_prefix = "{}.".format(pta.codegen["instance"])

    num_transitions = 0
    num_traces = 0
    for run in runs:
        outbuf.write(harness.start_run())
        harness.start_trace()
        param = pta.get_initial_param_dict()
        for transition, arguments, parameter in run:
            num_transitions += 1
            harness.append_transition(transition.name, param, arguments)
            harness.append_state(transition.destination.name, parameter.copy())
            outbuf.write("// {} -> {}\n".format(transition.origin.name,
                                                transition.destination.name))
            if transition.is_interrupt:
                outbuf.write("// wait for {} interrupt\n".format(
                    transition.name))
                transition_code = "// TODO add startTransition / stopTransition calls to interrupt routine"
            else:
                transition_code = "{}{}({});".format(
                    class_prefix, transition.name,
                    ", ".join(map(str, arguments)))
            outbuf.write(
                harness.pass_transition(
                    pta.get_transition_id(transition),
                    transition_code,
                    transition=transition,
                ))

            param = parameter

            outbuf.write("// current parameters: {}\n".format(", ".join(
                map(lambda kv: "{}={}".format(*kv), param.items()))))

            if "delay_after_ms" in transition.codegen:
                if "energytrace" in opt:
                    outbuf.write(
                        target.app_sleep(
                            transition.codegen["delay_after_ms"],
                            f"{transition.destination.name} -- delay mandated by codegen.delay_after_ms",
                        ))
                else:
                    outbuf.write(
                        target.app_delay(
                            transition.codegen["delay_after_ms"],
                            f"{transition.destination.name} -- delay mandated by codegen.delay_after_ms",
                        ))
            elif opt["sleep"]:
                if "energytrace" in opt:
                    outbuf.write(f"// -> {transition.destination.name}\n")
                    outbuf.write(target.sleep_ms(opt["sleep"]))
                else:
                    outbuf.write(f"// -> {transition.destination.name}\n")
                    outbuf.write(target.app_delay(opt["sleep"]))

        outbuf.write(harness.stop_run(num_traces))
        if dummy:
            outbuf.write(
                'kout << "[Energy] " << {}getEnergy() << endl;\n'.format(
                    class_prefix))
        outbuf.write("\n")
        num_traces += 1

    outbuf.write(harness.stop_benchmark())
    outbuf.write("}\n")

    # Ensure logging can be terminated after the specified number of measurements
    outbuf.write(harness.start_benchmark())
    outbuf.write(target.app_function_end())

    return outbuf