diff --git a/ports/qemu-arm/Makefile b/ports/qemu-arm/Makefile index f521a0c5ad82d..d68c07fb6303e 100644 --- a/ports/qemu-arm/Makefile +++ b/ports/qemu-arm/Makefile @@ -1,3 +1,5 @@ +TESTS_PROFILE = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/tests_profile.txt + include ../../py/mkenv.mk -include mpconfigport.mk @@ -6,6 +8,7 @@ QSTR_DEFS = qstrdefsport.h # MicroPython feature configurations MICROPY_ROM_TEXT_COMPRESSION ?= 1 +FROZEN_MANIFEST ?= "freeze('test-frzmpy')" # include py core make definitions include $(TOP)/py/py.mk @@ -46,6 +49,8 @@ QEMU_EXTRA = -m 128M SRC_BOARD_O = shared/runtime/gchelper_generic.o # It's really armv7a but closest supported value is armv6. MPY_CROSS_FLAGS += -march=armv6 +# These don't work on Cortex-A9. +TESTS_EXCLUDE = inlineasm/asmdiv.py inlineasm/asmspecialregs.py endif CROSS_COMPILE ?= arm-none-eabi- @@ -87,6 +92,7 @@ SRC_RUN_C = \ SRC_TEST_C = \ test_main.c \ lib/tinytest/tinytest.c \ + shared/upytesthelper/upytesthelper.c \ LIB_SRC_C += $(SRC_LIB_LIBM_C) LIB_SRC_C += $(SRC_LIB_LIBM_SQRT_SW_C) @@ -123,4 +129,23 @@ $(BUILD)/firmware.elf: $(LDSCRIPT) $(ALL_OBJ_RUN) $(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_RUN) $(LIBS) $(Q)$(SIZE) $@ +$(BUILD)/firmware-test.elf: $(LDSCRIPT) $(ALL_OBJ_TEST) + $(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_TEST) $(LIBS) + $(Q)$(SIZE) $@ + +$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h + +.PHONY: $(BUILD)/genhdr/tests.h +$(BUILD)/genhdr/tests.h: + (cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp) + $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py --profile $(TESTS_PROFILE) $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ + +$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING + +# Note: Using timeout(1) to handle cases where qemu hangs (e.g. this can happen with alignment errors). +test: $(BUILD)/firmware-test.elf + timeout --foreground -k 5s 30s qemu-system-arm -machine $(BOARD) $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out + $(Q)tail -n2 $(BUILD)/console.out + $(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" + include $(TOP)/py/mkrules.mk diff --git a/ports/qemu-arm/Makefile.test b/ports/qemu-arm/Makefile.test deleted file mode 100644 index cb5b0927c8c9a..0000000000000 --- a/ports/qemu-arm/Makefile.test +++ /dev/null @@ -1,33 +0,0 @@ -LIB_SRC_C = shared/upytesthelper/upytesthelper.c - -FROZEN_MANIFEST ?= "freeze('test-frzmpy')" - -include Makefile - -ifeq ($(BOARD),sabrelite) -# These don't work on Cortex-A9. -TESTS_EXCLUDE = inlineasm/asmdiv.py inlineasm/asmspecialregs.py -endif - -CFLAGS += -DTEST - -.PHONY: $(BUILD)/genhdr/tests.h - -TESTS_PROFILE = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/tests_profile.txt - -$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h -$(BUILD)/genhdr/tests.h: - (cd $(TOP)/tests; ./run-tests.py --target=qemu-arm --write-exp) - $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py --profile $(TESTS_PROFILE) $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ - -$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING - -$(BUILD)/firmware-test.elf: $(LDSCRIPT) $(ALL_OBJ_TEST) - $(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_TEST) $(LIBS) - $(Q)$(SIZE) $@ - -# Note: Using timeout(1) to handle cases where qemu hangs (e.g. this can happen with alignment errors). -test: $(BUILD)/firmware-test.elf - timeout --foreground -k 5s 30s qemu-system-arm -machine $(BOARD) $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out - $(Q)tail -n2 $(BUILD)/console.out - $(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" diff --git a/ports/qemu-arm/README.md b/ports/qemu-arm/README.md index f821c4d1e28fb..a006756b205ff 100644 --- a/ports/qemu-arm/README.md +++ b/ports/qemu-arm/README.md @@ -25,4 +25,4 @@ passed to the linker. To build and run image with builtin testsuite: - make -f Makefile.test test + make test diff --git a/ports/qemu-arm/main.c b/ports/qemu-arm/main.c index 025c1f17da04a..551f61fa078d0 100644 --- a/ports/qemu-arm/main.c +++ b/ports/qemu-arm/main.c @@ -32,6 +32,7 @@ #include "py/stackctrl.h" #include "py/gc.h" #include "py/mperrno.h" +#include "py/mphal.h" void do_str(const char *src, mp_parse_input_kind_t input_kind) { nlr_buf_t nlr; @@ -70,3 +71,7 @@ void nlr_jump_fail(void *val) { printf("uncaught NLR\n"); exit(1); } + +void qemu_print_strn(const char *str, size_t len) { + mp_hal_stdout_tx_strn_cooked(str, len); +} diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index fce379e47ecf4..c5f78d3e23f54 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -78,8 +78,7 @@ typedef long mp_off_t; // We need an implementation of the log2 function which is not a macro. #define MP_NEED_LOG2 (1) -#ifdef TEST -#include "shared/upytesthelper/upytesthelper.h" -#undef MP_PLAT_PRINT_STRN -#define MP_PLAT_PRINT_STRN(str, len) upytest_output(str, len) -#endif +// All printing is passed through a custom function to check test output. +#define MP_PLAT_PRINT_STRN(str, len) qemu_print_strn(str, len) + +void qemu_print_strn(const char *str, size_t len); diff --git a/ports/qemu-arm/test_main.c b/ports/qemu-arm/test_main.c index 96984f7cd16ed..4aef8c5630942 100644 --- a/ports/qemu-arm/test_main.c +++ b/ports/qemu-arm/test_main.c @@ -33,6 +33,7 @@ #include "py/gc.h" #include "py/mperrno.h" #include "shared/runtime/gchelper.h" +#include "shared/upytesthelper/upytesthelper.h" #include "lib/tinytest/tinytest.h" #include "lib/tinytest/tinytest_macros.h" @@ -64,3 +65,7 @@ void nlr_jump_fail(void *val) { printf("uncaught NLR\n"); exit(1); } + +void qemu_print_strn(const char *str, size_t len) { + upytest_output(str, len); +} diff --git a/ports/qemu-riscv/Makefile b/ports/qemu-riscv/Makefile index 6f15ce52e73c7..aa49120c768c5 100644 --- a/ports/qemu-riscv/Makefile +++ b/ports/qemu-riscv/Makefile @@ -1,3 +1,5 @@ +TESTS_PROFILE = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/tests_profile.txt + include ../../py/mkenv.mk -include mpconfigport.mk @@ -86,6 +88,7 @@ SRC_RUN_C = \ SRC_TEST_C = \ test_main.c \ lib/tinytest/tinytest.c \ + shared/upytesthelper/upytesthelper.c \ LIB_SRC_C += $(SRC_LIB_LIBM_C) LIB_SRC_C += $(SRC_LIB_LIBM_SQRT_SW_C) @@ -125,4 +128,27 @@ $(BUILD)/firmware.elf: $(LDSCRIPT) $(ALL_OBJ_RUN) $(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_RUN) $(LIBS) $(Q)$(SIZE) $@ +$(BUILD)/firmware-test.elf: $(LDSCRIPT) $(ALL_OBJ_TEST) + $(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_TEST) $(LIBS) + $(Q)$(SIZE) $@ + +$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h + +.PHONY: $(BUILD)/genhdr/tests.h +$(BUILD)/genhdr/tests.h: + (cd $(TOP)/tests; ./run-tests.py --target=qemu-riscv --write-exp) + $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py --profile $(TESTS_PROFILE) $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ + +$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING + +# Note: Using timeout(1) to handle cases where qemu hangs (e.g. this can happen with alignment errors). +test: $(BUILD)/firmware-test.elf + timeout --foreground -k 5s 60s qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out + $(Q)tail -n2 $(BUILD)/console.out + $(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" + +# `make debugtest` will block QEMU until a debugger is connected to port 1234. +debugtest: $(BUILD)/firmware-test.elf + qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -serial mon:stdio -S -s -kernel $< + include $(TOP)/py/mkrules.mk diff --git a/ports/qemu-riscv/Makefile.test b/ports/qemu-riscv/Makefile.test deleted file mode 100644 index df64a8d7cc920..0000000000000 --- a/ports/qemu-riscv/Makefile.test +++ /dev/null @@ -1,31 +0,0 @@ -LIB_SRC_C = shared/upytesthelper/upytesthelper.c - -include Makefile - -CFLAGS += -DTEST - -.PHONY: $(BUILD)/genhdr/tests.h - -TESTS_PROFILE = $(dir $(abspath $(firstword $(MAKEFILE_LIST))))/tests_profile.txt - -$(BUILD)/test_main.o: $(BUILD)/genhdr/tests.h -$(BUILD)/genhdr/tests.h: - (cd $(TOP)/tests; ./run-tests.py --target=qemu-riscv --write-exp) - $(Q)echo "Generating $@";(cd $(TOP)/tests; ../tools/tinytest-codegen.py --profile $(TESTS_PROFILE) $(addprefix --exclude ,$(TESTS_EXCLUDE))) > $@ - -$(BUILD)/lib/tinytest/tinytest.o: CFLAGS += -DNO_FORKING - -$(BUILD)/firmware-test.elf: $(LDSCRIPT) $(ALL_OBJ_TEST) - $(Q)$(LD) $(LDFLAGS) -o $@ $(ALL_OBJ_TEST) $(LIBS) - $(Q)$(SIZE) $@ - -# Note: Using timeout(1) to handle cases where qemu hangs (e.g. this can happen with alignment errors). -test: $(BUILD)/firmware-test.elf - timeout --foreground -k 5s 60s qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< > $(BUILD)/console.out - $(Q)tail -n2 $(BUILD)/console.out - $(Q)tail -n1 $(BUILD)/console.out | grep -q "status: 0" - -# `make debugtest` will block QEMU until a debugger is connected to port 1234. - -debugtest: $(BUILD)/firmware-test.elf - qemu-system-riscv32 -machine $(BOARD) -bios none $(QEMU_EXTRA) -nographic -monitor null -semihosting -serial mon:stdio -S -s -kernel $< diff --git a/ports/qemu-riscv/README.md b/ports/qemu-riscv/README.md index 50b1a65374d2b..0be5f042bab1b 100644 --- a/ports/qemu-riscv/README.md +++ b/ports/qemu-riscv/README.md @@ -26,4 +26,4 @@ Linux distribution's package manager, or independently packaged ones like To build and run the image with builtin testsuite: - make -f Makefile.test test + make test diff --git a/ports/qemu-riscv/mpconfigport.h b/ports/qemu-riscv/mpconfigport.h index 38bc70e986adb..1ae5e56b77935 100644 --- a/ports/qemu-riscv/mpconfigport.h +++ b/ports/qemu-riscv/mpconfigport.h @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include #include // options to control how MicroPython is built @@ -70,8 +71,7 @@ typedef long mp_off_t; // We need to provide a declaration/definition of alloca() #include -#ifdef TEST -#include "shared/upytesthelper/upytesthelper.h" -#undef MP_PLAT_PRINT_STRN -#define MP_PLAT_PRINT_STRN(str, len) upytest_output(str, len) -#endif +// All printing is passed through a custom function to check test output. +#define MP_PLAT_PRINT_STRN(str, len) qemu_print_strn(str, len) + +void qemu_print_strn(const char *str, size_t len); diff --git a/ports/qemu-riscv/test_main.c b/ports/qemu-riscv/test_main.c index ca796766aca5a..e935e47be233c 100644 --- a/ports/qemu-riscv/test_main.c +++ b/ports/qemu-riscv/test_main.c @@ -33,6 +33,7 @@ #include "py/gc.h" #include "py/mperrno.h" #include "shared/runtime/gchelper.h" +#include "shared/upytesthelper/upytesthelper.h" #include "lib/tinytest/tinytest.h" #include "lib/tinytest/tinytest_macros.h" @@ -64,3 +65,7 @@ void nlr_jump_fail(void *val) { printf("uncaught NLR\n"); exit(1); } + +void qemu_print_strn(const char *str, size_t len) { + upytest_output(str, len); +} diff --git a/tools/ci.sh b/tools/ci.sh index b0a1022c3b195..52706af90369f 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -258,10 +258,9 @@ function ci_qemu_arm_build { make ${MAKEOPTS} -C ports/qemu-arm submodules make ${MAKEOPTS} -C ports/qemu-arm CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 make ${MAKEOPTS} -C ports/qemu-arm clean - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test submodules - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test clean - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test BOARD=sabrelite test + make ${MAKEOPTS} -C ports/qemu-arm test + make ${MAKEOPTS} -C ports/qemu-arm clean + make ${MAKEOPTS} -C ports/qemu-arm BOARD=sabrelite test } ######################################################################################## @@ -279,8 +278,7 @@ function ci_qemu_riscv_build { make ${MAKEOPTS} -C ports/qemu-riscv submodules make ${MAKEOPTS} -C ports/qemu-riscv make ${MAKEOPTS} -C ports/qemu-riscv clean - make ${MAKEOPTS} -C ports/qemu-riscv -f Makefile.test submodules - make ${MAKEOPTS} -C ports/qemu-riscv -f Makefile.test test + make ${MAKEOPTS} -C ports/qemu-riscv test } ########################################################################################