Add Makefile support for more output binaries, add clock test

This commit is contained in:
2020-04-18 12:18:32 -07:00
parent ef23f1d03a
commit acba841bf1
6 changed files with 195 additions and 262 deletions

View File

@@ -1,3 +1,5 @@
#!/usr/bin/env python3
# Copyright (C) 2020 Max Regan
# Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,13 +26,18 @@ import serial.tools.list_ports
import logging
import pylink
import time
import os
import sys
from typing import List
PYTEST_DIR = os.path.dirname(os.path.abspath(__file__))
DEFAULT_FW_DIR = os.path.abspath(PYTEST_DIR + "../../../../firmware/")
SAMPLE_TIME_MS = 2500
SAMPLES_PER_SEC = 12000000
DRIVER = "fx2lafw"
TEST_START_TEXT = b"TEST_BEGIN\r\n"
TEST_PASS_TEXT = b"TEST_PASS\r\n"
TEST_FAIL_TEXT = b"TEST_FAIL\r\n"
@pytest.fixture
def logger():
@@ -40,7 +47,17 @@ def logger():
@pytest.fixture
def context_factory():
def create_context(mcu: str, addr: int, fw_path: str, leave_halted: bool=False):
def create_context(fw_rel_path: str,
mcu: str="STM32L412RB",
addr: int=0x8000000,
leave_halted: bool=False):
proc = subprocess.run(["make", "BOARD=devboard", fw_rel_path],
cwd=DEFAULT_FW_DIR,
capture_output=True,
check=True)
logging.info("Make process stdout: {}".format(proc.stdout))
ports = serial.tools.list_ports.comports()
if len(ports) == 0:
raise RuntimeError("No serial devices found")
@@ -56,44 +73,70 @@ def context_factory():
jlink.set_tif(pylink.enums.JLinkInterfaces.SWD)
jlink.connect(mcu)
#jlink.set_reset_strategy(pylink.enums.JLinkResetStrategyCortexM3.HALT_AFTER_BTL)
jlink.flash_file(fw_path, addr)
fw = DEFAULT_FW_DIR + "/" + fw_rel_path
logging.info("Flashing {}...".format(fw))
jlink.flash_file(fw, addr)
logging.info("Flashing done.")
assert jlink.halted()
jlink.reset(halt=True)
serial_dev = serial.Serial(port=ports[0].device, baudrate=115200)
if not leave_halted:
jlink.reset(halt=False)
while True:
try:
serial_dev.read_until(b"HELLO WORLD!\r\n")
except serial.serialutil.SerialException:
continue
break
serial_dev = serial.Serial(port=ports[0].device, baudrate=115200, timeout=1)
if leave_halted:
return serial_dev, jlink
# Start test test, and check that it started correctly over serial
jlink.reset(halt=False)
while True:
try:
logging.info("Waiting for firmware to start...")
assert serial_dev.read_until(TEST_START_TEXT).endswith(TEST_START_TEXT), \
"Timed out starting test firmware application"
logging.debug("Test execution started")
except serial.serialutil.SerialException:
continue
break
return serial_dev, jlink
return create_context
def test_serial(context_factory, logger):
serial_dev, jlink = context_factory(
"STM32L412RB",
0x8000000,
"/home/max/work/TimelyReference/firmware/watch.bin"
)
def test_basic(context_factory, logger):
serial_dev, jlink = context_factory("Test/basic.bin")
text = serial_dev.read_until(TEST_PASS_TEXT)
print("Got serial output: {}".format(text))
assert text.endswith(TEST_PASS_TEXT)
lines = [serial_dev.readline().decode("ascii", errors="ignore") for _ in range(3)]
logger.info("Test lines: {}".format(lines))
assert lines[0] == "Counter: 0\r\n"
assert lines[1] == "HELLO WORLD!\r\n"
assert lines[2] == "Counter: 1\r\n"
def test_watch(context_factory, logger):
serial_dev, jlink = context_factory("Application/main.bin", leave_halted=True)
jlink.reset(halt=False)
def test_clock(context_factory, logger):
serial_dev, jlink = context_factory("Test/clock.bin")
serial_dev.timeout = 1.5
START_MARKER = b"GO\r\n"
END_MARKER = b"STOP\r\n"
start_text = serial_dev.read_until(START_MARKER)
start = time.monotonic()
end_text = serial_dev.read_until(END_MARKER)
end = time.monotonic()
delta = end - start
logger.debug("Serial text: {}".format(start_text))
logger.debug("Serial text: {}".format(end_text))
logger.info("Start time: {}".format(start))
logger.info("End time: {}".format(end))
logger.info("Delta time: {}".format(delta))
# TODO: Using a single pin, instead of UART, would make this more
# accurate. Add support via sigrok.
assert start_text.endswith(START_MARKER)
assert end_text.endswith(END_MARKER)
assert delta < 1.1 and delta > .9
def main():
pytest.main()
pytest.main(sys.argv)
if __name__ == "__main__":
main()