diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ff9227a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "user/mpy/micropython"] + path = user/mpy/micropython + url = git@github.com:micropython/micropython.git + ignore = untracked diff --git a/Makefile b/Makefile index 0d11530..acecc17 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ NAME = piko # select QEMU when the target is unspecified -TARGET ?= stm32f429 +TARGET ?= stm32p103 CMSIS = external/cmsis # The platform Makefile contains hw details and flags @@ -32,20 +32,27 @@ CSRC += \ libc/piko/mman.c \ $(LIBPIKO_CSRC) +.PHONY: all check clean distclean + +all: $(CMSIS)/$(TARGET) $(USER) + $(MAKE) $(NAME).lds + $(MAKE) $(NAME).bin + +# micropython +include user/mpy/build.mk + OBJS += $(SSRC:.S=.o) $(CSRC:.c=.o) OBJS := $(sort $(OBJS)) deps := $(OBJS:%.o=.%.o.d) -.PHONY: all check clean distclean - -all: $(CMSIS)/$(TARGET) $(NAME).lds $(NAME).bin # generic build rules include mk/flags.mk include mk/rules.mk include mk/cmsis.mk + prebuild: $(CMSIS)/$(TARGET) check: @@ -57,6 +64,9 @@ clean: ifneq "$(wildcard $(CMSIS) )" "" find $(CMSIS) -name "*.o" -type f -delete endif + rm -rf user/mpy/micropython/build + rm -f user/mpy/micropython/*.o.d + rm -f user/mpy/micropython/py/*.o rm -f $(NAME).map $(NAME).lds rm -f $(NAME).elf $(NAME).bin diff --git a/user/mpy/_frozen_mpy.c b/user/mpy/_frozen_mpy.c new file mode 100644 index 0000000..45594a3 --- /dev/null +++ b/user/mpy/_frozen_mpy.c @@ -0,0 +1,112 @@ +#include "py/mpconfig.h" +#include "py/objint.h" +#include "py/objstr.h" +#include "py/emitglue.h" + +#if MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE +#error "MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE not supported with frozen mpy files" +#endif + +#if MICROPY_LONGINT_IMPL != 0 +#error "incompatible MICROPY_LONGINT_IMPL" +#endif + +#if MICROPY_PY_BUILTINS_FLOAT +typedef struct _mp_obj_float_t { + mp_obj_base_t base; + mp_float_t value; +} mp_obj_float_t; +#endif + +enum { + MP_QSTR_frozentest_dot_py = MP_QSTRnumber_of, + MP_QSTR_uPy, + MP_QSTR_i, +}; + +extern const qstr_pool_t mp_qstr_const_pool; +const qstr_pool_t mp_qstr_frozen_const_pool = { + (qstr_pool_t*)&mp_qstr_const_pool, // previous pool + MP_QSTRnumber_of, // previous pool size + 3, // allocated entries + 3, // used entries + { + (const byte*)"\xfe\x0d" "frozentest.py", + (const byte*)"\xf9\x03" "uPy", + (const byte*)"\xcc\x01" "i", + }, +}; + +// frozen bytecode for file frozentest.py, scope frozentest_ +STATIC const byte bytecode_data_frozentest__lt_module_gt_[92] = { + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + MP_QSTR__lt_module_gt_ & 0xff, MP_QSTR__lt_module_gt_ >> 8, + MP_QSTR_frozentest_dot_py & 0xff, MP_QSTR_frozentest_dot_py >> 8, + 0x2a, 0x28, 0x28, 0x28, 0x2b, 0x28, 0x00, 0x00, 0xff, + 0x1c, MP_QSTR_print & 0xff, MP_QSTR_print >> 8, + 0x16, MP_QSTR_uPy & 0xff, MP_QSTR_uPy >> 8, + 0x64, 0x01, + 0x32, + 0x1c, MP_QSTR_print & 0xff, MP_QSTR_print >> 8, + 0x17, 0x00, + 0x64, 0x01, + 0x32, + 0x1c, MP_QSTR_print & 0xff, MP_QSTR_print >> 8, + 0x17, 0x01, + 0x64, 0x01, + 0x32, + 0x1c, MP_QSTR_print & 0xff, MP_QSTR_print >> 8, + 0x17, 0x02, + 0x64, 0x01, + 0x32, + 0x1c, MP_QSTR_print & 0xff, MP_QSTR_print >> 8, + 0x14, 0xba, 0xef, 0x9a, 0x15, + 0x64, 0x01, + 0x32, + 0x80, + 0x35, 0x0f, 0x80, + 0x30, + 0x24, MP_QSTR_i & 0xff, MP_QSTR_i >> 8, + 0x1c, MP_QSTR_print & 0xff, MP_QSTR_print >> 8, + 0x1c, MP_QSTR_i & 0xff, MP_QSTR_i >> 8, + 0x64, 0x01, + 0x32, + 0x81, + 0xe9, + 0x30, + 0x84, + 0xf0, + 0x36, 0xeb, 0x7f, + 0x32, + 0x11, + 0x5b, +}; +STATIC const mp_obj_str_t const_obj_frozentest__lt_module_gt__0 = {{&mp_type_str}, 0, 34, (const byte*)"\x61\x20\x6c\x6f\x6e\x67\x20\x73\x74\x72\x69\x6e\x67\x20\x74\x68\x61\x74\x20\x69\x73\x20\x6e\x6f\x74\x20\x69\x6e\x74\x65\x72\x6e\x65\x64"}; +STATIC const mp_obj_str_t const_obj_frozentest__lt_module_gt__1 = {{&mp_type_str}, 0, 38, (const byte*)"\x61\x20\x73\x74\x72\x69\x6e\x67\x20\x74\x68\x61\x74\x20\x68\x61\x73\x20\x75\x6e\x69\x63\x6f\x64\x65\x20\xce\xb1\xce\xb2\xce\xb3\x20\x63\x68\x61\x72\x73"}; +STATIC const mp_obj_str_t const_obj_frozentest__lt_module_gt__2 = {{&mp_type_bytes}, 0, 11, (const byte*)"\x62\x79\x74\x65\x73\x20\x31\x32\x33\x34\x01"}; +STATIC const mp_uint_t const_table_data_frozentest__lt_module_gt_[3] = { + (mp_uint_t)&const_obj_frozentest__lt_module_gt__0, + (mp_uint_t)&const_obj_frozentest__lt_module_gt__1, + (mp_uint_t)&const_obj_frozentest__lt_module_gt__2, +}; +const mp_raw_code_t raw_code_frozentest__lt_module_gt_ = { + .kind = MP_CODE_BYTECODE, + .scope_flags = 0x00, + .n_pos_args = 0, + .data.u_byte = { + .bytecode = bytecode_data_frozentest__lt_module_gt_, + .const_table = const_table_data_frozentest__lt_module_gt_, + #if MICROPY_PERSISTENT_CODE_SAVE + .bc_len = 92, + .n_obj = 3, + .n_raw_code = 0, + #endif + }, +}; + +const char mp_frozen_mpy_names[] = { +"frozentest.py\0" +"\0"}; +const mp_raw_code_t *const mp_frozen_mpy_content[] = { + &raw_code_frozentest__lt_module_gt_, +}; diff --git a/user/mpy/build.mk b/user/mpy/build.mk new file mode 100644 index 0000000..1342c93 --- /dev/null +++ b/user/mpy/build.mk @@ -0,0 +1,70 @@ +TOP = user/mpy/micropython +PY_SRC ?= $(TOP)/py +BUILD = $(TOP)/build +PY_BUILD = $(BUILD)/py + +# where autogenerated header files go +HEADER_BUILD = $(BUILD)/genhdr + +# file containing qstr defs for the core Python bit +PY_QSTR_DEFS = $(PY_SRC)/qstrdefs.h + +$(USER): | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/mpversion.h + +include $(TOP)/../py.mk + +# If qstr autogeneration is not disabled we specify the output header +# for all collected qstrings. +ifneq ($(QSTR_AUTOGEN_DISABLE),1) +QSTR_DEFS_COLLECTED = $(HEADER_BUILD)/qstrdefs.collected.h +endif + +CP = cp +MKDIR = mkdir +SED = sed +PYTHON = python3 + +CFLAGS += \ + -Iuser/mpy \ + -I$(TOP) \ + -I$(BUILD) \ + +CSRC += \ + $(wildcard $(PY_SRC)/*.c) \ + user/mpy/mphalport.c \ + user/mpy/_frozen_mpy.c \ + $(TOP)/lib/utils/pyexec.c \ + $(TOP)/lib/mp-readline/readline.c \ + # $(TOP)/extmod/moductypes.o \ + # $(TOP)/extmod/modujson.o \ + # $(TOP)/extmod/modure.o \ + # $(TOP)/extmod/moduzlib.o \ + # $(TOP)/extmod/moduheapq.o \ + # $(TOP)/extmod/modutimeq.o \ + # $(TOP)/extmod/moduhashlib.o \ + # $(TOP)/extmod/modubinascii.o \ + # $(TOP)/extmod/virtpin.o \ + # $(TOP)/extmod/machine_mem.o \ + # $(TOP)/extmod/machine_pinbase.o \ + # $(TOP)/extmod/machine_signal.o \ + # $(TOP)/extmod/machine_pulse.o \ + # $(TOP)/extmod/machine_i2c.o \ + # $(TOP)/extmod/machine_spi.o \ + # $(TOP)/extmod/modussl_axtls.o \ + # $(TOP)/extmod/modussl_mbedtls.o \ + # $(TOP)/extmod/modurandom.o \ + # $(TOP)/extmod/moduselect.o \ + # $(TOP)/extmod/modwebsocket.o \ + # $(TOP)/extmod/modwebrepl.o \ + # $(TOP)/extmod/modframebuf.o \ + # $(TOP)/extmod/vfs.o \ + # $(TOP)/extmod/vfs_reader.o \ + # $(TOP)/extmod/vfs_fat.o \ + # $(TOP)/extmod/vfs_fat_diskio.o \ + # $(TOP)/extmod/vfs_fat_file.o \ + # $(TOP)/extmod/vfs_fat_misc.o \ + # $(TOP)/extmod/utime_mphal.o \ + # $(TOP)/extmod/uos_dupterm.o \ + # $(TOP)/lib/embed/abort_.o \ + +include $(TOP)/py/mkrules.mk diff --git a/user/mpy/forzentest.mpy b/user/mpy/forzentest.mpy new file mode 100644 index 0000000..f0ed8d2 --- /dev/null +++ b/user/mpy/forzentest.mpy @@ -0,0 +1,16 @@ +4d02 021f 5c03 0000 0000 000d 0a00 f700 +2a28 2828 2b28 0000 ff1b c700 16f8 0064 +0132 1bc7 0017 0064 0132 1bc7 0017 0164 +0132 1bc7 0017 0264 0132 1bc7 0014 baef +9a15 6401 3280 350f 8030 24f9 001b c700 +1bf9 0064 0132 81e9 3084 f036 eb7f 3211 +5b08 3c6d 6f64 756c 653e 0d66 726f 7a65 +6e74 6573 742e 7079 0570 7269 6e74 0375 +5079 0570 7269 6e74 0570 7269 6e74 0570 +7269 6e74 0570 7269 6e74 0169 0570 7269 +6e74 0169 0300 7322 6120 6c6f 6e67 2073 +7472 696e 6720 7468 6174 2069 7320 6e6f +7420 696e 7465 726e 6564 7326 6120 7374 +7269 6e67 2074 6861 7420 6861 7320 756e +6963 6f64 6520 ceb1 ceb2 ceb3 2063 6861 +7273 620b 6279 7465 7320 3132 3334 01 diff --git a/user/mpy/micropython b/user/mpy/micropython new file mode 160000 index 0000000..d5191ed --- /dev/null +++ b/user/mpy/micropython @@ -0,0 +1 @@ +Subproject commit d5191edf7ff81f5f07243cb2a318508c1e9cc5df diff --git a/user/mpy/mkrules.mk b/user/mpy/mkrules.mk new file mode 100644 index 0000000..1a3e5f0 --- /dev/null +++ b/user/mpy/mkrules.mk @@ -0,0 +1,16 @@ +$(HEADER_BUILD)/qstr.i.last: $(SRC_QSTR) | $(HEADER_BUILD)/mpversion.h + $(ECHO) "GEN $@" + $(Q)$(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) $(if $?,$?,$^) >$(HEADER_BUILD)/qstr.i.last; + +$(HEADER_BUILD)/qstr.split: $(HEADER_BUILD)/qstr.i.last + $(ECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py split $(HEADER_BUILD)/qstr.i.last $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) + $(Q)touch $@ + +$(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split + $(ECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py cat $(HEADER_BUILD)/qstr.i.last $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) + +$(BUILD)/_frozen_mpy.c: user/mpy/forzentest.mpy $(BUILD)/genhdr/qstrdefs.generated.h + @echo "MISC freezing bytecode" + user/mpy/tools/mpy-tool.py -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h -mlongint-impl=none $< > $@ diff --git a/user/mpy/mpconfigport.h b/user/mpy/mpconfigport.h new file mode 100644 index 0000000..ce4f8f2 --- /dev/null +++ b/user/mpy/mpconfigport.h @@ -0,0 +1,97 @@ +#include + +// options to control how MicroPython is built + +// You can disable the built-in MicroPython compiler by setting the following +// config option to 0. If you do this then you won't get a REPL prompt, but you +// will still be able to execute pre-compiled scripts, compiled with mpy-cross. +#define MICROPY_ENABLE_COMPILER (1) + +#define MICROPY_QSTR_BYTES_IN_HASH (1) +#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool +#define MICROPY_ALLOC_PATH_MAX (256) +#define MICROPY_ALLOC_PARSE_CHUNK_INIT (16) +#define MICROPY_EMIT_X64 (0) +#define MICROPY_EMIT_THUMB (0) +#define MICROPY_EMIT_INLINE_THUMB (0) +#define MICROPY_COMP_MODULE_CONST (0) +#define MICROPY_COMP_CONST (0) +#define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (0) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (0) +#define MICROPY_MEM_STATS (0) +#define MICROPY_DEBUG_PRINTERS (0) +#define MICROPY_ENABLE_GC (1) +#define MICROPY_GC_ALLOC_THRESHOLD (0) +#define MICROPY_REPL_EVENT_DRIVEN (0) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_HELPER_LEXER_UNIX (0) +#define MICROPY_ENABLE_SOURCE_LINE (0) +#define MICROPY_ENABLE_DOC_STRING (0) +#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) +#define MICROPY_PY_ASYNC_AWAIT (0) +#define MICROPY_PY_BUILTINS_BYTEARRAY (0) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) +#define MICROPY_PY_BUILTINS_ENUMERATE (0) +#define MICROPY_PY_BUILTINS_FILTER (0) +#define MICROPY_PY_BUILTINS_FROZENSET (0) +#define MICROPY_PY_BUILTINS_REVERSED (0) +#define MICROPY_PY_BUILTINS_SET (0) +#define MICROPY_PY_BUILTINS_SLICE (0) +#define MICROPY_PY_BUILTINS_PROPERTY (0) +#define MICROPY_PY_BUILTINS_MIN_MAX (0) +#define MICROPY_PY___FILE__ (0) +#define MICROPY_PY_GC (0) +#define MICROPY_PY_ARRAY (0) +#define MICROPY_PY_ATTRTUPLE (0) +#define MICROPY_PY_COLLECTIONS (0) +#define MICROPY_PY_MATH (0) +#define MICROPY_PY_CMATH (0) +#define MICROPY_PY_IO (0) +#define MICROPY_PY_STRUCT (0) +#define MICROPY_PY_SYS (0) +#define MICROPY_MODULE_FROZEN_MPY (1) +#define MICROPY_CPYTHON_COMPAT (0) +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) + +// type definitions for the specific machine + +#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p) | 1)) + +// This port is intended to be 32-bit, but unfortunately, int32_t for +// different targets may be defined in different ways - either as int +// or as long. This requires different printf formatting specifiers +// to print such value. So, we avoid int32_t and use int directly. +#define UINT_FMT "%u" +#define INT_FMT "%d" +typedef int mp_int_t; // must be pointer size +typedef unsigned mp_uint_t; // must be pointer size + +typedef long mp_off_t; + +#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) + +// extra built in names to add to the global namespace +#define MICROPY_PORT_BUILTINS \ + { MP_OBJ_NEW_QSTR(MP_QSTR_open), (mp_obj_t)&mp_builtin_open_obj }, + +// We need to provide a declaration/definition of alloca() +#include + +#define MICROPY_HW_BOARD_NAME "minimal" +#define MICROPY_HW_MCU_NAME "unknown-cpu" + +#ifdef __linux__ +#define MICROPY_MIN_USE_STDOUT (1) +#endif + +#ifdef __thumb__ +#define MICROPY_MIN_USE_CORTEX_CPU (1) +#define MICROPY_MIN_USE_STM32_MCU (1) +#endif + +#define MP_STATE_PORT MP_STATE_VM + +#define MICROPY_PORT_ROOT_POINTERS \ + const char *readline_hist[8]; diff --git a/user/mpy/mphalport.c b/user/mpy/mphalport.c new file mode 100644 index 0000000..fb3246a --- /dev/null +++ b/user/mpy/mphalport.c @@ -0,0 +1,18 @@ +#include "platform.h" +#include "py/mphal.h" + + +int mp_hal_stdin_rx_chr() { + char c; + int fd = open("/dev/ttyS0", 0); + + read(fd, &c, 1); + close(fd); + return c; +} + +void mp_hal_stdout_tx_strn(const char *s, mp_uint_t n) { + while (n--) { + __printk_putchar(*s++); + } +} diff --git a/user/mpy/mphalport.h b/user/mpy/mphalport.h new file mode 100644 index 0000000..9937063 --- /dev/null +++ b/user/mpy/mphalport.h @@ -0,0 +1,4 @@ +#define mp_hal_stdout_tx_strn_cooked(s, l) printk(s); +#define mp_hal_stdout_tx_str(s) printk(s); +#define mp_hal_set_interrupt_char(n) (0) +#define mp_hal_ticks_ms() (0) diff --git a/user/mpy/py.mk b/user/mpy/py.mk new file mode 100644 index 0000000..9dc322d --- /dev/null +++ b/user/mpy/py.mk @@ -0,0 +1,319 @@ +# where py object files go (they have a name prefix to prevent filename clashes) +PY_BUILD = $(BUILD)/py + +# where autogenerated header files go +HEADER_BUILD = $(BUILD)/genhdr + +# file containing qstr defs for the core Python bit +PY_QSTR_DEFS = $(PY_SRC)/qstrdefs.h + +# If qstr autogeneration is not disabled we specify the output header +# for all collected qstrings. +ifneq ($(QSTR_AUTOGEN_DISABLE),1) +QSTR_DEFS_COLLECTED = $(HEADER_BUILD)/qstrdefs.collected.h +endif + +# some code is performance bottleneck and compiled with other optimization options +CSUPEROPT = -O3 + +# this sets the config file for FatFs +CFLAGS_MOD += -DFFCONF_H=\"lib/oofatfs/ffconf.h\" + +ifeq ($(MICROPY_PY_USSL),1) +CFLAGS_MOD += -DMICROPY_PY_USSL=1 +ifeq ($(MICROPY_SSL_AXTLS),1) +CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/lib/axtls/config +LDFLAGS_MOD += -Lbuild -laxtls +else ifeq ($(MICROPY_SSL_MBEDTLS),1) +# Can be overridden by ports which have "builtin" mbedTLS +MICROPY_SSL_MBEDTLS_INCLUDE ?= $(TOP)/lib/mbedtls/include +CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(MICROPY_SSL_MBEDTLS_INCLUDE) +LDFLAGS_MOD += -L$(TOP)/lib/mbedtls/library -lmbedx509 -lmbedtls -lmbedcrypto +endif +endif + +#ifeq ($(MICROPY_PY_LWIP),1) +#CFLAGS_MOD += -DMICROPY_PY_LWIP=1 -I../lib/lwip/src/include -I../lib/lwip/src/include/ipv4 -I../extmod/lwip-include +#endif + +ifeq ($(MICROPY_PY_LWIP),1) +LWIP_DIR = lib/lwip/src +INC += -I$(TOP)/lib/lwip/src/include -I$(TOP)/lib/lwip/src/include/ipv4 -I$(TOP)/extmod/lwip-include +CFLAGS_MOD += -DMICROPY_PY_LWIP=1 +SRC_MOD += extmod/modlwip.c lib/netutils/netutils.c +SRC_MOD += $(addprefix $(LWIP_DIR)/,\ + core/def.c \ + core/dns.c \ + core/init.c \ + core/mem.c \ + core/memp.c \ + core/netif.c \ + core/pbuf.c \ + core/raw.c \ + core/stats.c \ + core/sys.c \ + core/tcp.c \ + core/tcp_in.c \ + core/tcp_out.c \ + core/timers.c \ + core/udp.c \ + core/ipv4/autoip.c \ + core/ipv4/icmp.c \ + core/ipv4/igmp.c \ + core/ipv4/inet.c \ + core/ipv4/inet_chksum.c \ + core/ipv4/ip_addr.c \ + core/ipv4/ip.c \ + core/ipv4/ip_frag.c \ + ) +ifeq ($(MICROPY_PY_LWIP_SLIP),1) +CFLAGS_MOD += -DMICROPY_PY_LWIP_SLIP=1 +SRC_MOD += $(LWIP_DIR)/netif/slipif.c +endif +endif + +ifeq ($(MICROPY_PY_BTREE),1) +BTREE_DIR = lib/berkeley-db-1.xx +BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error=printf -Dabort=abort_ -Dvirt_fd_t=mp_obj_t "-DVIRT_FD_T_HEADER=" +INC += -I$(TOP)/$(BTREE_DIR)/PORT/include +SRC_MOD += extmod/modbtree.c +SRC_MOD += $(addprefix $(BTREE_DIR)/,\ +btree/bt_close.c \ +btree/bt_conv.c \ +btree/bt_debug.c \ +btree/bt_delete.c \ +btree/bt_get.c \ +btree/bt_open.c \ +btree/bt_overflow.c \ +btree/bt_page.c \ +btree/bt_put.c \ +btree/bt_search.c \ +btree/bt_seq.c \ +btree/bt_split.c \ +btree/bt_utils.c \ +mpool/mpool.c \ + ) +CFLAGS_MOD += -DMICROPY_PY_BTREE=1 +# we need to suppress certain warnings to get berkeley-db to compile cleanly +# and we have separate BTREE_DEFS so the definitions don't interfere with other source code +$(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS) +$(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS) +endif + +# py object files +PY_O_BASENAME = \ + mpstate.o \ + nlrx86.o \ + nlrx64.o \ + nlrthumb.o \ + nlrxtensa.o \ + nlrsetjmp.o \ + malloc.o \ + gc.o \ + qstr.o \ + vstr.o \ + mpprint.o \ + unicode.o \ + mpz.o \ + reader.o \ + lexer.o \ + parse.o \ + scope.o \ + compile.o \ + emitcommon.o \ + emitbc.o \ + asmbase.o \ + asmx64.o \ + emitnx64.o \ + asmx86.o \ + emitnx86.o \ + asmthumb.o \ + emitnthumb.o \ + emitinlinethumb.o \ + asmarm.o \ + emitnarm.o \ + asmxtensa.o \ + emitnxtensa.o \ + emitinlinextensa.o \ + formatfloat.o \ + parsenumbase.o \ + parsenum.o \ + emitglue.o \ + persistentcode.o \ + runtime.o \ + runtime_utils.o \ + scheduler.o \ + nativeglue.o \ + stackctrl.o \ + argcheck.o \ + warning.o \ + map.o \ + obj.o \ + objarray.o \ + objattrtuple.o \ + objbool.o \ + objboundmeth.o \ + objcell.o \ + objclosure.o \ + objcomplex.o \ + objdict.o \ + objenumerate.o \ + objexcept.o \ + objfilter.o \ + objfloat.o \ + objfun.o \ + objgenerator.o \ + objgetitemiter.o \ + objint.o \ + objint_longlong.o \ + objint_mpz.o \ + objlist.o \ + objmap.o \ + objmodule.o \ + objobject.o \ + objpolyiter.o \ + objproperty.o \ + objnone.o \ + objnamedtuple.o \ + objrange.o \ + objreversed.o \ + objset.o \ + objsingleton.o \ + objslice.o \ + objstr.o \ + objstrunicode.o \ + objstringio.o \ + objtuple.o \ + objtype.o \ + objzip.o \ + opmethods.o \ + sequence.o \ + stream.o \ + binary.o \ + builtinimport.o \ + builtinevex.o \ + builtinhelp.o \ + modarray.o \ + modbuiltins.o \ + modcollections.o \ + modgc.o \ + modio.o \ + modmath.o \ + modcmath.o \ + modmicropython.o \ + modstruct.o \ + modsys.o \ + moduerrno.o \ + modthread.o \ + vm.o \ + bc.o \ + showbc.o \ + repl.o \ + smallint.o \ + frozenmod.o \ + ../extmod/moductypes.o \ + ../extmod/modujson.o \ + ../extmod/modure.o \ + ../extmod/moduzlib.o \ + ../extmod/moduheapq.o \ + ../extmod/modutimeq.o \ + ../extmod/moduhashlib.o \ + ../extmod/modubinascii.o \ + ../extmod/virtpin.o \ + ../extmod/machine_mem.o \ + ../extmod/machine_pinbase.o \ + ../extmod/machine_signal.o \ + ../extmod/machine_pulse.o \ + ../extmod/machine_i2c.o \ + ../extmod/machine_spi.o \ + ../extmod/modussl_axtls.o \ + ../extmod/modussl_mbedtls.o \ + ../extmod/modurandom.o \ + ../extmod/moduselect.o \ + ../extmod/modwebsocket.o \ + ../extmod/modwebrepl.o \ + ../extmod/modframebuf.o \ + ../extmod/vfs.o \ + ../extmod/vfs_reader.o \ + ../extmod/vfs_fat.o \ + ../extmod/vfs_fat_diskio.o \ + ../extmod/vfs_fat_file.o \ + ../extmod/vfs_fat_misc.o \ + ../extmod/utime_mphal.o \ + ../extmod/uos_dupterm.o \ + ../lib/embed/abort_.o \ + ../lib/utils/printf.o \ + +# prepend the build destination prefix to the py object files +PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME)) + +# object file for frozen files +ifneq ($(FROZEN_DIR),) +PY_O += $(BUILD)/$(BUILD)/frozen.o +endif + +# object file for frozen bytecode (froPY_QSTR_DEFSzen .mpy files) +ifneq ($(FROZEN_MPY_DIR),) +PY_O += $(BUILD)/$(BUILD)/frozen_mpy.o +endif + +# Sources that may contain qstrings +SRC_QSTR_IGNORE = nlr% emitnx86% emitnx64% emitnthumb% emitnarm% emitnxtensa% +SRC_QSTR = $(SRC_MOD) $(addprefix py/,$(filter-out $(SRC_QSTR_IGNORE),$(PY_O_BASENAME:.o=.c)) emitnative.c) + +$(HEADER_BUILD)/mpversion.h: $(HEADER_BUILD) + $(Q)$(PYTHON) $(PY_SRC)/makeversionhdr.py $@ + +# mpconfigport.mk is optional, but changes to it may drastically change +# overall config, so they need to be caught +MPCONFIGPORT_MK = $(wildcard mpconfigport.mk) + +# qstr data +# Adding an order only dependency on $(HEADER_BUILD) causes $(HEADER_BUILD) to get +# created before we run the script to generate the .h +# Note: we need to protect the qstr names from the preprocessor, so we wrap +# the lines in "" and then unwrap after the preprocessor is finished. +$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) $(PY_SRC)/makeqstrdata.py $(TOP)/../mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) + $(ECHO) "GEN $@" + $(Q)cat $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^"\(Q(.*)\)"/\1/' > $(HEADER_BUILD)/qstrdefs.preprocessed.h + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ + +# Force nlr code to always be compiled with space-saving optimisation so +# that the function preludes are of a minimal and predictable form. +$(PY_BUILD)/nlr%.o: CFLAGS += -Os + +# emitters + +# $(PY_BUILD)/emitnx64.o: CFLAGS += -DN_X64 +# $(PY_BUILD)/emitnx64.o: py/emitnative.c +# $(call compile_c) + +# $(PY_BUILD)/emitnx86.o: CFLAGS += -DN_X86 +# $(PY_BUILD)/emitnx86.o: py/emitnative.c +# $(call compile_c) + +# $(PY_BUILD)/emitnthumb.o: CFLAGS += -DN_THUMB +# $(PY_BUILD)/emitnthumb.o: py/emitnative.c +# $(call compile_c) + +# $(PY_BUILD)/emitnarm.o: CFLAGS += -DN_ARM +# $(PY_BUILD)/emitnarm.o: py/emitnative.c +# $(call compile_c) + +# $(PY_BUILD)/emitnxtensa.o: CFLAGS += -DN_XTENSA +# $(PY_BUILD)/emitnxtensa.o: py/emitnative.c +# $(call compile_c) + +# optimising gc for speed; 5ms down to 4ms on pybv2 +$(PY_BUILD)/gc.o: CFLAGS += $(CSUPEROPT) + +# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster) +$(PY_BUILD)/vm.o: CFLAGS += $(CSUPEROPT) +# Optimizing vm.o for modern deeply pipelined CPUs with branch predictors +# may require disabling tail jump optimization. This will make sure that +# each opcode has its own dispatching jump which will improve branch +# branch predictor efficiency. +# http://article.gmane.org/gmane.comp.lang.lua.general/75426 +# http://hg.python.org/cpython/file/b127046831e2/Python/ceval.c#l828 +# http://www.emulators.com/docs/nx25_nostradamus.htm +#-fno-crossjumping diff --git a/user/pyhton.c b/user/pyhton.c new file mode 100644 index 0000000..3d9606e --- /dev/null +++ b/user/pyhton.c @@ -0,0 +1,96 @@ +#include +#include +#include + +#include "sh.h" + +#include "py/nlr.h" +#include "py/compile.h" +#include "py/runtime.h" +#include "py/repl.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "lib/utils/pyexec.h" + +#if MICROPY_ENABLE_COMPILER +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, MP_EMIT_OPT_NONE, 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); + } +} +#endif + +static char *stack_top; +static char heap[2048]; + +int python(int argc, char **argv) { + int stack_dummy; + stack_top = (char*)&stack_dummy; + + #if MICROPY_ENABLE_GC + gc_init(heap, heap + sizeof(heap)); + #endif + mp_init(); + #if MICROPY_ENABLE_COMPILER + #if MICROPY_REPL_EVENT_DRIVEN + pyexec_event_repl_init(); + for (;;) { + int c = mp_hal_stdin_rx_chr(); + if (pyexec_event_repl_process_char(c)) { + break; + } + } + #else + pyexec_friendly_repl(); + #endif + //do_str("print('hello world!', list(x+1 for x in range(10)), end='eol\\n')", MP_PARSE_SINGLE_INPUT); + //do_str("for i in range(10):\r\n print(i)", MP_PARSE_FILE_INPUT); + #else + pyexec_frozen_module("frozentest.py"); + #endif + mp_deinit(); + return 0; +} + + +void gc_collect(void) { + // WARNING: This gc_collect implementation doesn't try to get root + // pointers from CPU registers, and thus may function incorrectly. + void *dummy; + gc_collect_start(); + gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t)); + gc_collect_end(); + gc_dump_info(); +} + +mp_lexer_t *mp_lexer_new_from_file(const char *filename) { + mp_raise_OSError(MP_ENOENT); +} + +mp_import_stat_t mp_import_stat(const char *path) { + return MP_IMPORT_STAT_NO_EXIST; +} + +mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); + +void nlr_jump_fail(void *val) { + while (1); +} + +void NORETURN __fatal_error(const char *msg) { + while (1); +} + +HOOK_BUILTIN_CMD(python, python);