| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| extern "C" { | ||
| #include <examplemodule.h> | ||
|
|
||
| // Here we implement the function using C++ code, but since it's | ||
| // declaration has to be compatible with C everything goes in extern "C" scope. | ||
| mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) { | ||
| // Prove we have (at least) C++11 features. | ||
| const auto a = mp_obj_get_int(a_obj); | ||
| const auto b = mp_obj_get_int(b_obj); | ||
| const auto sum = [&]() { | ||
| return mp_obj_new_int(a + b); | ||
| } (); | ||
| // Prove we're being scanned for QSTRs. | ||
| mp_obj_t tup[] = {sum, MP_ROM_QSTR(MP_QSTR_hellocpp)}; | ||
| return mp_obj_new_tuple(2, tup); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| #include <examplemodule.h> | ||
|
|
||
| // Define a Python reference to the function we'll make available. | ||
| // See example.cpp for the definition. | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc); | ||
|
|
||
| // Define all properties of the module. | ||
| // Table entries are key/value pairs of the attribute name (a string) | ||
| // and the MicroPython object reference. | ||
| // All identifiers and strings are written as MP_QSTR_xxx and will be | ||
| // optimized to word-sized integers by the build system (interned strings). | ||
| STATIC const mp_rom_map_elem_t cppexample_module_globals_table[] = { | ||
| { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cppexample) }, | ||
| { MP_ROM_QSTR(MP_QSTR_cppfunc), MP_ROM_PTR(&cppfunc_obj) }, | ||
| }; | ||
| STATIC MP_DEFINE_CONST_DICT(cppexample_module_globals, cppexample_module_globals_table); | ||
|
|
||
| // Define module object. | ||
| const mp_obj_module_t cppexample_user_cmodule = { | ||
| .base = { &mp_type_module }, | ||
| .globals = (mp_obj_dict_t *)&cppexample_module_globals, | ||
| }; | ||
|
|
||
| // Register the module to make it available in Python. | ||
| MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule, MODULE_CPPEXAMPLE_ENABLED); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // Include MicroPython API. | ||
| #include "py/runtime.h" | ||
|
|
||
| // Declare the function we'll make available in Python as cppexample.cppfunc(). | ||
| extern mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| CPPEXAMPLE_MOD_DIR := $(USERMOD_DIR) | ||
|
|
||
| # Add our source files to the respective variables. | ||
| SRC_USERMOD += $(CPPEXAMPLE_MOD_DIR)/examplemodule.c | ||
| SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp | ||
|
|
||
| # Add our module directory to the include path. | ||
| CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) | ||
| CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) | ||
|
|
||
| # We use C++ features so have to link against the standard library. | ||
| LDFLAGS_USERMOD += -lstdc++ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,117 @@ | ||
| /* | ||
| * Automatically generated header file: don't edit | ||
| */ | ||
|
|
||
| #define HAVE_DOT_CONFIG 1 | ||
| #define CONFIG_PLATFORM_LINUX 1 | ||
| #undef CONFIG_PLATFORM_CYGWIN | ||
| #undef CONFIG_PLATFORM_WIN32 | ||
|
|
||
| /* | ||
| * General Configuration | ||
| */ | ||
| #define PREFIX "/usr/local" | ||
| #undef CONFIG_DEBUG | ||
| #undef CONFIG_STRIP_UNWANTED_SECTIONS | ||
| #undef CONFIG_VISUAL_STUDIO_7_0 | ||
| #undef CONFIG_VISUAL_STUDIO_8_0 | ||
| #undef CONFIG_VISUAL_STUDIO_10_0 | ||
| #define CONFIG_VISUAL_STUDIO_7_0_BASE "" | ||
| #define CONFIG_VISUAL_STUDIO_8_0_BASE "" | ||
| #define CONFIG_VISUAL_STUDIO_10_0_BASE "" | ||
| #define CONFIG_EXTRA_CFLAGS_OPTIONS "" | ||
| #define CONFIG_EXTRA_LDFLAGS_OPTIONS "" | ||
|
|
||
| /* | ||
| * SSL Library | ||
| */ | ||
| #undef CONFIG_SSL_SERVER_ONLY | ||
| #undef CONFIG_SSL_CERT_VERIFICATION | ||
| #undef CONFIG_SSL_FULL_MODE | ||
| #define CONFIG_SSL_SKELETON_MODE 1 | ||
| #define CONFIG_SSL_ENABLE_SERVER 1 | ||
| #define CONFIG_SSL_ENABLE_CLIENT 1 | ||
| #undef CONFIG_SSL_DIAGNOSTICS | ||
| #define CONFIG_SSL_PROT_LOW 1 | ||
| #undef CONFIG_SSL_PROT_MEDIUM | ||
| #undef CONFIG_SSL_PROT_HIGH | ||
| #define CONFIG_SSL_AES 1 | ||
| #define CONFIG_SSL_USE_DEFAULT_KEY 1 | ||
| #define CONFIG_SSL_PRIVATE_KEY_LOCATION "" | ||
| #define CONFIG_SSL_PRIVATE_KEY_PASSWORD "" | ||
| #define CONFIG_SSL_X509_CERT_LOCATION "" | ||
| #undef CONFIG_SSL_GENERATE_X509_CERT | ||
| #define CONFIG_SSL_X509_COMMON_NAME "" | ||
| #define CONFIG_SSL_X509_ORGANIZATION_NAME "" | ||
| #define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME "" | ||
| #undef CONFIG_SSL_HAS_PEM | ||
| #undef CONFIG_SSL_USE_PKCS12 | ||
| #define CONFIG_SSL_EXPIRY_TIME | ||
| #define CONFIG_X509_MAX_CA_CERTS 0 | ||
| #define CONFIG_SSL_MAX_CERTS 3 | ||
| #undef CONFIG_SSL_CTX_MUTEXING | ||
| #undef CONFIG_USE_DEV_URANDOM | ||
| #undef CONFIG_WIN32_USE_CRYPTO_LIB | ||
| #undef CONFIG_OPENSSL_COMPATIBLE | ||
| #undef CONFIG_PERFORMANCE_TESTING | ||
| #undef CONFIG_SSL_TEST | ||
| #undef CONFIG_AXTLSWRAP | ||
| #undef CONFIG_AXHTTPD | ||
| #undef CONFIG_HTTP_STATIC_BUILD | ||
| #define CONFIG_HTTP_PORT | ||
| #define CONFIG_HTTP_HTTPS_PORT | ||
| #define CONFIG_HTTP_SESSION_CACHE_SIZE | ||
| #define CONFIG_HTTP_WEBROOT "" | ||
| #define CONFIG_HTTP_TIMEOUT | ||
| #undef CONFIG_HTTP_HAS_CGI | ||
| #define CONFIG_HTTP_CGI_EXTENSIONS "" | ||
| #undef CONFIG_HTTP_ENABLE_LUA | ||
| #define CONFIG_HTTP_LUA_PREFIX "" | ||
| #undef CONFIG_HTTP_BUILD_LUA | ||
| #define CONFIG_HTTP_CGI_LAUNCHER "" | ||
| #undef CONFIG_HTTP_DIRECTORIES | ||
| #undef CONFIG_HTTP_HAS_AUTHORIZATION | ||
| #undef CONFIG_HTTP_HAS_IPV6 | ||
| #undef CONFIG_HTTP_ENABLE_DIFFERENT_USER | ||
| #define CONFIG_HTTP_USER "" | ||
| #undef CONFIG_HTTP_VERBOSE | ||
| #undef CONFIG_HTTP_IS_DAEMON | ||
|
|
||
| /* | ||
| * Language Bindings | ||
| */ | ||
| #undef CONFIG_BINDINGS | ||
| #undef CONFIG_CSHARP_BINDINGS | ||
| #undef CONFIG_VBNET_BINDINGS | ||
| #define CONFIG_DOT_NET_FRAMEWORK_BASE "" | ||
| #undef CONFIG_JAVA_BINDINGS | ||
| #define CONFIG_JAVA_HOME "" | ||
| #undef CONFIG_PERL_BINDINGS | ||
| #define CONFIG_PERL_CORE "" | ||
| #define CONFIG_PERL_LIB "" | ||
| #undef CONFIG_LUA_BINDINGS | ||
| #define CONFIG_LUA_CORE "" | ||
|
|
||
| /* | ||
| * Samples | ||
| */ | ||
| #undef CONFIG_SAMPLES | ||
| #undef CONFIG_C_SAMPLES | ||
| #undef CONFIG_CSHARP_SAMPLES | ||
| #undef CONFIG_VBNET_SAMPLES | ||
| #undef CONFIG_JAVA_SAMPLES | ||
| #undef CONFIG_PERL_SAMPLES | ||
| #undef CONFIG_LUA_SAMPLES | ||
| #undef CONFIG_BIGINT_CLASSICAL | ||
| #undef CONFIG_BIGINT_MONTGOMERY | ||
| #undef CONFIG_BIGINT_BARRETT | ||
| #undef CONFIG_BIGINT_CRT | ||
| #undef CONFIG_BIGINT_KARATSUBA | ||
| #define MUL_KARATSUBA_THRESH | ||
| #define SQU_KARATSUBA_THRESH | ||
| #undef CONFIG_BIGINT_SLIDING_WINDOW | ||
| #undef CONFIG_BIGINT_SQUARE | ||
| #undef CONFIG_BIGINT_CHECK_ON | ||
| #undef CONFIG_INTEGER_32BIT | ||
| #undef CONFIG_INTEGER_16BIT | ||
| #undef CONFIG_INTEGER_8BIT |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| #define AXTLS_VERSION "(no version)" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # CMake fragment for MicroPython extmod component | ||
|
|
||
| set(MICROPY_EXTMOD_DIR "${MICROPY_DIR}/extmod") | ||
| set(MICROPY_OOFATFS_DIR "${MICROPY_DIR}/lib/oofatfs") | ||
|
|
||
| set(MICROPY_SOURCE_EXTMOD | ||
| ${MICROPY_DIR}/lib/embed/abort_.c | ||
| ${MICROPY_DIR}/lib/utils/printf.c | ||
| ${MICROPY_EXTMOD_DIR}/machine_i2c.c | ||
| ${MICROPY_EXTMOD_DIR}/machine_mem.c | ||
| ${MICROPY_EXTMOD_DIR}/machine_pulse.c | ||
| ${MICROPY_EXTMOD_DIR}/machine_signal.c | ||
| ${MICROPY_EXTMOD_DIR}/machine_spi.c | ||
| ${MICROPY_EXTMOD_DIR}/modbluetooth.c | ||
| ${MICROPY_EXTMOD_DIR}/modbtree.c | ||
| ${MICROPY_EXTMOD_DIR}/modframebuf.c | ||
| ${MICROPY_EXTMOD_DIR}/modonewire.c | ||
| ${MICROPY_EXTMOD_DIR}/moduasyncio.c | ||
| ${MICROPY_EXTMOD_DIR}/modubinascii.c | ||
| ${MICROPY_EXTMOD_DIR}/moducryptolib.c | ||
| ${MICROPY_EXTMOD_DIR}/moductypes.c | ||
| ${MICROPY_EXTMOD_DIR}/moduhashlib.c | ||
| ${MICROPY_EXTMOD_DIR}/moduheapq.c | ||
| ${MICROPY_EXTMOD_DIR}/modujson.c | ||
| ${MICROPY_EXTMOD_DIR}/modurandom.c | ||
| ${MICROPY_EXTMOD_DIR}/modure.c | ||
| ${MICROPY_EXTMOD_DIR}/moduselect.c | ||
| ${MICROPY_EXTMOD_DIR}/modussl_axtls.c | ||
| ${MICROPY_EXTMOD_DIR}/modussl_mbedtls.c | ||
| ${MICROPY_EXTMOD_DIR}/modutimeq.c | ||
| ${MICROPY_EXTMOD_DIR}/moduwebsocket.c | ||
| ${MICROPY_EXTMOD_DIR}/moduzlib.c | ||
| ${MICROPY_EXTMOD_DIR}/modwebrepl.c | ||
| ${MICROPY_EXTMOD_DIR}/uos_dupterm.c | ||
| ${MICROPY_EXTMOD_DIR}/utime_mphal.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_blockdev.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_fat.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_fat_diskio.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_fat_file.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_lfs.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_posix.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_posix_file.c | ||
| ${MICROPY_EXTMOD_DIR}/vfs_reader.c | ||
| ${MICROPY_EXTMOD_DIR}/virtpin.c | ||
| ${MICROPY_EXTMOD_DIR}/nimble/modbluetooth_nimble.c | ||
| ) | ||
|
|
||
| # Library for btree module and associated code | ||
|
|
||
| set(MICROPY_LIB_BERKELEY_DIR "${MICROPY_DIR}/lib/berkeley-db-1.xx") | ||
|
|
||
| if(EXISTS "${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c") | ||
| add_library(micropy_extmod_btree OBJECT | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_conv.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_debug.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_delete.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_get.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_open.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_overflow.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_page.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_put.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_search.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_seq.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_split.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_utils.c | ||
| ${MICROPY_LIB_BERKELEY_DIR}/mpool/mpool.c | ||
| ) | ||
|
|
||
| target_include_directories(micropy_extmod_btree PRIVATE | ||
| ${MICROPY_LIB_BERKELEY_DIR}/PORT/include | ||
| ) | ||
|
|
||
| target_compile_definitions(micropy_extmod_btree PRIVATE | ||
| __DBINTERFACE_PRIVATE=1 | ||
| mpool_error=printf | ||
| abort=abort_ | ||
| "virt_fd_t=void*" | ||
| ) | ||
|
|
||
| # The include directories and compile definitions below are needed to build | ||
| # modbtree.c and should be added to the main MicroPython target. | ||
|
|
||
| list(APPEND MICROPY_INC_CORE | ||
| "${MICROPY_LIB_BERKELEY_DIR}/PORT/include" | ||
| ) | ||
|
|
||
| list(APPEND MICROPY_DEF_CORE | ||
| __DBINTERFACE_PRIVATE=1 | ||
| "virt_fd_t=void*" | ||
| ) | ||
| endif() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,234 @@ | ||
| # This makefile fragment provides rules to build 3rd-party components for extmod modules | ||
|
|
||
| ################################################################################ | ||
| # VFS FAT FS | ||
|
|
||
| OOFATFS_DIR = lib/oofatfs | ||
|
|
||
| # this sets the config file for FatFs | ||
| CFLAGS_MOD += -DFFCONF_H=\"$(OOFATFS_DIR)/ffconf.h\" | ||
|
|
||
| ifeq ($(MICROPY_VFS_FAT),1) | ||
| CFLAGS_MOD += -DMICROPY_VFS_FAT=1 | ||
| SRC_MOD += $(addprefix $(OOFATFS_DIR)/,\ | ||
| ff.c \ | ||
| ffunicode.c \ | ||
| ) | ||
| endif | ||
|
|
||
| ################################################################################ | ||
| # VFS littlefs | ||
|
|
||
| LITTLEFS_DIR = lib/littlefs | ||
|
|
||
| ifeq ($(MICROPY_VFS_LFS1),1) | ||
| CFLAGS_MOD += -DMICROPY_VFS_LFS1=1 | ||
| CFLAGS_MOD += -DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT | ||
| SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\ | ||
| lfs1.c \ | ||
| lfs1_util.c \ | ||
| ) | ||
| else | ||
| CFLAGS_MOD += -DMICROPY_VFS_LFS1=0 | ||
| endif | ||
|
|
||
| ifeq ($(MICROPY_VFS_LFS2),1) | ||
| CFLAGS_MOD += -DMICROPY_VFS_LFS2=1 | ||
| CFLAGS_MOD += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT | ||
| SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\ | ||
| lfs2.c \ | ||
| lfs2_util.c \ | ||
| ) | ||
| else | ||
| CFLAGS_MOD += -DMICROPY_VFS_LFS2=0 | ||
|
|
||
| $(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers | ||
| endif | ||
|
|
||
| ################################################################################ | ||
| # ussl | ||
|
|
||
| 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)/extmod/axtls-include | ||
| AXTLS_DIR = lib/axtls | ||
| $(BUILD)/$(AXTLS_DIR)/%.o: CFLAGS += -Wno-all -Wno-unused-parameter -Wno-uninitialized -Wno-sign-compare -Wno-old-style-definition -Dmp_stream_errno=errno $(AXTLS_DEFS_EXTRA) | ||
| SRC_MOD += $(addprefix $(AXTLS_DIR)/,\ | ||
| ssl/asn1.c \ | ||
| ssl/loader.c \ | ||
| ssl/tls1.c \ | ||
| ssl/tls1_svr.c \ | ||
| ssl/tls1_clnt.c \ | ||
| ssl/x509.c \ | ||
| crypto/aes.c \ | ||
| crypto/bigint.c \ | ||
| crypto/crypto_misc.c \ | ||
| crypto/hmac.c \ | ||
| crypto/md5.c \ | ||
| crypto/rsa.c \ | ||
| crypto/sha1.c \ | ||
| ) | ||
| else ifeq ($(MICROPY_SSL_MBEDTLS),1) | ||
| MBEDTLS_DIR = lib/mbedtls | ||
| CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include | ||
| SRC_MOD += $(addprefix $(MBEDTLS_DIR)/library/,\ | ||
| aes.c \ | ||
| aesni.c \ | ||
| arc4.c \ | ||
| asn1parse.c \ | ||
| asn1write.c \ | ||
| base64.c \ | ||
| bignum.c \ | ||
| blowfish.c \ | ||
| camellia.c \ | ||
| ccm.c \ | ||
| certs.c \ | ||
| chacha20.c \ | ||
| chachapoly.c \ | ||
| cipher.c \ | ||
| cipher_wrap.c \ | ||
| cmac.c \ | ||
| ctr_drbg.c \ | ||
| debug.c \ | ||
| des.c \ | ||
| dhm.c \ | ||
| ecdh.c \ | ||
| ecdsa.c \ | ||
| ecjpake.c \ | ||
| ecp.c \ | ||
| ecp_curves.c \ | ||
| entropy.c \ | ||
| entropy_poll.c \ | ||
| error.c \ | ||
| gcm.c \ | ||
| havege.c \ | ||
| hmac_drbg.c \ | ||
| md2.c \ | ||
| md4.c \ | ||
| md5.c \ | ||
| md.c \ | ||
| md_wrap.c \ | ||
| oid.c \ | ||
| padlock.c \ | ||
| pem.c \ | ||
| pk.c \ | ||
| pkcs11.c \ | ||
| pkcs12.c \ | ||
| pkcs5.c \ | ||
| pkparse.c \ | ||
| pk_wrap.c \ | ||
| pkwrite.c \ | ||
| platform.c \ | ||
| platform_util.c \ | ||
| poly1305.c \ | ||
| ripemd160.c \ | ||
| rsa.c \ | ||
| rsa_internal.c \ | ||
| sha1.c \ | ||
| sha256.c \ | ||
| sha512.c \ | ||
| ssl_cache.c \ | ||
| ssl_ciphersuites.c \ | ||
| ssl_cli.c \ | ||
| ssl_cookie.c \ | ||
| ssl_srv.c \ | ||
| ssl_ticket.c \ | ||
| ssl_tls.c \ | ||
| timing.c \ | ||
| x509.c \ | ||
| x509_create.c \ | ||
| x509_crl.c \ | ||
| x509_crt.c \ | ||
| x509_csr.c \ | ||
| x509write_crt.c \ | ||
| x509write_csr.c \ | ||
| xtea.c \ | ||
| ) | ||
| endif | ||
| endif | ||
|
|
||
| ################################################################################ | ||
| # lwip | ||
|
|
||
| ifeq ($(MICROPY_PY_LWIP),1) | ||
| # A port should add an include path where lwipopts.h can be found (eg extmod/lwip-include) | ||
| LWIP_DIR = lib/lwip/src | ||
| INC += -I$(TOP)/$(LWIP_DIR)/include | ||
| CFLAGS_MOD += -DMICROPY_PY_LWIP=1 | ||
| $(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS_MOD += -Wno-address | ||
| SRC_MOD += extmod/modlwip.c lib/netutils/netutils.c | ||
| SRC_MOD += $(addprefix $(LWIP_DIR)/,\ | ||
| apps/mdns/mdns.c \ | ||
| core/def.c \ | ||
| core/dns.c \ | ||
| core/inet_chksum.c \ | ||
| core/init.c \ | ||
| core/ip.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/timeouts.c \ | ||
| core/udp.c \ | ||
| core/ipv4/autoip.c \ | ||
| core/ipv4/dhcp.c \ | ||
| core/ipv4/etharp.c \ | ||
| core/ipv4/icmp.c \ | ||
| core/ipv4/igmp.c \ | ||
| core/ipv4/ip4_addr.c \ | ||
| core/ipv4/ip4.c \ | ||
| core/ipv4/ip4_frag.c \ | ||
| core/ipv6/dhcp6.c \ | ||
| core/ipv6/ethip6.c \ | ||
| core/ipv6/icmp6.c \ | ||
| core/ipv6/inet6.c \ | ||
| core/ipv6/ip6_addr.c \ | ||
| core/ipv6/ip6.c \ | ||
| core/ipv6/ip6_frag.c \ | ||
| core/ipv6/mld6.c \ | ||
| core/ipv6/nd6.c \ | ||
| netif/ethernet.c \ | ||
| ) | ||
| ifeq ($(MICROPY_PY_LWIP_SLIP),1) | ||
| CFLAGS_MOD += -DMICROPY_PY_LWIP_SLIP=1 | ||
| SRC_MOD += $(LWIP_DIR)/netif/slipif.c | ||
| endif | ||
| endif | ||
|
|
||
| ################################################################################ | ||
| # btree | ||
|
|
||
| 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=void*" $(BTREE_DEFS_EXTRA) | ||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,309 @@ | ||
| /* | ||
| * This file is part of the MicroPython project, http://micropython.org/ | ||
| * | ||
| * The MIT License (MIT) | ||
| * | ||
| * Copyright (c) 2020 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/runtime.h" | ||
| #include "py/smallint.h" | ||
| #include "py/pairheap.h" | ||
| #include "py/mphal.h" | ||
|
|
||
| #if MICROPY_PY_UASYNCIO | ||
|
|
||
| #define TASK_STATE_RUNNING_NOT_WAITED_ON (mp_const_true) | ||
| #define TASK_STATE_DONE_NOT_WAITED_ON (mp_const_none) | ||
| #define TASK_STATE_DONE_WAS_WAITED_ON (mp_const_false) | ||
|
|
||
| #define TASK_IS_DONE(task) ( \ | ||
| (task)->state == TASK_STATE_DONE_NOT_WAITED_ON \ | ||
| || (task)->state == TASK_STATE_DONE_WAS_WAITED_ON) | ||
|
|
||
| typedef struct _mp_obj_task_t { | ||
| mp_pairheap_t pairheap; | ||
| mp_obj_t coro; | ||
| mp_obj_t data; | ||
| mp_obj_t state; | ||
| mp_obj_t ph_key; | ||
| } mp_obj_task_t; | ||
|
|
||
| typedef struct _mp_obj_task_queue_t { | ||
| mp_obj_base_t base; | ||
| mp_obj_task_t *heap; | ||
| } mp_obj_task_queue_t; | ||
|
|
||
| STATIC const mp_obj_type_t task_queue_type; | ||
| STATIC const mp_obj_type_t task_type; | ||
|
|
||
| STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); | ||
|
|
||
| /******************************************************************************/ | ||
| // Ticks for task ordering in pairing heap | ||
|
|
||
| STATIC mp_obj_t ticks(void) { | ||
| return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)); | ||
| } | ||
|
|
||
| STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) { | ||
| mp_uint_t t0 = MP_OBJ_SMALL_INT_VALUE(t0_in); | ||
| mp_uint_t t1 = MP_OBJ_SMALL_INT_VALUE(t1_in); | ||
| mp_int_t diff = ((t1 - t0 + MICROPY_PY_UTIME_TICKS_PERIOD / 2) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1)) | ||
| - MICROPY_PY_UTIME_TICKS_PERIOD / 2; | ||
| return diff; | ||
| } | ||
|
|
||
| STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) { | ||
| mp_obj_task_t *t1 = (mp_obj_task_t *)n1; | ||
| mp_obj_task_t *t2 = (mp_obj_task_t *)n2; | ||
| return MP_OBJ_SMALL_INT_VALUE(ticks_diff(t1->ph_key, t2->ph_key)) < 0; | ||
| } | ||
|
|
||
| /******************************************************************************/ | ||
| // TaskQueue class | ||
|
|
||
| STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { | ||
| (void)args; | ||
| mp_arg_check_num(n_args, kw_args, 0, 0, false); | ||
| mp_obj_task_queue_t *self = m_new_obj(mp_obj_task_queue_t); | ||
| self->base.type = type; | ||
| self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt); | ||
| return MP_OBJ_FROM_PTR(self); | ||
| } | ||
|
|
||
| STATIC mp_obj_t task_queue_peek(mp_obj_t self_in) { | ||
| mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); | ||
| if (self->heap == NULL) { | ||
| return mp_const_none; | ||
| } else { | ||
| return MP_OBJ_FROM_PTR(self->heap); | ||
| } | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek); | ||
|
|
||
| STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) { | ||
| mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]); | ||
| mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]); | ||
| task->data = mp_const_none; | ||
| if (n_args == 2) { | ||
| task->ph_key = ticks(); | ||
| } else { | ||
| assert(mp_obj_is_small_int(args[2])); | ||
| task->ph_key = args[2]; | ||
| } | ||
| self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, &self->heap->pairheap, &task->pairheap); | ||
| return mp_const_none; | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_sorted_obj, 2, 3, task_queue_push_sorted); | ||
|
|
||
| STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) { | ||
| mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); | ||
| mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap); | ||
| if (head == NULL) { | ||
| mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap")); | ||
| } | ||
| self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap); | ||
| return MP_OBJ_FROM_PTR(head); | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_head_obj, task_queue_pop_head); | ||
|
|
||
| STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) { | ||
| mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); | ||
| mp_obj_task_t *task = MP_OBJ_TO_PTR(task_in); | ||
| self->heap = (mp_obj_task_t *)mp_pairheap_delete(task_lt, &self->heap->pairheap, &task->pairheap); | ||
| return mp_const_none; | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_2(task_queue_remove_obj, task_queue_remove); | ||
|
|
||
| STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = { | ||
| { MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) }, | ||
| { MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_sorted_obj) }, | ||
| { MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_sorted_obj) }, | ||
| { MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) }, | ||
| { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) }, | ||
| }; | ||
| STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table); | ||
|
|
||
| STATIC const mp_obj_type_t task_queue_type = { | ||
| { &mp_type_type }, | ||
| .name = MP_QSTR_TaskQueue, | ||
| .make_new = task_queue_make_new, | ||
| .locals_dict = (mp_obj_dict_t *)&task_queue_locals_dict, | ||
| }; | ||
|
|
||
| /******************************************************************************/ | ||
| // Task class | ||
|
|
||
| // This is the core uasyncio context with cur_task, _task_queue and CancelledError. | ||
| STATIC mp_obj_t uasyncio_context = MP_OBJ_NULL; | ||
|
|
||
| STATIC mp_obj_t task_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { | ||
| mp_arg_check_num(n_args, kw_args, 1, 2, false); | ||
| mp_obj_task_t *self = m_new_obj(mp_obj_task_t); | ||
| self->pairheap.base.type = type; | ||
| mp_pairheap_init_node(task_lt, &self->pairheap); | ||
| self->coro = args[0]; | ||
| self->data = mp_const_none; | ||
| self->state = TASK_STATE_RUNNING_NOT_WAITED_ON; | ||
| self->ph_key = MP_OBJ_NEW_SMALL_INT(0); | ||
| if (n_args == 2) { | ||
| uasyncio_context = args[1]; | ||
| } | ||
| return MP_OBJ_FROM_PTR(self); | ||
| } | ||
|
|
||
| STATIC mp_obj_t task_done(mp_obj_t self_in) { | ||
| mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); | ||
| return mp_obj_new_bool(TASK_IS_DONE(self)); | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_done_obj, task_done); | ||
|
|
||
| STATIC mp_obj_t task_cancel(mp_obj_t self_in) { | ||
| mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); | ||
| // Check if task is already finished. | ||
| if (TASK_IS_DONE(self)) { | ||
| return mp_const_false; | ||
| } | ||
| // Can't cancel self (not supported yet). | ||
| mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task)); | ||
| if (self_in == cur_task) { | ||
| mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't cancel self")); | ||
| } | ||
| // If Task waits on another task then forward the cancel to the one it's waiting on. | ||
| while (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(self->data)), MP_OBJ_FROM_PTR(&task_type))) { | ||
| self = MP_OBJ_TO_PTR(self->data); | ||
| } | ||
|
|
||
| mp_obj_t _task_queue = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR__task_queue)); | ||
|
|
||
| // Reschedule Task as a cancelled task. | ||
| mp_obj_t dest[3]; | ||
| mp_load_method_maybe(self->data, MP_QSTR_remove, dest); | ||
| if (dest[0] != MP_OBJ_NULL) { | ||
| // Not on the main running queue, remove the task from the queue it's on. | ||
| dest[2] = MP_OBJ_FROM_PTR(self); | ||
| mp_call_method_n_kw(1, 0, dest); | ||
| // _task_queue.push_head(self) | ||
| dest[0] = _task_queue; | ||
| dest[1] = MP_OBJ_FROM_PTR(self); | ||
| task_queue_push_sorted(2, dest); | ||
| } else if (ticks_diff(self->ph_key, ticks()) > 0) { | ||
| // On the main running queue but scheduled in the future, so bring it forward to now. | ||
| // _task_queue.remove(self) | ||
| task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self)); | ||
| // _task_queue.push_head(self) | ||
| dest[0] = _task_queue; | ||
| dest[1] = MP_OBJ_FROM_PTR(self); | ||
| task_queue_push_sorted(2, dest); | ||
| } | ||
|
|
||
| self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError)); | ||
|
|
||
| return mp_const_true; | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel); | ||
|
|
||
| STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { | ||
| mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); | ||
| if (dest[0] == MP_OBJ_NULL) { | ||
| // Load | ||
| if (attr == MP_QSTR_coro) { | ||
| dest[0] = self->coro; | ||
| } else if (attr == MP_QSTR_data) { | ||
| dest[0] = self->data; | ||
| } else if (attr == MP_QSTR_state) { | ||
| dest[0] = self->state; | ||
| } else if (attr == MP_QSTR_done) { | ||
| dest[0] = MP_OBJ_FROM_PTR(&task_done_obj); | ||
| dest[1] = self_in; | ||
| } else if (attr == MP_QSTR_cancel) { | ||
| dest[0] = MP_OBJ_FROM_PTR(&task_cancel_obj); | ||
| dest[1] = self_in; | ||
| } else if (attr == MP_QSTR_ph_key) { | ||
| dest[0] = self->ph_key; | ||
| } | ||
| } else if (dest[1] != MP_OBJ_NULL) { | ||
| // Store | ||
| if (attr == MP_QSTR_data) { | ||
| self->data = dest[1]; | ||
| dest[0] = MP_OBJ_NULL; | ||
| } else if (attr == MP_QSTR_state) { | ||
| self->state = dest[1]; | ||
| dest[0] = MP_OBJ_NULL; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { | ||
| (void)iter_buf; | ||
| mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); | ||
| if (TASK_IS_DONE(self)) { | ||
| // Signal that the completed-task has been await'ed on. | ||
| self->state = TASK_STATE_DONE_WAS_WAITED_ON; | ||
| } else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) { | ||
| // Allocate the waiting queue. | ||
| self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL); | ||
| } | ||
| return self_in; | ||
| } | ||
|
|
||
| STATIC mp_obj_t task_iternext(mp_obj_t self_in) { | ||
| mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); | ||
| if (TASK_IS_DONE(self)) { | ||
| // Task finished, raise return value to caller so it can continue. | ||
| nlr_raise(self->data); | ||
| } else { | ||
| // Put calling task on waiting queue. | ||
| mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task)); | ||
| mp_obj_t args[2] = { self->state, cur_task }; | ||
| task_queue_push_sorted(2, args); | ||
| // Set calling task's data to this task that it waits on, to double-link it. | ||
| ((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in; | ||
| } | ||
| return mp_const_none; | ||
| } | ||
|
|
||
| STATIC const mp_obj_type_t task_type = { | ||
| { &mp_type_type }, | ||
| .name = MP_QSTR_Task, | ||
| .make_new = task_make_new, | ||
| .attr = task_attr, | ||
| .getiter = task_getiter, | ||
| .iternext = task_iternext, | ||
| }; | ||
|
|
||
| /******************************************************************************/ | ||
| // C-level uasyncio module | ||
|
|
||
| STATIC const mp_rom_map_elem_t mp_module_uasyncio_globals_table[] = { | ||
| { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__uasyncio) }, | ||
| { MP_ROM_QSTR(MP_QSTR_TaskQueue), MP_ROM_PTR(&task_queue_type) }, | ||
| { MP_ROM_QSTR(MP_QSTR_Task), MP_ROM_PTR(&task_type) }, | ||
| }; | ||
| STATIC MP_DEFINE_CONST_DICT(mp_module_uasyncio_globals, mp_module_uasyncio_globals_table); | ||
|
|
||
| const mp_obj_module_t mp_module_uasyncio = { | ||
| .base = { &mp_type_module }, | ||
| .globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals, | ||
| }; | ||
|
|
||
| #endif // MICROPY_PY_UASYNCIO |