| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| /* This example demonstrates the following features in a native module: | ||
| - using floats | ||
| - defining additional code in Python (see test.py) | ||
| - have extra C code in a separate file (see prod.c) | ||
| */ | ||
|
|
||
| // Include the header file to get access to the MicroPython API | ||
| #include "py/dynruntime.h" | ||
|
|
||
| // Include the header for auxiliary C code for this module | ||
| #include "prod.h" | ||
|
|
||
| // Automatically detect if this module should include double-precision code. | ||
| // If double precision is supported by the target architecture then it can | ||
| // be used in native module regardless of what float setting the target | ||
| // MicroPython runtime uses (being none, float or double). | ||
| #if defined(__i386__) || defined(__x86_64__) || (defined(__ARM_FP) && (__ARM_FP & 8)) | ||
| #define USE_DOUBLE 1 | ||
| #else | ||
| #define USE_DOUBLE 0 | ||
| #endif | ||
|
|
||
| // A function that uses the default float type configured for the current target | ||
| // This default can be overridden by specifying MICROPY_FLOAT_IMPL at the make level | ||
| STATIC mp_obj_t add(mp_obj_t x, mp_obj_t y) { | ||
| return mp_obj_new_float(mp_obj_get_float(x) + mp_obj_get_float(y)); | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_obj, add); | ||
|
|
||
| // A function that explicitly uses single precision floats | ||
| STATIC mp_obj_t add_f(mp_obj_t x, mp_obj_t y) { | ||
| return mp_obj_new_float_from_f(mp_obj_get_float_to_f(x) + mp_obj_get_float_to_f(y)); | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_f_obj, add_f); | ||
|
|
||
| #if USE_DOUBLE | ||
| // A function that explicitly uses double precision floats | ||
| STATIC mp_obj_t add_d(mp_obj_t x, mp_obj_t y) { | ||
| return mp_obj_new_float_from_d(mp_obj_get_float_to_d(x) + mp_obj_get_float_to_d(y)); | ||
| } | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_2(add_d_obj, add_d); | ||
| #endif | ||
|
|
||
| // A function that computes the product of floats in an array. | ||
| // This function uses the most general C argument interface, which is more difficult | ||
| // to use but has access to the globals dict of the module via self->globals. | ||
| STATIC mp_obj_t productf(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| // Check number of arguments is valid | ||
| mp_arg_check_num_mp(n_args, n_kw, 1, 1, false); | ||
|
|
||
| // Extract buffer pointer and verify typecode | ||
| mp_buffer_info_t bufinfo; | ||
| mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_RW); | ||
| if (bufinfo.typecode != 'f') { | ||
| mp_raise_ValueError(MP_ERROR_TEXT("expecting float array")); | ||
| } | ||
|
|
||
| // Compute product, store result back in first element of array | ||
| float *ptr = bufinfo.buf; | ||
| float prod = prod_array(bufinfo.len / sizeof(*ptr), ptr); | ||
| ptr[0] = prod; | ||
|
|
||
| return mp_const_none; | ||
| } | ||
|
|
||
| // This is the entry point and is called when the module is imported | ||
| mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| // This must be first, it sets up the globals dict and other things | ||
| MP_DYNRUNTIME_INIT_ENTRY | ||
|
|
||
| // Make the functions available in the module's namespace | ||
| mp_store_global(MP_QSTR_add, MP_OBJ_FROM_PTR(&add_obj)); | ||
| mp_store_global(MP_QSTR_add_f, MP_OBJ_FROM_PTR(&add_f_obj)); | ||
| #if USE_DOUBLE | ||
| mp_store_global(MP_QSTR_add_d, MP_OBJ_FROM_PTR(&add_d_obj)); | ||
| #endif | ||
|
|
||
| // The productf function uses the most general C argument interface | ||
| mp_store_global(MP_QSTR_productf, MP_DYNRUNTIME_MAKE_FUNCTION(productf)); | ||
|
|
||
| // This must be last, it restores the globals dict | ||
| MP_DYNRUNTIME_INIT_EXIT | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #include "prod.h" | ||
|
|
||
| float prod_array(int n, float *ar) { | ||
| float ans = 1; | ||
| for (int i = 0; i < n; ++i) { | ||
| ans *= ar[i]; | ||
| } | ||
| return ans; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| float prod_array(int n, float *ar); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # This Python code will be merged with the C code in main.c | ||
|
|
||
| import array | ||
|
|
||
|
|
||
| def isclose(a, b): | ||
| return abs(a - b) < 1e-3 | ||
|
|
||
|
|
||
| def test(): | ||
| tests = [ | ||
| isclose(add(0.1, 0.2), 0.3), | ||
| isclose(add_f(0.1, 0.2), 0.3), | ||
| ] | ||
|
|
||
| ar = array.array("f", [1, 2, 3.5]) | ||
| productf(ar) | ||
| tests.append(isclose(ar[0], 7)) | ||
|
|
||
| if "add_d" in globals(): | ||
| tests.append(isclose(add_d(0.1, 0.2), 0.3)) | ||
|
|
||
| print(tests) | ||
|
|
||
| if not all(tests): | ||
| raise SystemExit(1) | ||
|
|
||
|
|
||
| test() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Location of top-level MicroPython directory | ||
| MPY_DIR = ../../.. | ||
|
|
||
| # Name of module (different to built-in framebuf so it can coexist) | ||
| MOD = framebuf_$(ARCH) | ||
|
|
||
| # Source files (.c or .py) | ||
| SRC = framebuf.c | ||
|
|
||
| # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) | ||
| ARCH = x64 | ||
|
|
||
| include $(MPY_DIR)/py/dynruntime.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #define MICROPY_PY_FRAMEBUF (1) | ||
|
|
||
| #include "py/dynruntime.h" | ||
|
|
||
| #if !defined(__linux__) | ||
| void *memset(void *s, int c, size_t n) { | ||
| return mp_fun_table.memset_(s, c, n); | ||
| } | ||
| #endif | ||
|
|
||
| mp_obj_type_t mp_type_framebuf; | ||
|
|
||
| #include "extmod/modframebuf.c" | ||
|
|
||
| mp_map_elem_t framebuf_locals_dict_table[10]; | ||
| STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); | ||
|
|
||
| mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| MP_DYNRUNTIME_INIT_ENTRY | ||
|
|
||
| mp_type_framebuf.base.type = (void*)&mp_type_type; | ||
| mp_type_framebuf.name = MP_QSTR_FrameBuffer; | ||
| mp_type_framebuf.make_new = framebuf_make_new; | ||
| mp_type_framebuf.buffer_p.get_buffer = framebuf_get_buffer; | ||
| framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; | ||
| framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; | ||
| framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; | ||
| framebuf_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_hline), MP_OBJ_FROM_PTR(&framebuf_hline_obj) }; | ||
| framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) }; | ||
| framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) }; | ||
| framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) }; | ||
| framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; | ||
| framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; | ||
| framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; | ||
| mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict; | ||
|
|
||
| mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); | ||
| mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj)); | ||
| mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); | ||
| mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); | ||
| mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565)); | ||
| mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB)); | ||
| mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB)); | ||
| mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8)); | ||
| mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB)); | ||
| mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB)); | ||
|
|
||
| MP_DYNRUNTIME_INIT_EXIT | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Location of top-level MicroPython directory | ||
| MPY_DIR = ../../.. | ||
|
|
||
| # Name of module (different to built-in uheapq so it can coexist) | ||
| MOD = uheapq_$(ARCH) | ||
|
|
||
| # Source files (.c or .py) | ||
| SRC = uheapq.c | ||
|
|
||
| # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) | ||
| ARCH = x64 | ||
|
|
||
| include $(MPY_DIR)/py/dynruntime.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #define MICROPY_PY_UHEAPQ (1) | ||
|
|
||
| #include "py/dynruntime.h" | ||
|
|
||
| #include "extmod/moduheapq.c" | ||
|
|
||
| mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| MP_DYNRUNTIME_INIT_ENTRY | ||
|
|
||
| mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uheapq)); | ||
| mp_store_global(MP_QSTR_heappush, MP_OBJ_FROM_PTR(&mod_uheapq_heappush_obj)); | ||
| mp_store_global(MP_QSTR_heappop, MP_OBJ_FROM_PTR(&mod_uheapq_heappop_obj)); | ||
| mp_store_global(MP_QSTR_heapify, MP_OBJ_FROM_PTR(&mod_uheapq_heapify_obj)); | ||
|
|
||
| MP_DYNRUNTIME_INIT_EXIT | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Location of top-level MicroPython directory | ||
| MPY_DIR = ../../.. | ||
|
|
||
| # Name of module (different to built-in urandom so it can coexist) | ||
| MOD = urandom_$(ARCH) | ||
|
|
||
| # Source files (.c or .py) | ||
| SRC = urandom.c | ||
|
|
||
| # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) | ||
| ARCH = x64 | ||
|
|
||
| include $(MPY_DIR)/py/dynruntime.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #define MICROPY_PY_URANDOM (1) | ||
| #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) | ||
|
|
||
| #include "py/dynruntime.h" | ||
|
|
||
| // Dynamic native modules don't support a data section so these must go in the BSS | ||
| uint32_t yasmarang_pad, yasmarang_n, yasmarang_d; | ||
| uint8_t yasmarang_dat; | ||
|
|
||
| #include "extmod/modurandom.c" | ||
|
|
||
| mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| MP_DYNRUNTIME_INIT_ENTRY | ||
|
|
||
| yasmarang_pad = 0xeda4baba; | ||
| yasmarang_n = 69; | ||
| yasmarang_d = 233; | ||
|
|
||
| mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_urandom)); | ||
| mp_store_global(MP_QSTR_getrandbits, MP_OBJ_FROM_PTR(&mod_urandom_getrandbits_obj)); | ||
| mp_store_global(MP_QSTR_seed, MP_OBJ_FROM_PTR(&mod_urandom_seed_obj)); | ||
| #if MICROPY_PY_URANDOM_EXTRA_FUNCS | ||
| mp_store_global(MP_QSTR_randrange, MP_OBJ_FROM_PTR(&mod_urandom_randrange_obj)); | ||
| mp_store_global(MP_QSTR_randint, MP_OBJ_FROM_PTR(&mod_urandom_randint_obj)); | ||
| mp_store_global(MP_QSTR_choice, MP_OBJ_FROM_PTR(&mod_urandom_choice_obj)); | ||
| #if MICROPY_PY_BUILTINS_FLOAT | ||
| mp_store_global(MP_QSTR_random, MP_OBJ_FROM_PTR(&mod_urandom_random_obj)); | ||
| mp_store_global(MP_QSTR_uniform, MP_OBJ_FROM_PTR(&mod_urandom_uniform_obj)); | ||
| #endif | ||
| #endif | ||
|
|
||
| MP_DYNRUNTIME_INIT_EXIT | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Location of top-level MicroPython directory | ||
| MPY_DIR = ../../.. | ||
|
|
||
| # Name of module (different to built-in ure so it can coexist) | ||
| MOD = ure_$(ARCH) | ||
|
|
||
| # Source files (.c or .py) | ||
| SRC = ure.c | ||
|
|
||
| # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) | ||
| ARCH = x64 | ||
|
|
||
| include $(MPY_DIR)/py/dynruntime.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| #define MICROPY_STACK_CHECK (1) | ||
| #define MICROPY_PY_URE (1) | ||
| #define MICROPY_PY_URE_MATCH_GROUPS (1) | ||
| #define MICROPY_PY_URE_MATCH_SPAN_START_END (1) | ||
| #define MICROPY_PY_URE_SUB (0) // requires vstr interface | ||
|
|
||
| #include <alloca.h> | ||
| #include "py/dynruntime.h" | ||
|
|
||
| #define STACK_LIMIT (2048) | ||
|
|
||
| const char *stack_top; | ||
|
|
||
| void mp_stack_check(void) { | ||
| // Assumes descending stack on target | ||
| volatile char dummy; | ||
| if (stack_top - &dummy >= STACK_LIMIT) { | ||
| mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("maximum recursion depth exceeded")); | ||
| } | ||
| } | ||
|
|
||
| #if !defined(__linux__) | ||
| void *memcpy(void *dst, const void *src, size_t n) { | ||
| return mp_fun_table.memmove_(dst, src, n); | ||
| } | ||
| void *memset(void *s, int c, size_t n) { | ||
| return mp_fun_table.memset_(s, c, n); | ||
| } | ||
| #endif | ||
|
|
||
| void *memmove(void *dest, const void *src, size_t n) { | ||
| return mp_fun_table.memmove_(dest, src, n); | ||
| } | ||
|
|
||
| mp_obj_type_t match_type; | ||
| mp_obj_type_t re_type; | ||
|
|
||
| #include "extmod/modure.c" | ||
|
|
||
| mp_map_elem_t match_locals_dict_table[5]; | ||
| STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table); | ||
|
|
||
| mp_map_elem_t re_locals_dict_table[3]; | ||
| STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table); | ||
|
|
||
| mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| MP_DYNRUNTIME_INIT_ENTRY | ||
|
|
||
| char dummy; | ||
| stack_top = &dummy; | ||
|
|
||
| // Because MP_QSTR_start/end/split are static, xtensa and xtensawin will make a small data section | ||
| // to copy in this key/value pair if they are specified as a struct, so assign them separately. | ||
|
|
||
| match_type.base.type = (void*)&mp_fun_table.type_type; | ||
| match_type.name = MP_QSTR_match; | ||
| match_type.print = match_print; | ||
| match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) }; | ||
| match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) }; | ||
| match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) }; | ||
| match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) }; | ||
| match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) }; | ||
| match_type.locals_dict = (void*)&match_locals_dict; | ||
|
|
||
| re_type.base.type = (void*)&mp_fun_table.type_type; | ||
| re_type.name = MP_QSTR_ure; | ||
| re_type.print = re_print; | ||
| re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) }; | ||
| re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) }; | ||
| re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) }; | ||
| re_type.locals_dict = (void*)&re_locals_dict; | ||
|
|
||
| mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj)); | ||
| mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj)); | ||
| mp_store_global(MP_QSTR_search, MP_OBJ_FROM_PTR(&re_search_obj)); | ||
|
|
||
| MP_DYNRUNTIME_INIT_EXIT | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # Location of top-level MicroPython directory | ||
| MPY_DIR = ../../.. | ||
|
|
||
| # Name of module (different to built-in uzlib so it can coexist) | ||
| MOD = uzlib_$(ARCH) | ||
|
|
||
| # Source files (.c or .py) | ||
| SRC = uzlib.c | ||
|
|
||
| # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) | ||
| ARCH = x64 | ||
|
|
||
| include $(MPY_DIR)/py/dynruntime.mk |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #define MICROPY_PY_UZLIB (1) | ||
|
|
||
| #include "py/dynruntime.h" | ||
|
|
||
| #if !defined(__linux__) | ||
| void *memset(void *s, int c, size_t n) { | ||
| return mp_fun_table.memset_(s, c, n); | ||
| } | ||
| #endif | ||
|
|
||
| mp_obj_type_t decompio_type; | ||
|
|
||
| #include "extmod/moduzlib.c" | ||
|
|
||
| mp_map_elem_t decompio_locals_dict_table[3]; | ||
| STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table); | ||
|
|
||
| mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { | ||
| MP_DYNRUNTIME_INIT_ENTRY | ||
|
|
||
| decompio_type.base.type = mp_fun_table.type_type; | ||
| decompio_type.name = MP_QSTR_DecompIO; | ||
| decompio_type.make_new = decompio_make_new; | ||
| decompio_type.protocol = &decompio_stream_p; | ||
| decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) }; | ||
| decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) }; | ||
| decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) }; | ||
| decompio_type.locals_dict = (void*)&decompio_locals_dict; | ||
|
|
||
| mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib)); | ||
| mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj)); | ||
| mp_store_global(MP_QSTR_DecompIO, MP_OBJ_FROM_PTR(&decompio_type)); | ||
|
|
||
| MP_DYNRUNTIME_INIT_EXIT | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // Include MicroPython API. | ||
| #include "py/runtime.h" | ||
|
|
||
| // This is the function which will be called from Python as cexample.add_ints(a, b). | ||
| STATIC mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) { | ||
| // Extract the ints from the micropython input objects. | ||
| int a = mp_obj_get_int(a_obj); | ||
| int b = mp_obj_get_int(b_obj); | ||
|
|
||
| // Calculate the addition and convert to MicroPython object. | ||
| return mp_obj_new_int(a + b); | ||
| } | ||
| // Define a Python reference to the function above. | ||
| STATIC MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints); | ||
|
|
||
| // 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 example_module_globals_table[] = { | ||
| { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) }, | ||
| { MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) }, | ||
| }; | ||
| STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table); | ||
|
|
||
| // Define module object. | ||
| const mp_obj_module_t example_user_cmodule = { | ||
| .base = { &mp_type_module }, | ||
| .globals = (mp_obj_dict_t *)&example_module_globals, | ||
| }; | ||
|
|
||
| // Register the module to make it available in Python. | ||
| MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, MODULE_CEXAMPLE_ENABLED); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| EXAMPLE_MOD_DIR := $(USERMOD_DIR) | ||
|
|
||
| # Add all C files to SRC_USERMOD. | ||
| SRC_USERMOD += $(EXAMPLE_MOD_DIR)/examplemodule.c | ||
|
|
||
| # We can add our module folder to include paths if needed | ||
| # This is not actually needed in this example. | ||
| CFLAGS_USERMOD += -I$(EXAMPLE_MOD_DIR) | ||
| CEXAMPLE_MOD_DIR := $(USERMOD_DIR) |
| 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,312 @@ | ||
| /* | ||
| * 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 }, | ||
| .flags = MP_TYPE_FLAG_EXTENDED, | ||
| .name = MP_QSTR_Task, | ||
| .make_new = task_make_new, | ||
| .attr = task_attr, | ||
| MP_TYPE_EXTENDED_FIELDS( | ||
| .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 |