diff options
-rw-r--r-- | .github/workflows/ports_qemu-arm.yml | 2 | ||||
-rw-r--r-- | ports/qemu-arm/Makefile | 41 | ||||
-rw-r--r-- | ports/qemu-arm/Makefile.test | 33 | ||||
-rw-r--r-- | ports/qemu-arm/README.md | 59 | ||||
-rw-r--r-- | ports/qemu-arm/main.c | 53 | ||||
-rw-r--r-- | ports/qemu-arm/modmachine.c | 16 | ||||
-rw-r--r-- | ports/qemu-arm/mpconfigport.h | 13 | ||||
-rw-r--r-- | ports/qemu-arm/mphalport.c | 66 | ||||
-rw-r--r-- | ports/qemu-arm/mphalport.h | 5 | ||||
-rw-r--r-- | ports/qemu-arm/startup.c | 29 | ||||
-rw-r--r-- | ports/qemu-arm/tests_profile.txt | 16 | ||||
-rw-r--r-- | ports/qemu-riscv/Makefile | 2 | ||||
-rw-r--r-- | ports/qemu-riscv/main.c (renamed from ports/qemu-arm/test_main.c) | 38 | ||||
-rwxr-xr-x | tests/run-tests.py | 12 | ||||
-rwxr-xr-x | tools/ci.sh | 6 |
15 files changed, 237 insertions, 154 deletions
diff --git a/.github/workflows/ports_qemu-arm.yml b/.github/workflows/ports_qemu-arm.yml index db3cd7871d..99750b7535 100644 --- a/.github/workflows/ports_qemu-arm.yml +++ b/.github/workflows/ports_qemu-arm.yml @@ -29,4 +29,4 @@ jobs: run: source tools/ci.sh && ci_qemu_arm_build - name: Print failures if: failure() - run: grep --before-context=100 --text "FAIL" ports/qemu-arm/build/console.out + run: tests/run-tests.py --print-failures diff --git a/ports/qemu-arm/Makefile b/ports/qemu-arm/Makefile index 5ff63bf7da..cdfc39580b 100644 --- a/ports/qemu-arm/Makefile +++ b/ports/qemu-arm/Makefile @@ -11,14 +11,19 @@ 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 include $(TOP)/extmod/extmod.mk +CFLAGS += -DMICROPY_HW_BOARD_NAME='"$(BOARD)"' +QEMU_ARGS += -machine $(BOARD) -nographic -monitor null -semihosting + ifeq ($(BOARD),netduino2) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_STM32 +CFLAGS += -DMICROPY_HW_MCU_NAME='"STM32"' LDSCRIPT = stm32.ld SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o MPY_CROSS_FLAGS += -march=armv7m @@ -27,8 +32,9 @@ endif ifeq ($(BOARD),microbit) CFLAGS += -mthumb -mcpu=cortex-m0 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_NRF51 +CFLAGS += -DMICROPY_HW_MCU_NAME='"nRF51"' LDSCRIPT = nrf51.ld -QEMU_EXTRA = -global nrf51-soc.flash-size=1048576 -global nrf51-soc.sram-size=262144 +QEMU_ARGS += -global nrf51-soc.flash-size=1048576 -global nrf51-soc.sram-size=262144 SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb1.o MPY_CROSS_FLAGS += -march=armv7m endif @@ -36,6 +42,7 @@ endif ifeq ($(BOARD),mps2-an385) CFLAGS += -mthumb -mcpu=cortex-m3 -mfloat-abi=soft CFLAGS += -DQEMU_SOC_MPS2 +CFLAGS += -DMICROPY_HW_MCU_NAME='"Cortex-M3"' LDSCRIPT = mps2.ld SRC_BOARD_O = shared/runtime/gchelper_native.o shared/runtime/gchelper_thumb2.o MPY_CROSS_FLAGS += -march=armv7m @@ -44,11 +51,16 @@ endif ifeq ($(BOARD),sabrelite) CFLAGS += -mcpu=cortex-a9 CFLAGS += -DQEMU_SOC_IMX6 +CFLAGS += -DMICROPY_HW_MCU_NAME='"Cortex-A9"' LDSCRIPT = imx6.ld -QEMU_EXTRA = -m 128M +QEMU_ARGS += -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 +# Cortex-A9 should support unaligned-access, but qemu doesn't seem to. +CFLAGS += -mno-unaligned-access +# These don't work on Cortex-A9. +TESTS_EXCLUDE = --exclude '(asmdiv|asmspecialregs).py' endif CROSS_COMPILE ?= arm-none-eabi- @@ -81,16 +93,18 @@ LIBS = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) SRC_COMMON_C = \ startup.c \ uart.c \ + mphalport.c \ shared/libc/string0.c \ + shared/readline/readline.c \ + shared/runtime/interrupt_char.c \ + shared/runtime/pyexec.c \ + shared/runtime/semihosting_arm.c \ + shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c \ SRC_RUN_C = \ main.c \ -SRC_TEST_C = \ - test_main.c \ - lib/tinytest/tinytest.c \ - LIB_SRC_C += $(SRC_LIB_LIBM_C) LIB_SRC_C += $(SRC_LIB_LIBM_SQRT_SW_C) @@ -116,10 +130,21 @@ OBJ = $(OBJ_COMMON) $(OBJ_RUN) $(OBJ_TEST) # List of sources for qstr extraction SRC_QSTR += $(SRC_COMMON_C) $(SRC_RUN_C) $(LIB_SRC_C) -all: run +all: $(BUILD)/firmware.elf +.PHONY: repl +repl: $(BUILD)/firmware.elf + $(ECHO) "Use machine.reset() to exit" + qemu-system-arm $(QEMU_ARGS) -serial mon:stdio -kernel $< + +.PHONY: run run: $(BUILD)/firmware.elf - qemu-system-arm -machine $(BOARD) $(QEMU_EXTRA) -nographic -monitor null -semihosting -kernel $< + qemu-system-arm $(QEMU_ARGS) -serial pty -kernel $< + +.PHONY: test +test: $(BUILD)/firmware.elf + $(eval DIRNAME=ports/$(notdir $(CURDIR))) + cd $(TOP)/tests && ./run-tests.py --target qemu-arm --device execpty:"qemu-system-arm $(QEMU_ARGS) -serial pty -kernel ../$(DIRNAME)/$<" $(TESTS_EXCLUDE) ## `$(LD)` doesn't seem to like `--specs` for some reason, but we can just use `$(CC)` here. $(BUILD)/firmware.elf: $(LDSCRIPT) $(ALL_OBJ_RUN) diff --git a/ports/qemu-arm/Makefile.test b/ports/qemu-arm/Makefile.test deleted file mode 100644 index cb5b0927c8..0000000000 --- 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 f821c4d1e2..34d73fd165 100644 --- a/ports/qemu-arm/README.md +++ b/ports/qemu-arm/README.md @@ -1,3 +1,6 @@ +MicroPython port to qemu-arm +============================ + This is experimental, community-supported port for Cortex-M emulation as provided by QEMU (http://qemu.org). @@ -15,14 +18,52 @@ The purposes of this port are to enable: - no need to use OpenOCD or anything else that might slow down the process in terms of plugging things together, pressing buttons, etc. -This port will only work with the [GNU ARM Embedded Toolchain]( -https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads - and not with CodeSourcery toolchain. You will need to modify -`LDFLAGS` if you want to use CodeSourcery's version of `arm-none-eabi`. -The difference is that CodeSourcery needs `-T generic-m-hosted.ld` while -ARM's version requires `--specs=nano.specs --specs=rdimon.specs` to be -passed to the linker. +Build instructions +------------------ + +First make sure the MicroPython cross-compiler is built (run from this directory): + + $ make -C ../../mpy-cross + +Then build using: + + $ make + +The default qemu-supported board is `mps2-an385`, a Cortex-M3 board. To select a +different board pass the `BOARD` argument to `make`, for example: + + $ make BOARD=sabrelite + +Running +------- + +When the firmware is run it will provide a REPL on the emulated hardware UART. +To access the REPL directly use: + + $ make repl + +This will start `qemu-system-arm` with the UART redirected to stdio. It's also +possible to redirect the UART to a pty device using: + + $ make run + +This will start the emulation and the name of the pty device will be printed to +stdout. This serial device then be accessed via a serial terminal program, +for example `mpremote`: + + $ mpremote connect /dev/pts/1 + +You can disconnect and reconnect to the serial device multiple times. Once you +are finished, stop the `make run` command by pressing Ctrl-C where that command +was started (or execute `machine.reset()` at the REPL). + +The test suite can be run against the firmware by using the UART redirection. +You can either do this automatically using the single command: + + $ make test -To build and run image with builtin testsuite: +Or manually by first starting the emulation with `make run` and then running the +tests against the serial device, for example: - make -f Makefile.test test + $ cd ../../tests + $ ./run-tests.py --target qemu-arm --device /dev/pts/1 diff --git a/ports/qemu-arm/main.c b/ports/qemu-arm/main.c index 025c1f17da..0421065804 100644 --- a/ports/qemu-arm/main.c +++ b/ports/qemu-arm/main.c @@ -25,41 +25,50 @@ */ #include <stdlib.h> -#include <stdio.h> #include "py/compile.h" #include "py/runtime.h" #include "py/stackctrl.h" #include "py/gc.h" #include "py/mperrno.h" +#include "shared/runtime/gchelper.h" +#include "shared/runtime/pyexec.h" -void do_str(const char *src, mp_parse_input_kind_t input_kind) { - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); - qstr source_name = lex->source_name; - mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); - mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true); - mp_call_function_0(module_fun); - nlr_pop(); - } else { - // uncaught exception - mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); - } -} +#define HEAP_SIZE (100 * 1024) + +static uint32_t gc_heap[HEAP_SIZE / sizeof(uint32_t)]; int main(int argc, char **argv) { mp_stack_ctrl_init(); mp_stack_set_limit(10240); - uint32_t heap[16 * 1024 / 4]; - gc_init(heap, (char *)heap + 16 * 1024); - mp_init(); - do_str("print('hello world!')", MP_PARSE_SINGLE_INPUT); - mp_deinit(); - return 0; + gc_init(gc_heap, (char *)gc_heap + HEAP_SIZE); + + for (;;) { + mp_init(); + + for (;;) { + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if (pyexec_raw_repl() != 0) { + break; + } + } else { + if (pyexec_friendly_repl() != 0) { + break; + } + } + } + + mp_printf(&mp_plat_print, "MPY: soft reboot\n"); + + gc_sweep_all(); + mp_deinit(); + } } void gc_collect(void) { + gc_collect_start(); + gc_helper_collect_regs_and_stack(); + gc_collect_end(); } mp_lexer_t *mp_lexer_new_from_file(qstr filename) { @@ -67,6 +76,6 @@ mp_lexer_t *mp_lexer_new_from_file(qstr filename) { } void nlr_jump_fail(void *val) { - printf("uncaught NLR\n"); + mp_printf(&mp_plat_print, "uncaught NLR\n"); exit(1); } diff --git a/ports/qemu-arm/modmachine.c b/ports/qemu-arm/modmachine.c index a897c5670e..75872a22c1 100644 --- a/ports/qemu-arm/modmachine.c +++ b/ports/qemu-arm/modmachine.c @@ -27,6 +27,22 @@ // This file is never compiled standalone, it's included directly from // extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE. +#include <stdlib.h> + static void mp_machine_idle(void) { // Do nothing. } + +#if MICROPY_PY_MACHINE_RESET + +static void mp_machine_reset(void) { + // Exit qemu (via semihosting call). + exit(0); +} + +static mp_int_t mp_machine_reset_cause(void) { + // Not implemented. + return 0; +} + +#endif diff --git a/ports/qemu-arm/mpconfigport.h b/ports/qemu-arm/mpconfigport.h index fce379e47e..4059a5926d 100644 --- a/ports/qemu-arm/mpconfigport.h +++ b/ports/qemu-arm/mpconfigport.h @@ -42,22 +42,19 @@ #define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) #define MICROPY_MEM_STATS (1) #define MICROPY_ENABLE_GC (1) -#define MICROPY_KBD_EXCEPTION (0) -#define MICROPY_HELPER_REPL (0) +#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) #define MICROPY_WARNINGS (1) -#define MICROPY_PY_BUILTINS_INPUT (0) -#define MICROPY_PY_BUILTINS_HELP (0) #define MICROPY_PY_IO_IOBASE (0) #define MICROPY_PY_SYS_PLATFORM "qemu-arm" -#define MICROPY_PY_SYS_STDFILES (0) #define MICROPY_PY_SYS_STDIO_BUFFER (0) #define MICROPY_PY_SELECT (0) #define MICROPY_PY_TIME (0) #define MICROPY_PY_ASYNCIO (0) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_INCLUDEFILE "ports/qemu-arm/modmachine.c" +#define MICROPY_PY_MACHINE_RESET (1) #define MICROPY_PY_MACHINE_PIN_BASE (1) #define MICROPY_VFS (1) @@ -78,8 +75,4 @@ 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 +#define MP_STATE_PORT MP_STATE_VM diff --git a/ports/qemu-arm/mphalport.c b/ports/qemu-arm/mphalport.c new file mode 100644 index 0000000000..dbb87b48b8 --- /dev/null +++ b/ports/qemu-arm/mphalport.c @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mphal.h" +#include "shared/runtime/semihosting_arm.h" +#include "uart.h" + +// UART is better behaved with redirection under qemu-system-arm, so prefer that for stdio. +#define USE_UART (1) +#define USE_SEMIHOSTING (0) + +uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { + // Not implemented. + return 0; +} + +int mp_hal_stdin_rx_chr(void) { + for (;;) { + #if USE_UART + int c = uart_rx_chr(); + if (c >= 0) { + return c; + } + #endif + #if USE_SEMIHOSTING + char str[1]; + int ret = mp_semihosting_rx_chars(str, 1); + if (ret == 0) { + return str[0]; + } + #endif + } +} + +mp_uint_t mp_hal_stdout_tx_strn(const char *str, size_t len) { + #if USE_UART + uart_tx_strn(str, len); + #endif + #if USE_SEMIHOSTING + mp_semihosting_tx_strn(str, len); + #endif + return len; +} diff --git a/ports/qemu-arm/mphalport.h b/ports/qemu-arm/mphalport.h index 8a40505ba6..348b45701b 100644 --- a/ports/qemu-arm/mphalport.h +++ b/ports/qemu-arm/mphalport.h @@ -24,7 +24,4 @@ * THE SOFTWARE. */ -#include "uart.h" - -#define mp_hal_stdin_rx_chr() (0) -#define mp_hal_stdout_tx_strn_cooked(s, l) uart_tx_strn((s), (l)) +#include "shared/runtime/interrupt_char.h" diff --git a/ports/qemu-arm/startup.c b/ports/qemu-arm/startup.c index a1e89d111c..118a5b8006 100644 --- a/ports/qemu-arm/startup.c +++ b/ports/qemu-arm/startup.c @@ -28,6 +28,7 @@ #include <stdio.h> #include <stdlib.h> +#include "shared/runtime/semihosting_arm.h" #include "uart.h" extern uint32_t _estack, _sidata, _sdata, _edata, _sbss, _ebss; @@ -97,6 +98,8 @@ const uint32_t isr_vector[] __attribute__((section(".isr_vector"))) = { #endif void _start(void) { + mp_semihosting_init(); + // Enable the UART uart_init(); @@ -108,21 +111,9 @@ void _start(void) { exit(0); } -__attribute__((naked)) void exit(int status) { +void exit(int status) { // Force qemu to exit using ARM Semihosting - __asm volatile ( - "mov r1, r0\n" - "cmp r1, #0\n" - "bne .notclean\n" - "ldr r1, =0x20026\n" // ADP_Stopped_ApplicationExit, a clean exit - ".notclean:\n" - "movs r0, #0x18\n" // SYS_EXIT - #if defined(__ARM_ARCH_ISA_ARM) - "svc 0x00123456\n" - #elif defined(__ARM_ARCH_ISA_THUMB) - "bkpt 0xab\n" - #endif - ); + mp_semihosting_exit(status); for (;;) { } } @@ -134,13 +125,3 @@ void __assert_func(const char *file, int line, const char *func, const char *exp exit(1); } #endif - -// The following are needed for tinytest - -#include <stdio.h> - -int setvbuf(FILE *stream, char *buf, int mode, size_t size) { - return 0; -} - -struct _reent *_impure_ptr; diff --git a/ports/qemu-arm/tests_profile.txt b/ports/qemu-arm/tests_profile.txt deleted file mode 100644 index 101943b7c6..0000000000 --- a/ports/qemu-arm/tests_profile.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Port-specific test directories. - -test_dirs.update(("inlineasm", "ports/qemu-arm")) - -# Port-specific tests exclusion list. - -exclude_tests.update( - ( - # inline asm FP tests (require Cortex-M4) - "inlineasm/asmfpaddsub.py", - "inlineasm/asmfpcmp.py", - "inlineasm/asmfpldrstr.py", - "inlineasm/asmfpmuldiv.py", - "inlineasm/asmfpsqrt.py", - ) -) diff --git a/ports/qemu-riscv/Makefile b/ports/qemu-riscv/Makefile index 6f15ce52e7..473aec882d 100644 --- a/ports/qemu-riscv/Makefile +++ b/ports/qemu-riscv/Makefile @@ -81,7 +81,7 @@ SRC_COMMON_C = \ shared/runtime/sys_stdio_mphal.c \ SRC_RUN_C = \ - ports/qemu-arm/main.c \ + main.c \ SRC_TEST_C = \ test_main.c \ diff --git a/ports/qemu-arm/test_main.c b/ports/qemu-riscv/main.c index 96984f7cd1..025c1f17da 100644 --- a/ports/qemu-arm/test_main.c +++ b/ports/qemu-riscv/main.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2014 Ilya Dmitrichenko + * Copyright (c) 2014-2023 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,28 +32,34 @@ #include "py/stackctrl.h" #include "py/gc.h" #include "py/mperrno.h" -#include "shared/runtime/gchelper.h" -#include "lib/tinytest/tinytest.h" -#include "lib/tinytest/tinytest_macros.h" -#define HEAP_SIZE (100 * 1024) - -#include "genhdr/tests.h" +void do_str(const char *src, mp_parse_input_kind_t input_kind) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); + qstr source_name = lex->source_name; + mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); + mp_obj_t module_fun = mp_compile(&parse_tree, source_name, true); + mp_call_function_0(module_fun); + nlr_pop(); + } else { + // uncaught exception + mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); + } +} -int main() { +int main(int argc, char **argv) { mp_stack_ctrl_init(); mp_stack_set_limit(10240); - static uint32_t heap[HEAP_SIZE / sizeof(uint32_t)]; - upytest_set_heap(heap, (char *)heap + HEAP_SIZE); - int r = tinytest_main(0, NULL, groups); - printf("status: %d\n", r); - return r; + uint32_t heap[16 * 1024 / 4]; + gc_init(heap, (char *)heap + 16 * 1024); + mp_init(); + do_str("print('hello world!')", MP_PARSE_SINGLE_INPUT); + mp_deinit(); + return 0; } void gc_collect(void) { - gc_collect_start(); - gc_helper_collect_regs_and_stack(); - gc_collect_end(); } mp_lexer_t *mp_lexer_new_from_file(qstr filename) { diff --git a/tests/run-tests.py b/tests/run-tests.py index d0c93f74b9..60bfc2599f 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -676,7 +676,11 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): "extmod/time_time_ns.py" ) # RA fsp rtc function doesn't support nano sec info elif args.target == "qemu-arm": - skip_tests.add("misc/print_exception.py") # requires sys stdfiles + skip_tests.add("inlineasm/asmfpaddsub.py") # requires Cortex-M4 + skip_tests.add("inlineasm/asmfpcmp.py") + skip_tests.add("inlineasm/asmfpldrstr.py") + skip_tests.add("inlineasm/asmfpmuldiv.py") + skip_tests.add("inlineasm/asmfpsqrt.py") elif args.target == "qemu-riscv": skip_tests.add("misc/print_exception.py") # requires sys stdfiles elif args.target == "webassembly": @@ -1043,7 +1047,6 @@ the last matching regex is used: LOCAL_TARGETS = ( "unix", - "qemu-arm", "qemu-riscv", "webassembly", ) @@ -1054,6 +1057,7 @@ the last matching regex is used: "esp32", "minimal", "nrf", + "qemu-arm", "renesas-ra", "rp2", ) @@ -1141,10 +1145,6 @@ the last matching regex is used: "ports/unix", ) elif args.target == "qemu-arm": - if not args.write_exp: - raise ValueError("--target=qemu-arm must be used with --write-exp") - # Generate expected output files for qemu run. - # This list should match the test_dirs tuple in tinytest-codegen.py. test_dirs += ( "float", "inlineasm", diff --git a/tools/ci.sh b/tools/ci.sh index 7353a3ecdf..175d7f5762 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -258,10 +258,8 @@ 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 BOARD=sabrelite test } ######################################################################################## |