From caac542b235003f7b79d7aa23eaebe8f2c772508 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 25 Mar 2014 14:18:18 +0000 Subject: Proper support for registering builtin modules in ROM. Comes with some refactoring of code and renaming of files. All modules are now named mod*.[ch]. --- py/builtin.h | 2 + py/builtinimport.c | 7 +- py/builtinmath.c | 153 ------------------------- py/builtinmp.c | 51 --------- py/builtintables.c | 154 +++++++++++++++++++++++++ py/builtintables.h | 2 + py/modarray.c | 25 ++++ py/modcollections.c | 25 ++++ py/modmath.c | 153 +++++++++++++++++++++++++ py/modmicropython.c | 50 ++++++++ py/mpconfig.h | 8 +- py/obj.h | 5 +- py/objarray.c | 12 +- py/objmodule.c | 50 ++++---- py/objmodule.h | 4 + py/py.mk | 7 +- py/runtime.c | 151 +++---------------------- stm/main.c | 3 +- stm/pybmodule.c | 3 +- stmhal/Makefile | 6 +- stmhal/main.c | 13 +-- stmhal/modos.c | 178 +++++++++++++++++++++++++++++ stmhal/modos.h | 1 + stmhal/modpyb.c | 308 ++++++++++++++++++++++++++++++++++++++++++++++++++ stmhal/modpyb.h | 1 + stmhal/modtime.c | 44 ++++++++ stmhal/modtime.h | 1 + stmhal/mpconfigport.h | 9 ++ stmhal/osmodule.c | 178 ----------------------------- stmhal/osmodule.h | 1 - stmhal/pybmodule.c | 308 -------------------------------------------------- stmhal/pybmodule.h | 1 - stmhal/timemodule.c | 44 -------- stmhal/timemodule.h | 1 - 34 files changed, 1030 insertions(+), 929 deletions(-) delete mode 100644 py/builtinmath.c delete mode 100644 py/builtinmp.c create mode 100644 py/builtintables.c create mode 100644 py/builtintables.h create mode 100644 py/modarray.c create mode 100644 py/modcollections.c create mode 100644 py/modmath.c create mode 100644 py/modmicropython.c create mode 100644 py/objmodule.h create mode 100644 stmhal/modos.c create mode 100644 stmhal/modos.h create mode 100644 stmhal/modpyb.c create mode 100644 stmhal/modpyb.h create mode 100644 stmhal/modtime.c create mode 100644 stmhal/modtime.h delete mode 100644 stmhal/osmodule.c delete mode 100644 stmhal/osmodule.h delete mode 100644 stmhal/pybmodule.c delete mode 100644 stmhal/pybmodule.h delete mode 100644 stmhal/timemodule.c delete mode 100644 stmhal/timemodule.h diff --git a/py/builtin.h b/py/builtin.h index 69b94e018..45da172d1 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -32,5 +32,7 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj); MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); +extern const mp_obj_module_t mp_module_array; +extern const mp_obj_module_t mp_module_collections; extern const mp_obj_module_t mp_module_math; extern const mp_obj_module_t mp_module_micropython; diff --git a/py/builtinimport.c b/py/builtinimport.c index d4d56b517..882b128df 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -12,6 +12,7 @@ #include "lexerunix.h" #include "parse.h" #include "obj.h" +#include "objmodule.h" #include "parsehelper.h" #include "compile.h" #include "runtime0.h" @@ -156,7 +157,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { const char *mod_str = (const char*)mp_obj_str_get_data(args[0], &mod_len); // check if module already exists - mp_obj_t module_obj = mp_obj_module_get(mp_obj_str_get_qstr(args[0])); + mp_obj_t module_obj = mp_module_get(mp_obj_str_get_qstr(args[0])); if (module_obj != MP_OBJ_NULL) { // If it's not a package, return module right away char *p = strchr(mod_str, '.'); @@ -169,7 +170,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { } // Otherwise, we need to return top-level package qstr pkg_name = qstr_from_strn(mod_str, p - mod_str); - return mp_obj_module_get(pkg_name); + return mp_module_get(pkg_name); } uint last = 0; @@ -200,7 +201,7 @@ mp_obj_t mp_builtin___import__(uint n_args, mp_obj_t *args) { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "ImportError: No module named '%s'", qstr_str(mod_name))); } - module_obj = mp_obj_module_get(mod_name); + module_obj = mp_module_get(mod_name); if (module_obj == MP_OBJ_NULL) { // module not already loaded, so load it! diff --git a/py/builtinmath.c b/py/builtinmath.c deleted file mode 100644 index b81482253..000000000 --- a/py/builtinmath.c +++ /dev/null @@ -1,153 +0,0 @@ -#include - -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "obj.h" -#include "map.h" -#include "builtin.h" - -#if MICROPY_ENABLE_FLOAT - -//TODO: Change macros to check for overflow and raise OverflowError or RangeError -#define MATH_FUN_1(py_name, c_name) \ - mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ - STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); - -#define MATH_FUN_2(py_name, c_name) \ - mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \ - STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name); - -#define MATH_FUN_BOOL1(py_name, c_name) \ - mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return MP_BOOL(c_name(mp_obj_get_float(x_obj))); } \ - STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); - -STATIC const mp_obj_float_t mp_math_e_obj = {{&mp_type_float}, M_E}; -STATIC const mp_obj_float_t mp_math_pi_obj = {{&mp_type_float}, M_PI}; - -MATH_FUN_1(sqrt, sqrt) -MATH_FUN_2(pow, pow) -MATH_FUN_1(exp, exp) -MATH_FUN_1(expm1, expm1) -MATH_FUN_1(log, log) -MATH_FUN_1(log2, log2) -MATH_FUN_1(log10, log10) -MATH_FUN_1(cosh, cosh) -MATH_FUN_1(sinh, sinh) -MATH_FUN_1(tanh, tanh) -MATH_FUN_1(acosh, acosh) -MATH_FUN_1(asinh, asinh) -MATH_FUN_1(atanh, atanh) -MATH_FUN_1(cos, cos) -MATH_FUN_1(sin, sin) -MATH_FUN_1(tan, tan) -MATH_FUN_1(acos, acos) -MATH_FUN_1(asin, asin) -MATH_FUN_1(atan, atan) -MATH_FUN_2(atan2, atan2) -MATH_FUN_1(ceil, ceil) -MATH_FUN_2(copysign, copysign) -MATH_FUN_1(fabs, fabs) -MATH_FUN_1(floor, floor) //TODO: delegate to x.__floor__() if x is not a float -MATH_FUN_2(fmod, fmod) -MATH_FUN_BOOL1(isfinite, isfinite) -MATH_FUN_BOOL1(isinf, isinf) -MATH_FUN_BOOL1(isnan, isnan) -MATH_FUN_1(trunc, trunc) -MATH_FUN_2(ldexp, ldexp) -MATH_FUN_1(erf, erf) -MATH_FUN_1(erfc, erfc) -MATH_FUN_1(gamma, tgamma) -MATH_FUN_1(lgamma, lgamma) -//TODO: factorial, fsum - -// Functions that return a tuple -mp_obj_t mp_math_frexp(mp_obj_t x_obj) { - int int_exponent = 0; - mp_float_t significand = MICROPY_FLOAT_C_FUN(frexp)(mp_obj_get_float(x_obj), &int_exponent); - mp_obj_t tuple[2]; - tuple[0] = mp_obj_new_float(significand); - tuple[1] = mp_obj_new_int(int_exponent); - return mp_obj_new_tuple(2, tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_frexp_obj, mp_math_frexp); - -mp_obj_t mp_math_modf(mp_obj_t x_obj) { - mp_float_t int_part = 0.0; - mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(mp_obj_get_float(x_obj), &int_part); - mp_obj_t tuple[2]; - tuple[0] = mp_obj_new_float(fractional_part); - tuple[1] = mp_obj_new_float(int_part); - return mp_obj_new_tuple(2, tuple); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_modf_obj, mp_math_modf); - -// Angular conversions -mp_obj_t mp_math_radians(mp_obj_t x_obj) { - return mp_obj_new_float(mp_obj_get_float(x_obj) * M_PI / 180.0); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_radians_obj, mp_math_radians); - -mp_obj_t mp_math_degrees(mp_obj_t x_obj) { - return mp_obj_new_float(mp_obj_get_float(x_obj) * 180.0 / M_PI); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_degrees_obj, mp_math_degrees); - -STATIC const mp_map_elem_t mp_module_math_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_math) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_e), (mp_obj_t)&mp_math_e_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_pi), (mp_obj_t)&mp_math_pi_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&mp_math_sqrt_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_pow), (mp_obj_t)&mp_math_pow_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&mp_math_exp_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_expm1), (mp_obj_t)&mp_math_expm1_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&mp_math_log_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&mp_math_log2_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&mp_math_log10_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_cosh), (mp_obj_t)&mp_math_cosh_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&mp_math_sinh_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&mp_math_tanh_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&mp_math_acosh_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&mp_math_asinh_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&mp_math_atanh_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&mp_math_cos_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&mp_math_sin_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&mp_math_tan_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&mp_math_acos_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&mp_math_asin_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&mp_math_atan_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_atan2), (mp_obj_t)&mp_math_atan2_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ceil), (mp_obj_t)&mp_math_ceil_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_copysign), (mp_obj_t)&mp_math_copysign_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_fabs), (mp_obj_t)&mp_math_fabs_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&mp_math_floor_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ldexp), (mp_obj_t)&mp_math_ldexp_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_modf), (mp_obj_t)&mp_math_modf_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_trunc), (mp_obj_t)&mp_math_trunc_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_radians), (mp_obj_t)&mp_math_radians_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_degrees), (mp_obj_t)&mp_math_degrees_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_erf), (mp_obj_t)&mp_math_erf_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_erfc), (mp_obj_t)&mp_math_erfc_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gamma), (mp_obj_t)&mp_math_gamma_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_lgamma), (mp_obj_t)&mp_math_lgamma_obj }, -}; - -STATIC const mp_map_t mp_module_math_globals = { - .all_keys_are_qstrs = 1, - .table_is_fixed_array = 1, - .used = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t), - .alloc = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t), - .table = (mp_map_elem_t*)mp_module_math_globals_table, -}; - -const mp_obj_module_t mp_module_math = { - .base = { &mp_type_module }, - .name = MP_QSTR_math, - .globals = (mp_map_t*)&mp_module_math_globals, -}; - -#endif // MICROPY_ENABLE_FLOAT diff --git a/py/builtinmp.c b/py/builtinmp.c deleted file mode 100644 index 3b7351796..000000000 --- a/py/builtinmp.c +++ /dev/null @@ -1,51 +0,0 @@ - -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "obj.h" -#include "map.h" -#include "builtin.h" - -// Various builtins specific to MicroPython runtime, -// living in micropython module - -#if MICROPY_MEM_STATS -STATIC mp_obj_t mp_micropython_mem_total() { - return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_total_bytes_allocated()); -} - -STATIC mp_obj_t mp_micropython_mem_current() { - return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_current_bytes_allocated()); -} - -STATIC mp_obj_t mp_micropython_mem_peak() { - return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_peak_bytes_allocated()); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_total_obj, mp_micropython_mem_total); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_current_obj, mp_micropython_mem_current); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_peak_obj, mp_micropython_mem_peak); -#endif - -STATIC const mp_map_elem_t mp_module_micropython_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_micropython) }, -#if MICROPY_MEM_STATS - { MP_OBJ_NEW_QSTR(MP_QSTR_mem_total), (mp_obj_t)&mp_micropython_mem_total_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mem_current), (mp_obj_t)&mp_micropython_mem_current_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mem_peak), (mp_obj_t)&mp_micropython_mem_peak_obj }, -#endif -}; - -STATIC const mp_map_t mp_module_micropython_globals = { - .all_keys_are_qstrs = 1, - .table_is_fixed_array = 1, - .used = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t), - .alloc = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t), - .table = (mp_map_elem_t*)mp_module_micropython_globals_table, -}; - -const mp_obj_module_t mp_module_micropython = { - .base = { &mp_type_module }, - .name = MP_QSTR_micropython, - .globals = (mp_map_t*)&mp_module_micropython_globals, -}; diff --git a/py/builtintables.c b/py/builtintables.c new file mode 100644 index 000000000..e9c1bcab2 --- /dev/null +++ b/py/builtintables.c @@ -0,0 +1,154 @@ +#include + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "builtin.h" +#include "builtintables.h" +#include "objarray.h" + +// builtins +// we put these tables in ROM because they're always needed and take up quite a bit of room in RAM +// in fact, it uses less ROM here in table form than the equivalent in code form initialising a dynamic mp_map_t object in RAM +// at the moment it's a linear table, but we could convert it to a const mp_map_t table with a simple preprocessing script + +typedef struct _mp_builtin_elem_t { + qstr qstr; + mp_obj_t elem; +} mp_builtin_elem_t; + +STATIC const mp_builtin_elem_t builtin_object_table[] = { + // built-in core functions + { MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj }, + { MP_QSTR___import__, (mp_obj_t)&mp_builtin___import___obj }, + { MP_QSTR___repl_print__, (mp_obj_t)&mp_builtin___repl_print___obj }, + + // built-in types + { MP_QSTR_bool, (mp_obj_t)&bool_type }, + { MP_QSTR_bytes, (mp_obj_t)&bytes_type }, +#if MICROPY_ENABLE_FLOAT + { MP_QSTR_complex, (mp_obj_t)&mp_type_complex }, +#endif + { MP_QSTR_dict, (mp_obj_t)&dict_type }, + { MP_QSTR_enumerate, (mp_obj_t)&enumerate_type }, + { MP_QSTR_filter, (mp_obj_t)&filter_type }, +#if MICROPY_ENABLE_FLOAT + { MP_QSTR_float, (mp_obj_t)&mp_type_float }, +#endif + { MP_QSTR_int, (mp_obj_t)&int_type }, + { MP_QSTR_list, (mp_obj_t)&list_type }, + { MP_QSTR_map, (mp_obj_t)&map_type }, + { MP_QSTR_object, (mp_obj_t)&mp_type_object }, + { MP_QSTR_set, (mp_obj_t)&set_type }, + { MP_QSTR_str, (mp_obj_t)&str_type }, + { MP_QSTR_super, (mp_obj_t)&super_type }, + { MP_QSTR_tuple, (mp_obj_t)&tuple_type }, + { MP_QSTR_type, (mp_obj_t)&mp_type_type }, + { MP_QSTR_zip, (mp_obj_t)&zip_type }, + + { MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod }, + { MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod }, + + // built-in user functions + { MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj }, + { MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj }, + { MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj }, + { MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj }, + { MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj }, + { MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj }, + { MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj }, + { MP_QSTR_eval, (mp_obj_t)&mp_builtin_eval_obj }, + { MP_QSTR_exec, (mp_obj_t)&mp_builtin_exec_obj }, + { MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj }, + { MP_QSTR_id, (mp_obj_t)&mp_builtin_id_obj }, + { MP_QSTR_isinstance, (mp_obj_t)&mp_builtin_isinstance_obj }, + { MP_QSTR_issubclass, (mp_obj_t)&mp_builtin_issubclass_obj }, + { MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj }, + { MP_QSTR_len, (mp_obj_t)&mp_builtin_len_obj }, + { MP_QSTR_max, (mp_obj_t)&mp_builtin_max_obj }, + { MP_QSTR_min, (mp_obj_t)&mp_builtin_min_obj }, + { MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj }, + { MP_QSTR_ord, (mp_obj_t)&mp_builtin_ord_obj }, + { MP_QSTR_pow, (mp_obj_t)&mp_builtin_pow_obj }, + { MP_QSTR_print, (mp_obj_t)&mp_builtin_print_obj }, + { MP_QSTR_range, (mp_obj_t)&mp_builtin_range_obj }, + { MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj }, + { MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj }, + { MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj }, + { MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj }, + + // built-in exceptions + { MP_QSTR_BaseException, (mp_obj_t)&mp_type_BaseException }, + { MP_QSTR_ArithmeticError, (mp_obj_t)&mp_type_ArithmeticError }, + { MP_QSTR_AssertionError, (mp_obj_t)&mp_type_AssertionError }, + { MP_QSTR_AttributeError, (mp_obj_t)&mp_type_AttributeError }, + { MP_QSTR_BufferError, (mp_obj_t)&mp_type_BufferError }, + { MP_QSTR_EOFError, (mp_obj_t)&mp_type_EOFError }, + { MP_QSTR_EnvironmentError, (mp_obj_t)&mp_type_EnvironmentError }, + { MP_QSTR_Exception, (mp_obj_t)&mp_type_Exception }, + { MP_QSTR_FloatingPointError, (mp_obj_t)&mp_type_FloatingPointError }, + { MP_QSTR_GeneratorExit, (mp_obj_t)&mp_type_GeneratorExit }, + { MP_QSTR_IOError, (mp_obj_t)&mp_type_IOError }, + { MP_QSTR_ImportError, (mp_obj_t)&mp_type_ImportError }, + { MP_QSTR_IndentationError, (mp_obj_t)&mp_type_IndentationError }, + { MP_QSTR_IndexError, (mp_obj_t)&mp_type_IndexError }, + { MP_QSTR_KeyError, (mp_obj_t)&mp_type_KeyError }, + { MP_QSTR_LookupError, (mp_obj_t)&mp_type_LookupError }, + { MP_QSTR_MemoryError, (mp_obj_t)&mp_type_MemoryError }, + { MP_QSTR_NameError, (mp_obj_t)&mp_type_NameError }, + { MP_QSTR_NotImplementedError, (mp_obj_t)&mp_type_NotImplementedError }, + { MP_QSTR_OSError, (mp_obj_t)&mp_type_OSError }, + { MP_QSTR_OverflowError, (mp_obj_t)&mp_type_OverflowError }, + { MP_QSTR_ReferenceError, (mp_obj_t)&mp_type_ReferenceError }, + { MP_QSTR_RuntimeError, (mp_obj_t)&mp_type_RuntimeError }, + { MP_QSTR_SyntaxError, (mp_obj_t)&mp_type_SyntaxError }, + { MP_QSTR_SystemError, (mp_obj_t)&mp_type_SystemError }, + { MP_QSTR_SystemExit, (mp_obj_t)&mp_type_SystemExit }, + { MP_QSTR_TabError, (mp_obj_t)&mp_type_TabError }, + { MP_QSTR_TypeError, (mp_obj_t)&mp_type_TypeError }, + { MP_QSTR_UnboundLocalError, (mp_obj_t)&mp_type_UnboundLocalError }, + { MP_QSTR_ValueError, (mp_obj_t)&mp_type_ValueError }, + { MP_QSTR_ZeroDivisionError, (mp_obj_t)&mp_type_ZeroDivisionError }, + { MP_QSTR_StopIteration, (mp_obj_t)&mp_type_StopIteration }, + // Somehow CPython managed to have OverflowError not inherit from ValueError ;-/ + // TODO: For MICROPY_CPYTHON_COMPAT==0 use ValueError to avoid exc proliferation + + // Extra builtins as defined by a port + MICROPY_EXTRA_BUILTINS + + { MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel +}; + +STATIC const mp_builtin_elem_t builtin_module_table[] = { + { MP_QSTR_micropython, (mp_obj_t)&mp_module_micropython }, + + { MP_QSTR_array, (mp_obj_t)&mp_module_array }, + { MP_QSTR_collections, (mp_obj_t)&mp_module_collections }, + +#if MICROPY_ENABLE_FLOAT + { MP_QSTR_math, (mp_obj_t)&mp_module_math }, +#endif + + // extra builtin modules as defined by a port + MICROPY_EXTRA_BUILTIN_MODULES + + { MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel +}; + +STATIC mp_obj_t mp_builtin_tables_lookup(const mp_builtin_elem_t *table, qstr q) { + for (; table->qstr != MP_QSTR_; table++) { + if (table->qstr == q) { + return table->elem; + } + } + return MP_OBJ_NULL; +} + +mp_obj_t mp_builtin_tables_lookup_object(qstr q) { + return mp_builtin_tables_lookup(&builtin_object_table[0], q); +} + +mp_obj_t mp_builtin_tables_lookup_module(qstr q) { + return mp_builtin_tables_lookup(&builtin_module_table[0], q); +} diff --git a/py/builtintables.h b/py/builtintables.h new file mode 100644 index 000000000..9b22b66e0 --- /dev/null +++ b/py/builtintables.h @@ -0,0 +1,2 @@ +mp_obj_t mp_builtin_tables_lookup_object(qstr q); +mp_obj_t mp_builtin_tables_lookup_module(qstr q); diff --git a/py/modarray.c b/py/modarray.c new file mode 100644 index 000000000..2544f7ed5 --- /dev/null +++ b/py/modarray.c @@ -0,0 +1,25 @@ +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "builtin.h" + +STATIC const mp_map_elem_t mp_module_array_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_array) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_array), (mp_obj_t)&mp_type_array }, +}; + +STATIC const mp_map_t mp_module_array_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(mp_module_array_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(mp_module_array_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)mp_module_array_globals_table, +}; + +const mp_obj_module_t mp_module_array = { + .base = { &mp_type_module }, + .name = MP_QSTR_array, + .globals = (mp_map_t*)&mp_module_array_globals, +}; diff --git a/py/modcollections.c b/py/modcollections.c new file mode 100644 index 000000000..ad951d5e9 --- /dev/null +++ b/py/modcollections.c @@ -0,0 +1,25 @@ +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "builtin.h" + +STATIC const mp_map_elem_t mp_module_collections_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_collections) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_namedtuple), (mp_obj_t)&mp_namedtuple_obj }, +}; + +STATIC const mp_map_t mp_module_collections_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(mp_module_collections_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(mp_module_collections_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)mp_module_collections_globals_table, +}; + +const mp_obj_module_t mp_module_collections = { + .base = { &mp_type_module }, + .name = MP_QSTR_collections, + .globals = (mp_map_t*)&mp_module_collections_globals, +}; diff --git a/py/modmath.c b/py/modmath.c new file mode 100644 index 000000000..b81482253 --- /dev/null +++ b/py/modmath.c @@ -0,0 +1,153 @@ +#include + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "builtin.h" + +#if MICROPY_ENABLE_FLOAT + +//TODO: Change macros to check for overflow and raise OverflowError or RangeError +#define MATH_FUN_1(py_name, c_name) \ + mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#define MATH_FUN_2(py_name, c_name) \ + mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj, mp_obj_t y_obj) { return mp_obj_new_float(MICROPY_FLOAT_C_FUN(c_name)(mp_obj_get_float(x_obj), mp_obj_get_float(y_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +#define MATH_FUN_BOOL1(py_name, c_name) \ + mp_obj_t mp_math_ ## py_name(mp_obj_t x_obj) { return MP_BOOL(c_name(mp_obj_get_float(x_obj))); } \ + STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name); + +STATIC const mp_obj_float_t mp_math_e_obj = {{&mp_type_float}, M_E}; +STATIC const mp_obj_float_t mp_math_pi_obj = {{&mp_type_float}, M_PI}; + +MATH_FUN_1(sqrt, sqrt) +MATH_FUN_2(pow, pow) +MATH_FUN_1(exp, exp) +MATH_FUN_1(expm1, expm1) +MATH_FUN_1(log, log) +MATH_FUN_1(log2, log2) +MATH_FUN_1(log10, log10) +MATH_FUN_1(cosh, cosh) +MATH_FUN_1(sinh, sinh) +MATH_FUN_1(tanh, tanh) +MATH_FUN_1(acosh, acosh) +MATH_FUN_1(asinh, asinh) +MATH_FUN_1(atanh, atanh) +MATH_FUN_1(cos, cos) +MATH_FUN_1(sin, sin) +MATH_FUN_1(tan, tan) +MATH_FUN_1(acos, acos) +MATH_FUN_1(asin, asin) +MATH_FUN_1(atan, atan) +MATH_FUN_2(atan2, atan2) +MATH_FUN_1(ceil, ceil) +MATH_FUN_2(copysign, copysign) +MATH_FUN_1(fabs, fabs) +MATH_FUN_1(floor, floor) //TODO: delegate to x.__floor__() if x is not a float +MATH_FUN_2(fmod, fmod) +MATH_FUN_BOOL1(isfinite, isfinite) +MATH_FUN_BOOL1(isinf, isinf) +MATH_FUN_BOOL1(isnan, isnan) +MATH_FUN_1(trunc, trunc) +MATH_FUN_2(ldexp, ldexp) +MATH_FUN_1(erf, erf) +MATH_FUN_1(erfc, erfc) +MATH_FUN_1(gamma, tgamma) +MATH_FUN_1(lgamma, lgamma) +//TODO: factorial, fsum + +// Functions that return a tuple +mp_obj_t mp_math_frexp(mp_obj_t x_obj) { + int int_exponent = 0; + mp_float_t significand = MICROPY_FLOAT_C_FUN(frexp)(mp_obj_get_float(x_obj), &int_exponent); + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_float(significand); + tuple[1] = mp_obj_new_int(int_exponent); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_frexp_obj, mp_math_frexp); + +mp_obj_t mp_math_modf(mp_obj_t x_obj) { + mp_float_t int_part = 0.0; + mp_float_t fractional_part = MICROPY_FLOAT_C_FUN(modf)(mp_obj_get_float(x_obj), &int_part); + mp_obj_t tuple[2]; + tuple[0] = mp_obj_new_float(fractional_part); + tuple[1] = mp_obj_new_float(int_part); + return mp_obj_new_tuple(2, tuple); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_modf_obj, mp_math_modf); + +// Angular conversions +mp_obj_t mp_math_radians(mp_obj_t x_obj) { + return mp_obj_new_float(mp_obj_get_float(x_obj) * M_PI / 180.0); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_radians_obj, mp_math_radians); + +mp_obj_t mp_math_degrees(mp_obj_t x_obj) { + return mp_obj_new_float(mp_obj_get_float(x_obj) * 180.0 / M_PI); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_degrees_obj, mp_math_degrees); + +STATIC const mp_map_elem_t mp_module_math_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_math) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_e), (mp_obj_t)&mp_math_e_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_pi), (mp_obj_t)&mp_math_pi_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sqrt), (mp_obj_t)&mp_math_sqrt_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_pow), (mp_obj_t)&mp_math_pow_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_exp), (mp_obj_t)&mp_math_exp_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_expm1), (mp_obj_t)&mp_math_expm1_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_log), (mp_obj_t)&mp_math_log_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_log2), (mp_obj_t)&mp_math_log2_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_log10), (mp_obj_t)&mp_math_log10_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_cosh), (mp_obj_t)&mp_math_cosh_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sinh), (mp_obj_t)&mp_math_sinh_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_tanh), (mp_obj_t)&mp_math_tanh_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_acosh), (mp_obj_t)&mp_math_acosh_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_asinh), (mp_obj_t)&mp_math_asinh_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_atanh), (mp_obj_t)&mp_math_atanh_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_cos), (mp_obj_t)&mp_math_cos_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sin), (mp_obj_t)&mp_math_sin_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_tan), (mp_obj_t)&mp_math_tan_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_acos), (mp_obj_t)&mp_math_acos_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_asin), (mp_obj_t)&mp_math_asin_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_atan), (mp_obj_t)&mp_math_atan_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_atan2), (mp_obj_t)&mp_math_atan2_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ceil), (mp_obj_t)&mp_math_ceil_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_copysign), (mp_obj_t)&mp_math_copysign_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_fabs), (mp_obj_t)&mp_math_fabs_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_floor), (mp_obj_t)&mp_math_floor_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_frexp), (mp_obj_t)&mp_math_frexp_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ldexp), (mp_obj_t)&mp_math_ldexp_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_modf), (mp_obj_t)&mp_math_modf_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_isfinite), (mp_obj_t)&mp_math_isfinite_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_isinf), (mp_obj_t)&mp_math_isinf_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_isnan), (mp_obj_t)&mp_math_isnan_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_trunc), (mp_obj_t)&mp_math_trunc_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_radians), (mp_obj_t)&mp_math_radians_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_degrees), (mp_obj_t)&mp_math_degrees_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_erf), (mp_obj_t)&mp_math_erf_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_erfc), (mp_obj_t)&mp_math_erfc_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_gamma), (mp_obj_t)&mp_math_gamma_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_lgamma), (mp_obj_t)&mp_math_lgamma_obj }, +}; + +STATIC const mp_map_t mp_module_math_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(mp_module_math_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)mp_module_math_globals_table, +}; + +const mp_obj_module_t mp_module_math = { + .base = { &mp_type_module }, + .name = MP_QSTR_math, + .globals = (mp_map_t*)&mp_module_math_globals, +}; + +#endif // MICROPY_ENABLE_FLOAT diff --git a/py/modmicropython.c b/py/modmicropython.c new file mode 100644 index 000000000..96ceb811c --- /dev/null +++ b/py/modmicropython.c @@ -0,0 +1,50 @@ +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "builtin.h" + +// Various builtins specific to MicroPython runtime, +// living in micropython module + +#if MICROPY_MEM_STATS +STATIC mp_obj_t mp_micropython_mem_total() { + return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_total_bytes_allocated()); +} + +STATIC mp_obj_t mp_micropython_mem_current() { + return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_current_bytes_allocated()); +} + +STATIC mp_obj_t mp_micropython_mem_peak() { + return MP_OBJ_NEW_SMALL_INT((machine_int_t)m_get_peak_bytes_allocated()); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_total_obj, mp_micropython_mem_total); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_current_obj, mp_micropython_mem_current); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_mem_peak_obj, mp_micropython_mem_peak); +#endif + +STATIC const mp_map_elem_t mp_module_micropython_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_micropython) }, +#if MICROPY_MEM_STATS + { MP_OBJ_NEW_QSTR(MP_QSTR_mem_total), (mp_obj_t)&mp_micropython_mem_total_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem_current), (mp_obj_t)&mp_micropython_mem_current_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem_peak), (mp_obj_t)&mp_micropython_mem_peak_obj }, +#endif +}; + +STATIC const mp_map_t mp_module_micropython_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(mp_module_micropython_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)mp_module_micropython_globals_table, +}; + +const mp_obj_module_t mp_module_micropython = { + .base = { &mp_type_module }, + .name = MP_QSTR_micropython, + .globals = (mp_map_t*)&mp_module_micropython_globals, +}; diff --git a/py/mpconfig.h b/py/mpconfig.h index 5b13c4648..09cc37913 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -125,10 +125,16 @@ typedef double mp_float_t; #define MICROPY_PATH_MAX (512) #endif -// Additional builtin function definitions - see runtime.c:builtin_table for format. +// Additional builtin function definitions - see builtintables.c:builtin_object_table for format. #ifndef MICROPY_EXTRA_BUILTINS #define MICROPY_EXTRA_BUILTINS #endif + +// Additional builtin module definitions - see builtintables.c:builtin_module_table for format. +#ifndef MICROPY_EXTRA_BUILTIN_MODULES +#define MICROPY_EXTRA_BUILTIN_MODULES +#endif + /*****************************************************************************/ /* Miscellaneous settings */ diff --git a/py/obj.h b/py/obj.h index dcb43c074..d4f9144ea 100644 --- a/py/obj.h +++ b/py/obj.h @@ -417,7 +417,7 @@ void mp_obj_slice_get(mp_obj_t self_in, machine_int_t *start, machine_int_t *sto extern const mp_obj_type_t zip_type; // array -extern const mp_obj_type_t array_type; +extern const mp_obj_type_t mp_type_array; uint mp_obj_array_len(mp_obj_t self_in); mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items); @@ -454,9 +454,6 @@ typedef struct _mp_obj_module_t { struct _mp_map_t *globals; } mp_obj_module_t; extern const mp_obj_type_t mp_type_module; -mp_obj_t mp_obj_new_module(qstr module_name); -mp_obj_t mp_obj_module_get(qstr module_name); -void mp_obj_module_register(qstr qstr, mp_obj_t module); //use for loading statically allocated modules struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in); // staticmethod and classmethod types; defined here so we can make const versions diff --git a/py/objarray.c b/py/objarray.c index ee43bde96..69f60e000 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -121,7 +121,7 @@ STATIC mp_obj_t array_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { } STATIC mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) { - assert(MP_OBJ_IS_TYPE(self_in, &array_type)); + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_array)); mp_obj_array_t *self = self_in; if (self->free == 0) { int item_sz = mp_binary_get_size(self->typecode); @@ -154,7 +154,7 @@ STATIC const mp_method_t array_type_methods[] = { { NULL, NULL }, }; -const mp_obj_type_t array_type = { +const mp_obj_type_t mp_type_array = { { &mp_type_type }, .name = MP_QSTR_array, .print = array_print, @@ -169,7 +169,7 @@ const mp_obj_type_t array_type = { STATIC mp_obj_array_t *array_new(char typecode, uint n) { mp_obj_array_t *o = m_new_obj(mp_obj_array_t); - o->base.type = &array_type; + o->base.type = &mp_type_array; o->typecode = typecode; o->free = 0; o->len = n; @@ -190,7 +190,7 @@ mp_obj_t mp_obj_new_bytearray(uint n, void *items) { // Create bytearray which references specified memory area mp_obj_t mp_obj_new_bytearray_by_ref(uint n, void *items) { mp_obj_array_t *o = m_new_obj(mp_obj_array_t); - o->base.type = &array_type; + o->base.type = &mp_type_array; o->typecode = BYTEARRAY_TYPECODE; o->free = 0; o->len = n; @@ -207,7 +207,7 @@ typedef struct _mp_obj_array_it_t { machine_uint_t cur; } mp_obj_array_it_t; -mp_obj_t array_it_iternext(mp_obj_t self_in) { +STATIC mp_obj_t array_it_iternext(mp_obj_t self_in) { mp_obj_array_it_t *self = self_in; if (self->cur < self->array->len) { return mp_binary_get_val(self->array->typecode, self->array->items, self->cur++); @@ -222,7 +222,7 @@ STATIC const mp_obj_type_t array_it_type = { .iternext = array_it_iternext, }; -mp_obj_t array_iterator_new(mp_obj_t array_in) { +STATIC mp_obj_t array_iterator_new(mp_obj_t array_in) { mp_obj_array_t *array = array_in; mp_obj_array_it_t *o = m_new_obj(mp_obj_array_it_t); o->base.type = &array_it_type; diff --git a/py/objmodule.c b/py/objmodule.c index 21fec9e86..a388ca3f3 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -6,9 +6,12 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" +#include "objmodule.h" #include "runtime.h" #include "map.h" -#include "builtin.h" +#include "builtintables.h" + +STATIC mp_map_t mp_loaded_modules_map; // TODO: expose as sys.modules STATIC void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_module_t *self = self_in; @@ -39,7 +42,7 @@ const mp_obj_type_t mp_type_module = { }; mp_obj_t mp_obj_new_module(qstr module_name) { - mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); + mp_map_elem_t *el = mp_map_lookup(&mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); // We could error out if module already exists, but let C extensions // add new members to existing modules. if (el->value != MP_OBJ_NULL) { @@ -62,9 +65,27 @@ mp_obj_t mp_obj_new_module(qstr module_name) { return o; } -mp_obj_t mp_obj_module_get(qstr module_name) { +mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module)); + mp_obj_module_t *self = self_in; + return self->globals; +} + +/******************************************************************************/ +// Global module table and related functions + +void mp_module_init(void) { + mp_map_init(&mp_loaded_modules_map, 3); +} + +void mp_module_deinit(void) { + mp_map_deinit(&mp_loaded_modules_map); +} + +// returns MP_OBJ_NULL if not found +mp_obj_t mp_module_get(qstr module_name) { // lookup module - mp_map_elem_t *el = mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); + mp_map_elem_t *el = mp_map_lookup(&mp_loaded_modules_map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); // module found, return it if (el != NULL) { @@ -72,23 +93,10 @@ mp_obj_t mp_obj_module_get(qstr module_name) { } // module not found, look for builtin module names -#if MICROPY_ENABLE_FLOAT - if (module_name == MP_QSTR_math) { - return (mp_obj_t)&mp_module_math; - } -#endif - - // no module found, return NULL object - return MP_OBJ_NULL; -} - -void mp_obj_module_register(qstr qstr, mp_obj_t module) -{ - mp_map_lookup(rt_loaded_modules_get(), MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module; + // it will return MP_OBJ_NULL if nothing found + return mp_builtin_tables_lookup_module(module_name); } -mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_module)); - mp_obj_module_t *self = self_in; - return self->globals; +void mp_module_register(qstr qstr, mp_obj_t module) { + mp_map_lookup(&mp_loaded_modules_map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = module; } diff --git a/py/objmodule.h b/py/objmodule.h new file mode 100644 index 000000000..270551da4 --- /dev/null +++ b/py/objmodule.h @@ -0,0 +1,4 @@ +void mp_module_init(void); +void mp_module_deinit(void); +mp_obj_t mp_module_get(qstr module_name); +void mp_module_register(qstr qstr, mp_obj_t module); diff --git a/py/py.mk b/py/py.mk index 624797d82..2247b6bab 100644 --- a/py/py.mk +++ b/py/py.mk @@ -74,8 +74,11 @@ PY_O_BASENAME = \ builtin.o \ builtinimport.o \ builtinevex.o \ - builtinmp.o \ - builtinmath.o \ + builtintables.o \ + modarray.o \ + modcollections.o \ + modmath.o \ + modmicropython.o \ vm.o \ showbc.o \ repl.o \ diff --git a/py/runtime.c b/py/runtime.c index 17a9e778d..0f5d1229f 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -12,12 +12,13 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" +#include "objmodule.h" #include "parsenum.h" #include "runtime0.h" #include "runtime.h" #include "map.h" #include "builtin.h" -#include "objarray.h" +#include "builtintables.h" #include "bc.h" #include "intdivmod.h" @@ -35,7 +36,6 @@ STATIC mp_map_t *map_locals; STATIC mp_map_t *map_globals; STATIC mp_map_t map_builtins; -STATIC mp_map_t map_loaded_modules; // TODO: expose as sys.modules typedef enum { MP_CODE_NONE, @@ -72,119 +72,6 @@ STATIC mp_code_t *unique_codes = NULL; FILE *fp_write_code = NULL; #endif -// builtins -// we put this table in ROM because it's always needed and takes up quite a bit of room in RAM -// in fact, it uses less ROM here in table form than the equivalent in code form initialising a dynamic mp_map_t object in RAM -// at the moment it's a linear table, but we could convert it to a const mp_map_t table with a simple preprocessing script -// if we wanted to allow dynamic modification of the builtins, we could provide an mp_map_t object which is searched before this one - -typedef struct _mp_builtin_elem_t { - qstr qstr; - mp_obj_t fun; -} mp_builtin_elem_t; - -STATIC const mp_builtin_elem_t builtin_table[] = { - // built-in core functions - { MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj }, - { MP_QSTR___import__, (mp_obj_t)&mp_builtin___import___obj }, - { MP_QSTR___repl_print__, (mp_obj_t)&mp_builtin___repl_print___obj }, - - // built-in types - { MP_QSTR_bool, (mp_obj_t)&bool_type }, - { MP_QSTR_bytes, (mp_obj_t)&bytes_type }, -#if MICROPY_ENABLE_FLOAT - { MP_QSTR_complex, (mp_obj_t)&mp_type_complex }, -#endif - { MP_QSTR_dict, (mp_obj_t)&dict_type }, - { MP_QSTR_enumerate, (mp_obj_t)&enumerate_type }, - { MP_QSTR_filter, (mp_obj_t)&filter_type }, -#if MICROPY_ENABLE_FLOAT - { MP_QSTR_float, (mp_obj_t)&mp_type_float }, -#endif - { MP_QSTR_int, (mp_obj_t)&int_type }, - { MP_QSTR_list, (mp_obj_t)&list_type }, - { MP_QSTR_map, (mp_obj_t)&map_type }, - { MP_QSTR_object, (mp_obj_t)&mp_type_object }, - { MP_QSTR_set, (mp_obj_t)&set_type }, - { MP_QSTR_str, (mp_obj_t)&str_type }, - { MP_QSTR_super, (mp_obj_t)&super_type }, - { MP_QSTR_tuple, (mp_obj_t)&tuple_type }, - { MP_QSTR_type, (mp_obj_t)&mp_type_type }, - { MP_QSTR_zip, (mp_obj_t)&zip_type }, - - { MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod }, - { MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod }, - - // built-in user functions - { MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj }, - { MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj }, - { MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj }, - { MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj }, - { MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj }, - { MP_QSTR_dir, (mp_obj_t)&mp_builtin_dir_obj }, - { MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj }, - { MP_QSTR_eval, (mp_obj_t)&mp_builtin_eval_obj }, - { MP_QSTR_exec, (mp_obj_t)&mp_builtin_exec_obj }, - { MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj }, - { MP_QSTR_id, (mp_obj_t)&mp_builtin_id_obj }, - { MP_QSTR_isinstance, (mp_obj_t)&mp_builtin_isinstance_obj }, - { MP_QSTR_issubclass, (mp_obj_t)&mp_builtin_issubclass_obj }, - { MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj }, - { MP_QSTR_len, (mp_obj_t)&mp_builtin_len_obj }, - { MP_QSTR_max, (mp_obj_t)&mp_builtin_max_obj }, - { MP_QSTR_min, (mp_obj_t)&mp_builtin_min_obj }, - { MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj }, - { MP_QSTR_ord, (mp_obj_t)&mp_builtin_ord_obj }, - { MP_QSTR_pow, (mp_obj_t)&mp_builtin_pow_obj }, - { MP_QSTR_print, (mp_obj_t)&mp_builtin_print_obj }, - { MP_QSTR_range, (mp_obj_t)&mp_builtin_range_obj }, - { MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj }, - { MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj }, - { MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj }, - { MP_QSTR_bytearray, (mp_obj_t)&mp_builtin_bytearray_obj }, - - // built-in exceptions - { MP_QSTR_BaseException, (mp_obj_t)&mp_type_BaseException }, - { MP_QSTR_ArithmeticError, (mp_obj_t)&mp_type_ArithmeticError }, - { MP_QSTR_AssertionError, (mp_obj_t)&mp_type_AssertionError }, - { MP_QSTR_AttributeError, (mp_obj_t)&mp_type_AttributeError }, - { MP_QSTR_BufferError, (mp_obj_t)&mp_type_BufferError }, - { MP_QSTR_EOFError, (mp_obj_t)&mp_type_EOFError }, - { MP_QSTR_EnvironmentError, (mp_obj_t)&mp_type_EnvironmentError }, - { MP_QSTR_Exception, (mp_obj_t)&mp_type_Exception }, - { MP_QSTR_FloatingPointError, (mp_obj_t)&mp_type_FloatingPointError }, - { MP_QSTR_GeneratorExit, (mp_obj_t)&mp_type_GeneratorExit }, - { MP_QSTR_IOError, (mp_obj_t)&mp_type_IOError }, - { MP_QSTR_ImportError, (mp_obj_t)&mp_type_ImportError }, - { MP_QSTR_IndentationError, (mp_obj_t)&mp_type_IndentationError }, - { MP_QSTR_IndexError, (mp_obj_t)&mp_type_IndexError }, - { MP_QSTR_KeyError, (mp_obj_t)&mp_type_KeyError }, - { MP_QSTR_LookupError, (mp_obj_t)&mp_type_LookupError }, - { MP_QSTR_MemoryError, (mp_obj_t)&mp_type_MemoryError }, - { MP_QSTR_NameError, (mp_obj_t)&mp_type_NameError }, - { MP_QSTR_NotImplementedError, (mp_obj_t)&mp_type_NotImplementedError }, - { MP_QSTR_OSError, (mp_obj_t)&mp_type_OSError }, - { MP_QSTR_OverflowError, (mp_obj_t)&mp_type_OverflowError }, - { MP_QSTR_ReferenceError, (mp_obj_t)&mp_type_ReferenceError }, - { MP_QSTR_RuntimeError, (mp_obj_t)&mp_type_RuntimeError }, - { MP_QSTR_SyntaxError, (mp_obj_t)&mp_type_SyntaxError }, - { MP_QSTR_SystemError, (mp_obj_t)&mp_type_SystemError }, - { MP_QSTR_SystemExit, (mp_obj_t)&mp_type_SystemExit }, - { MP_QSTR_TabError, (mp_obj_t)&mp_type_TabError }, - { MP_QSTR_TypeError, (mp_obj_t)&mp_type_TypeError }, - { MP_QSTR_UnboundLocalError, (mp_obj_t)&mp_type_UnboundLocalError }, - { MP_QSTR_ValueError, (mp_obj_t)&mp_type_ValueError }, - { MP_QSTR_ZeroDivisionError, (mp_obj_t)&mp_type_ZeroDivisionError }, - { MP_QSTR_StopIteration, (mp_obj_t)&mp_type_StopIteration }, - // Somehow CPython managed to have OverflowError not inherit from ValueError ;-/ - // TODO: For MICROPY_CPYTHON_COMPAT==0 use ValueError to avoid exc proliferation - - // Extra builtins as defined by a port - MICROPY_EXTRA_BUILTINS - - { MP_QSTR_, MP_OBJ_NULL }, // end of list sentinel -}; - // a good optimising compiler will inline this if necessary STATIC void mp_map_add_qstr(mp_map_t *map, qstr qstr, mp_obj_t value) { mp_map_lookup(map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; @@ -193,23 +80,17 @@ STATIC void mp_map_add_qstr(mp_map_t *map, qstr qstr, mp_obj_t value) { void rt_init(void) { // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New()) map_locals = map_globals = mp_map_new(1); - mp_map_add_qstr(map_globals, MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR___main__)); // init built-in hash table mp_map_init(&map_builtins, 3); - // init loaded modules table - mp_map_init(&map_loaded_modules, 3); + // init global module stuff + mp_module_init(); - // built-in objects + // add some builtins that can't be done in ROM + mp_map_add_qstr(map_globals, MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR___main__)); mp_map_add_qstr(&map_builtins, MP_QSTR_Ellipsis, mp_const_ellipsis); - mp_obj_t m_array = mp_obj_new_module(MP_QSTR_array); - rt_store_attr(m_array, MP_QSTR_array, (mp_obj_t)&array_type); - - mp_obj_t m_collections = mp_obj_new_module(MP_QSTR_collections); - rt_store_attr(m_collections, MP_QSTR_namedtuple, (mp_obj_t)&mp_namedtuple_obj); - #if MICROPY_CPYTHON_COMPAT // Precreate sys module, so "import sys" didn't throw exceptions. mp_obj_t m_sys = mp_obj_new_module(MP_QSTR_sys); @@ -221,10 +102,6 @@ void rt_init(void) { //sys_path = mp_obj_new_list(0, NULL); //rt_store_attr(m_sys, MP_QSTR_path, sys_path); - // we pre-import the micropython module - // probably shouldn't do this, so we are compatible with CPython - rt_store_name(MP_QSTR_micropython, (mp_obj_t)&mp_module_micropython); - // TODO: wastes one mp_code_t structure in mem next_unique_code_id = 1; // 0 indicates "no code" unique_codes_alloc = 0; @@ -238,8 +115,8 @@ void rt_init(void) { void rt_deinit(void) { m_del(mp_code_t, unique_codes, unique_codes_alloc); mp_map_free(map_globals); - mp_map_deinit(&map_loaded_modules); mp_map_deinit(&map_builtins); + mp_module_deinit(); #ifdef WRITE_CODE if (fp_write_code != NULL) { fclose(fp_write_code); @@ -428,10 +305,9 @@ mp_obj_t rt_load_global(qstr qstr) { if (elem == NULL) { elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); if (elem == NULL) { - for (const mp_builtin_elem_t *e = &builtin_table[0]; e->qstr != MP_QSTR_; e++) { - if (e->qstr == qstr) { - return e->fun; - } + mp_obj_t o = mp_builtin_tables_lookup_object(qstr); + if (o != MP_OBJ_NULL) { + return o; } nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_NameError, "name '%s' is not defined", qstr_str(qstr))); } @@ -441,10 +317,13 @@ mp_obj_t rt_load_global(qstr qstr) { mp_obj_t rt_load_build_class(void) { DEBUG_OP_printf("load_build_class\n"); + // lookup __build_class__ in dynamic table of builtins first mp_map_elem_t *elem = mp_map_lookup(&map_builtins, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP); if (elem != NULL) { + // found user-defined __build_class__, return it return elem->value; } else { + // no user-defined __build_class__, return builtin one return (mp_obj_t)&mp_builtin___build_class___obj; } } @@ -1141,10 +1020,6 @@ void rt_globals_set(mp_map_t *m) { map_globals = m; } -mp_map_t *rt_loaded_modules_get(void) { - return &map_loaded_modules; -} - // these must correspond to the respective enum void *const rt_fun_table[RT_F_NUMBER_OF] = { rt_load_const_dec, diff --git a/stm/main.c b/stm/main.c index 6ad311127..44be4d348 100644 --- a/stm/main.c +++ b/stm/main.c @@ -24,6 +24,7 @@ #include "lexerfatfs.h" #include "parse.h" #include "obj.h" +#include "objmodule.h" #include "parsehelper.h" #include "compile.h" #include "runtime0.h" @@ -273,7 +274,7 @@ soft_reset: rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open)); // load the pyb module - mp_obj_module_register(MP_QSTR_pyb, (mp_obj_t)&pyb_module); + mp_module_register(MP_QSTR_pyb, (mp_obj_t)&pyb_module); // check if user switch held (initiates reset of filesystem) bool reset_filesystem = false; diff --git a/stm/pybmodule.c b/stm/pybmodule.c index ed705af73..fde61b513 100644 --- a/stm/pybmodule.c +++ b/stm/pybmodule.c @@ -181,7 +181,8 @@ STATIC mp_obj_t pyb_standby(void) { MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby); STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) { - mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4); + mp_obj_t *items; + mp_obj_get_array_fixed_n(arg, 4, &items); uint8_t data[4]; data[0] = mp_obj_get_int(items[0]); data[1] = mp_obj_get_int(items[1]); diff --git a/stmhal/Makefile b/stmhal/Makefile index 7896849c6..1c9ea5531 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -74,9 +74,9 @@ SRC_C = \ pyexec.c \ help.c \ input.c \ - pybmodule.c \ - osmodule.c \ - timemodule.c \ + modpyb.c \ + modos.c \ + modtime.c \ import.c \ lexerfatfs.c \ gpio.c \ diff --git a/stmhal/main.c b/stmhal/main.c index a231ca250..ab96dcdef 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -21,9 +21,6 @@ #include "gc.h" #include "gccollect.h" #include "pyexec.h" -#include "pybmodule.h" -#include "osmodule.h" -#include "timemodule.h" #include "usart.h" #include "led.h" #include "exti.h" @@ -110,6 +107,7 @@ static const char fresh_boot_py[] = "# boot.py -- run on boot-up\n" "# can run arbitrary Python, but best to keep it minimal\n" "\n" +"import pyb\n" "pyb.source_dir('/src')\n" "pyb.main('main.py')\n" "#pyb.usb_usr('VCP')\n" @@ -246,15 +244,6 @@ soft_reset: pin_map_init(); - // we pre-import the pyb module - // probably shouldn't do this, so we are compatible with CPython - rt_store_name(MP_QSTR_pyb, (mp_obj_t)&pyb_module); - - // pre-import the os and time modules - // TODO don't do this! (need a way of registering builtin modules...) - rt_store_name(MP_QSTR_os, (mp_obj_t)&os_module); - rt_store_name(MP_QSTR_time, (mp_obj_t)&time_module); - // check if user switch held (initiates reset of filesystem) bool reset_filesystem = false; #if MICROPY_HW_HAS_SWITCH diff --git a/stmhal/modos.c b/stmhal/modos.c new file mode 100644 index 000000000..0ec9fcbb9 --- /dev/null +++ b/stmhal/modos.c @@ -0,0 +1,178 @@ +#include + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "systick.h" +#include "rng.h" +#include "storage.h" +#include "ff.h" +#include "modos.h" + +#if _USE_LFN +static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */ +#endif + +STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) { + const mp_obj_type_t *local_str_type = &str_type; + const char *path; + if (n_args == 1) { + if (mp_obj_get_type(args[0]) == &bytes_type) { + local_str_type = &bytes_type; + } + path = mp_obj_str_get_str(args[0]); + } else { + path = "0:"; + } + + FRESULT res; + FILINFO fno; + DIR dir; +#if _USE_LFN + fno.lfname = lfn; + fno.lfsize = sizeof lfn; +#endif + + res = f_opendir(&dir, path); /* Open the directory */ + if (res != FR_OK) { + // TODO should be mp_type_FileNotFoundError + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path)); + } + + mp_obj_t dir_list = mp_obj_new_list(0, NULL); + + uint path_len = strlen(path); + if (path[path_len - 1] == '/') { + path_len--; + } + + for (;;) { + res = f_readdir(&dir, &fno); /* Read a directory item */ + if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ + if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */ + if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */ + +#if _USE_LFN + char *fn = *fno.lfname ? fno.lfname : fno.fname; +#else + char *fn = fno.fname; +#endif + + if (fno.fattrib & AM_DIR) { /* It is a directory */ + } else { /* It is a file. */ + } + + // make a string object for this entry + byte *data; + uint fn_len = strlen(fn); + mp_obj_t entry_o = mp_obj_str_builder_start(local_str_type, path_len + 1 + fn_len, &data); + memcpy(data, path, path_len); + data[path_len] = '/'; + memcpy(data + path_len + 1, fn, fn_len); + + // add the entry to the list + mp_obj_list_append(dir_list, mp_obj_str_builder_end(entry_o)); + } + + f_closedir(&dir); + + return dir_list; +} + +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir); + +STATIC mp_obj_t os_mkdir(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + FRESULT res = f_mkdir(path); + switch (res) { + case FR_OK: + return mp_const_none; + case FR_EXIST: + // TODO should be FileExistsError + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path)); + default: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path)); + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir); + +STATIC mp_obj_t os_remove(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + // TODO check that path is actually a file before trying to unlink it + FRESULT res = f_unlink(path); + switch (res) { + case FR_OK: + return mp_const_none; + default: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path)); + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove); + +STATIC mp_obj_t os_rmdir(mp_obj_t path_o) { + const char *path = mp_obj_str_get_str(path_o); + // TODO check that path is actually a directory before trying to unlink it + FRESULT res = f_unlink(path); + switch (res) { + case FR_OK: + return mp_const_none; + default: + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path)); + } +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); + +STATIC mp_obj_t os_sync(void) { + storage_flush(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); + +STATIC mp_obj_t os_urandom(mp_obj_t num) { + machine_int_t n = mp_obj_get_int(num); + byte *data; + mp_obj_t o = mp_obj_str_builder_start(&bytes_type, n, &data); + for (int i = 0; i < n; i++) { + data[i] = rng_get(); + } + return mp_obj_str_builder_end(o); +} + +MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); + +STATIC const mp_map_elem_t os_module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_os) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove + + { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj }, +}; + +STATIC const mp_map_t os_module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)os_module_globals_table, +}; + +const mp_obj_module_t os_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_os, + .globals = (mp_map_t*)&os_module_globals, +}; diff --git a/stmhal/modos.h b/stmhal/modos.h new file mode 100644 index 000000000..e3c13f756 --- /dev/null +++ b/stmhal/modos.h @@ -0,0 +1 @@ +extern const mp_obj_module_t os_module; diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c new file mode 100644 index 000000000..c7bab3666 --- /dev/null +++ b/stmhal/modpyb.c @@ -0,0 +1,308 @@ +#include +#include + +#include + +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "gc.h" +#include "gccollect.h" +#include "systick.h" +#include "pyexec.h" +#include "led.h" +#include "gpio.h" +#include "pin.h" +#include "exti.h" +#include "usrsw.h" +#include "rng.h" +#include "rtc.h" +#include "usart.h" +#include "adc.h" +#include "storage.h" +#include "sdcard.h" +#include "accel.h" +#include "servo.h" +#include "dac.h" +#if 0 +#include "usb.h" +#include "i2c.h" +#endif +#include "modpyb.h" +#include "ff.h" + +// get lots of info about the board +STATIC mp_obj_t pyb_info(void) { + // get and print unique id; 96 bits + { + byte *id = (byte*)0x1fff7a10; + printf("ID=%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x\n", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11]); + } + + // get and print clock speeds + // SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz + { + printf("S=%lu\nH=%lu\nP1=%lu\nP2=%lu\n", + HAL_RCC_GetSysClockFreq(), + HAL_RCC_GetHCLKFreq(), + HAL_RCC_GetPCLK1Freq(), + HAL_RCC_GetPCLK2Freq()); + } + + // to print info about memory + { + printf("_etext=%p\n", &_etext); + printf("_sidata=%p\n", &_sidata); + printf("_sdata=%p\n", &_sdata); + printf("_edata=%p\n", &_edata); + printf("_sbss=%p\n", &_sbss); + printf("_ebss=%p\n", &_ebss); + printf("_estack=%p\n", &_estack); + printf("_ram_start=%p\n", &_ram_start); + printf("_heap_start=%p\n", &_heap_start); + printf("_heap_end=%p\n", &_heap_end); + printf("_ram_end=%p\n", &_ram_end); + } + + // qstr info + { + uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes; + qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); + printf("qstr:\n n_pool=%u\n n_qstr=%u\n n_str_data_bytes=%u\n n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes); + } + + // GC info + { + gc_info_t info; + gc_info(&info); + printf("GC:\n"); + printf(" %lu total\n", info.total); + printf(" %lu : %lu\n", info.used, info.free); + printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block); + } + + // free space on flash + { + DWORD nclst; + FATFS *fatfs; + f_getfree("0:", &nclst, &fatfs); + printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512)); + } + + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_info_obj, pyb_info); + +// sync all file systems +STATIC mp_obj_t pyb_sync(void) { + storage_flush(); + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_sync_obj, pyb_sync); + +STATIC mp_obj_t pyb_millis(void) { + return mp_obj_new_int(HAL_GetTick()); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis); + +STATIC mp_obj_t pyb_delay(mp_obj_t count) { + HAL_Delay(mp_obj_get_int(count)); + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay); + +STATIC mp_obj_t pyb_udelay(mp_obj_t usec) { + uint32_t count = 0; + const uint32_t utime = (168 * mp_obj_get_int(usec) / 5); + for (;;) { + if (++count > utime) { + return mp_const_none; + } + } +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay); + +#if 0 +STATIC void SYSCLKConfig_STOP(void) { + /* After wake-up from STOP reconfigure the system clock */ + /* Enable HSE */ + RCC_HSEConfig(RCC_HSE_ON); + + /* Wait till HSE is ready */ + while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) { + } + + /* Enable PLL */ + RCC_PLLCmd(ENABLE); + + /* Wait till PLL is ready */ + while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { + } + + /* Select PLL as system clock source */ + RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); + + /* Wait till PLL is used as system clock source */ + while (RCC_GetSYSCLKSource() != 0x08) { + } +} +#endif + +STATIC mp_obj_t pyb_stop(void) { +#if 0 + PWR_EnterSTANDBYMode(); + //PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this + + /* Enter Stop Mode */ + PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); + + /* Configures system clock after wake-up from STOP: enable HSE, PLL and select + * PLL as system clock source (HSE and PLL are disabled in STOP mode) */ + SYSCLKConfig_STOP(); + + //PWR_FlashPowerDownCmd(DISABLE); +#endif + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_stop_obj, pyb_stop); + +STATIC mp_obj_t pyb_standby(void) { +#if 0 + PWR_EnterSTANDBYMode(); +#endif + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby); + +STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) { +#if 0 + mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4); + uint8_t data[4]; + data[0] = mp_obj_get_int(items[0]); + data[1] = mp_obj_get_int(items[1]); + data[2] = mp_obj_get_int(items[2]); + data[3] = mp_obj_get_int(items[3]); + usb_hid_send_report(data); +#endif + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report); + +#if 0 +MP_DEFINE_CONST_FUN_OBJ_2(pyb_I2C_obj, pyb_I2C); // TODO put this in i2c.c +#endif + +extern int stdin_rx_chr(void); + +STATIC mp_obj_t pyb_input(void ) { + return mp_obj_new_int(stdin_rx_chr()); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_input_obj, pyb_input); + +MP_DECLARE_CONST_FUN_OBJ(pyb_source_dir_obj); // defined in main.c +MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c + +STATIC const mp_map_elem_t pyb_module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_gc), (mp_obj_t)&pyb_gc_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj }, + +#if MICROPY_HW_ENABLE_RNG + { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj }, +#endif + +#if MICROPY_HW_ENABLE_RTC + { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&pyb_rtc_read_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_rtc_info), (mp_obj_t)&pyb_rtc_info_obj }, +#endif + +#if MICROPY_HW_ENABLE_SERVO + { MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_servo_type }, +#endif + +#if MICROPY_HW_HAS_SWITCH + { MP_OBJ_NEW_QSTR(MP_QSTR_switch), (mp_obj_t)&pyb_switch_obj }, +#endif + +#if MICROPY_HW_HAS_SDCARD + { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj }, +#endif + +#if MICROPY_HW_HAS_MMA7660 + { MP_OBJ_NEW_QSTR(MP_QSTR_Accel), (mp_obj_t)&pyb_accel_type }, +#endif + +#if 0 + { MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj }, +#endif + { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_led_type }, +#if 0 + { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_I2C_obj }, +#endif + { MP_OBJ_NEW_QSTR(MP_QSTR_Usart), (mp_obj_t)&pyb_Usart_obj }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ADC_all), (mp_obj_t)&pyb_ADC_all_obj }, + +#if MICROPY_HW_ENABLE_DAC + { MP_OBJ_NEW_QSTR(MP_QSTR_DAC), (mp_obj_t)&pyb_dac_type }, +#endif + + // input + { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&pyb_input_obj }, + + // pin mapper + { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_map_obj }, + + // GPIO bindings + { MP_OBJ_NEW_QSTR(MP_QSTR_gpio), (mp_obj_t)&pyb_gpio_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_gpio_in), (mp_obj_t)&pyb_gpio_input_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_gpio_out), (mp_obj_t)&pyb_gpio_output_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PUSH_PULL), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) }, + + // EXTI bindings + { MP_OBJ_NEW_QSTR(MP_QSTR_Exti), (mp_obj_t)&exti_obj_type }, +}; + +STATIC const mp_map_t pyb_module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(pyb_module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(pyb_module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)pyb_module_globals_table, +}; + +const mp_obj_module_t pyb_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_pyb, + .globals = (mp_map_t*)&pyb_module_globals, +}; diff --git a/stmhal/modpyb.h b/stmhal/modpyb.h new file mode 100644 index 000000000..955aaefe3 --- /dev/null +++ b/stmhal/modpyb.h @@ -0,0 +1 @@ +extern const mp_obj_module_t pyb_module; diff --git a/stmhal/modtime.c b/stmhal/modtime.c new file mode 100644 index 000000000..4786c85c7 --- /dev/null +++ b/stmhal/modtime.c @@ -0,0 +1,44 @@ +#include + +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "map.h" +#include "modtime.h" + +STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { +#if MICROPY_ENABLE_FLOAT + if (MP_OBJ_IS_INT(seconds_o)) { +#endif + HAL_Delay(1000 * mp_obj_get_int(seconds_o)); +#if MICROPY_ENABLE_FLOAT + } else { + HAL_Delay((uint32_t)(1000 * mp_obj_get_float(seconds_o))); + } +#endif + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); + +STATIC const mp_map_elem_t time_module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_time) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj }, +}; + +STATIC const mp_map_t time_module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(time_module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(time_module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)time_module_globals_table, +}; + +const mp_obj_module_t time_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_time, + .globals = (mp_map_t*)&time_module_globals, +}; diff --git a/stmhal/modtime.h b/stmhal/modtime.h new file mode 100644 index 000000000..70e35b1fd --- /dev/null +++ b/stmhal/modtime.h @@ -0,0 +1 @@ +extern const mp_obj_module_t time_module; diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h index edaee6315..b187c43bb 100644 --- a/stmhal/mpconfigport.h +++ b/stmhal/mpconfigport.h @@ -27,6 +27,15 @@ extern const struct _mp_obj_fun_native_t mp_builtin_open_obj; { MP_QSTR_input, (mp_obj_t)&mp_builtin_input_obj }, \ { MP_QSTR_open, (mp_obj_t)&mp_builtin_open_obj }, +// extra built in modules to add to the list of known ones +extern const struct _mp_obj_module_t os_module; +extern const struct _mp_obj_module_t pyb_module; +extern const struct _mp_obj_module_t time_module; +#define MICROPY_EXTRA_BUILTIN_MODULES \ + { MP_QSTR_os, (mp_obj_t)&os_module }, \ + { MP_QSTR_pyb, (mp_obj_t)&pyb_module }, \ + { MP_QSTR_time, (mp_obj_t)&time_module }, \ + // type definitions for the specific machine #define BYTES_PER_WORD (4) diff --git a/stmhal/osmodule.c b/stmhal/osmodule.c deleted file mode 100644 index 7f32fe674..000000000 --- a/stmhal/osmodule.c +++ /dev/null @@ -1,178 +0,0 @@ -#include - -#include "nlr.h" -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "obj.h" -#include "map.h" -#include "systick.h" -#include "rng.h" -#include "storage.h" -#include "ff.h" -#include "osmodule.h" - -#if _USE_LFN -static char lfn[_MAX_LFN + 1]; /* Buffer to store the LFN */ -#endif - -STATIC mp_obj_t os_listdir(uint n_args, const mp_obj_t *args) { - const mp_obj_type_t *local_str_type = &str_type; - const char *path; - if (n_args == 1) { - if (mp_obj_get_type(args[0]) == &bytes_type) { - local_str_type = &bytes_type; - } - path = mp_obj_str_get_str(args[0]); - } else { - path = "0:"; - } - - FRESULT res; - FILINFO fno; - DIR dir; -#if _USE_LFN - fno.lfname = lfn; - fno.lfsize = sizeof lfn; -#endif - - res = f_opendir(&dir, path); /* Open the directory */ - if (res != FR_OK) { - // TODO should be mp_type_FileNotFoundError - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "No such file or directory: '%s'", path)); - } - - mp_obj_t dir_list = mp_obj_new_list(0, NULL); - - uint path_len = strlen(path); - if (path[path_len - 1] == '/') { - path_len--; - } - - for (;;) { - res = f_readdir(&dir, &fno); /* Read a directory item */ - if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ - if (fno.fname[0] == '.' && fno.fname[1] == 0) continue; /* Ignore . entry */ - if (fno.fname[0] == '.' && fno.fname[1] == '.' && fno.fname[2] == 0) continue; /* Ignore .. entry */ - -#if _USE_LFN - char *fn = *fno.lfname ? fno.lfname : fno.fname; -#else - char *fn = fno.fname; -#endif - - if (fno.fattrib & AM_DIR) { /* It is a directory */ - } else { /* It is a file. */ - } - - // make a string object for this entry - byte *data; - uint fn_len = strlen(fn); - mp_obj_t entry_o = mp_obj_str_builder_start(local_str_type, path_len + 1 + fn_len, &data); - memcpy(data, path, path_len); - data[path_len] = '/'; - memcpy(data + path_len + 1, fn, fn_len); - - // add the entry to the list - mp_obj_list_append(dir_list, mp_obj_str_builder_end(entry_o)); - } - - f_closedir(&dir); - - return dir_list; -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir); - -STATIC mp_obj_t os_mkdir(mp_obj_t path_o) { - const char *path = mp_obj_str_get_str(path_o); - FRESULT res = f_mkdir(path); - switch (res) { - case FR_OK: - return mp_const_none; - case FR_EXIST: - // TODO should be FileExistsError - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "File exists: '%s'", path)); - default: - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error creating directory '%s'", path)); - } -} - -MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir); - -STATIC mp_obj_t os_remove(mp_obj_t path_o) { - const char *path = mp_obj_str_get_str(path_o); - // TODO check that path is actually a file before trying to unlink it - FRESULT res = f_unlink(path); - switch (res) { - case FR_OK: - return mp_const_none; - default: - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing file '%s'", path)); - } -} - -MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove); - -STATIC mp_obj_t os_rmdir(mp_obj_t path_o) { - const char *path = mp_obj_str_get_str(path_o); - // TODO check that path is actually a directory before trying to unlink it - FRESULT res = f_unlink(path); - switch (res) { - case FR_OK: - return mp_const_none; - default: - nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_OSError, "Error removing directory '%s'", path)); - } -} - -MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); - -STATIC mp_obj_t os_sync(void) { - storage_flush(); - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); - -STATIC mp_obj_t os_urandom(mp_obj_t num) { - machine_int_t n = mp_obj_get_int(num); - byte *data; - mp_obj_t o = mp_obj_str_builder_start(&bytes_type, n, &data); - for (int i = 0; i < n; i++) { - data[i] = rng_get(); - } - return mp_obj_str_builder_end(o); -} - -MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); - -STATIC const mp_map_elem_t os_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_os) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_listdir), (mp_obj_t)&os_listdir_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mkdir), (mp_obj_t)&os_mkdir_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_remove), (mp_obj_t)&os_remove_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_rmdir), (mp_obj_t)&os_rmdir_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_unlink), (mp_obj_t)&os_remove_obj }, // unlink aliases to remove - - { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&os_sync_obj }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_urandom), (mp_obj_t)&os_urandom_obj }, -}; - -STATIC const mp_map_t os_module_globals = { - .all_keys_are_qstrs = 1, - .table_is_fixed_array = 1, - .used = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t), - .alloc = sizeof(os_module_globals_table) / sizeof(mp_map_elem_t), - .table = (mp_map_elem_t*)os_module_globals_table, -}; - -const mp_obj_module_t os_module = { - .base = { &mp_type_module }, - .name = MP_QSTR_os, - .globals = (mp_map_t*)&os_module_globals, -}; diff --git a/stmhal/osmodule.h b/stmhal/osmodule.h deleted file mode 100644 index e3c13f756..000000000 --- a/stmhal/osmodule.h +++ /dev/null @@ -1 +0,0 @@ -extern const mp_obj_module_t os_module; diff --git a/stmhal/pybmodule.c b/stmhal/pybmodule.c deleted file mode 100644 index 5e735903e..000000000 --- a/stmhal/pybmodule.c +++ /dev/null @@ -1,308 +0,0 @@ -#include -#include - -#include - -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "obj.h" -#include "map.h" -#include "gc.h" -#include "gccollect.h" -#include "systick.h" -#include "pyexec.h" -#include "led.h" -#include "gpio.h" -#include "pin.h" -#include "exti.h" -#include "usrsw.h" -#include "rng.h" -#include "rtc.h" -#include "usart.h" -#include "adc.h" -#include "storage.h" -#include "sdcard.h" -#include "accel.h" -#include "servo.h" -#include "dac.h" -#if 0 -#include "usb.h" -#include "i2c.h" -#endif -#include "pybmodule.h" -#include "ff.h" - -// get lots of info about the board -STATIC mp_obj_t pyb_info(void) { - // get and print unique id; 96 bits - { - byte *id = (byte*)0x1fff7a10; - printf("ID=%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x\n", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11]); - } - - // get and print clock speeds - // SYSCLK=168MHz, HCLK=168MHz, PCLK1=42MHz, PCLK2=84MHz - { - printf("S=%lu\nH=%lu\nP1=%lu\nP2=%lu\n", - HAL_RCC_GetSysClockFreq(), - HAL_RCC_GetHCLKFreq(), - HAL_RCC_GetPCLK1Freq(), - HAL_RCC_GetPCLK2Freq()); - } - - // to print info about memory - { - printf("_etext=%p\n", &_etext); - printf("_sidata=%p\n", &_sidata); - printf("_sdata=%p\n", &_sdata); - printf("_edata=%p\n", &_edata); - printf("_sbss=%p\n", &_sbss); - printf("_ebss=%p\n", &_ebss); - printf("_estack=%p\n", &_estack); - printf("_ram_start=%p\n", &_ram_start); - printf("_heap_start=%p\n", &_heap_start); - printf("_heap_end=%p\n", &_heap_end); - printf("_ram_end=%p\n", &_ram_end); - } - - // qstr info - { - uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes; - qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); - printf("qstr:\n n_pool=%u\n n_qstr=%u\n n_str_data_bytes=%u\n n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes); - } - - // GC info - { - gc_info_t info; - gc_info(&info); - printf("GC:\n"); - printf(" %lu total\n", info.total); - printf(" %lu : %lu\n", info.used, info.free); - printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block); - } - - // free space on flash - { - DWORD nclst; - FATFS *fatfs; - f_getfree("0:", &nclst, &fatfs); - printf("LFS free: %u bytes\n", (uint)(nclst * fatfs->csize * 512)); - } - - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_info_obj, pyb_info); - -// sync all file systems -STATIC mp_obj_t pyb_sync(void) { - storage_flush(); - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_sync_obj, pyb_sync); - -STATIC mp_obj_t pyb_millis(void) { - return mp_obj_new_int(HAL_GetTick()); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis); - -STATIC mp_obj_t pyb_delay(mp_obj_t count) { - HAL_Delay(mp_obj_get_int(count)); - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay); - -STATIC mp_obj_t pyb_udelay(mp_obj_t usec) { - uint32_t count = 0; - const uint32_t utime = (168 * mp_obj_get_int(usec) / 5); - for (;;) { - if (++count > utime) { - return mp_const_none; - } - } -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay); - -#if 0 -STATIC void SYSCLKConfig_STOP(void) { - /* After wake-up from STOP reconfigure the system clock */ - /* Enable HSE */ - RCC_HSEConfig(RCC_HSE_ON); - - /* Wait till HSE is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) { - } - - /* Enable PLL */ - RCC_PLLCmd(ENABLE); - - /* Wait till PLL is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { - } - - /* Select PLL as system clock source */ - RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); - - /* Wait till PLL is used as system clock source */ - while (RCC_GetSYSCLKSource() != 0x08) { - } -} -#endif - -STATIC mp_obj_t pyb_stop(void) { -#if 0 - PWR_EnterSTANDBYMode(); - //PWR_FlashPowerDownCmd(ENABLE); don't know what the logic is with this - - /* Enter Stop Mode */ - PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); - - /* Configures system clock after wake-up from STOP: enable HSE, PLL and select - * PLL as system clock source (HSE and PLL are disabled in STOP mode) */ - SYSCLKConfig_STOP(); - - //PWR_FlashPowerDownCmd(DISABLE); -#endif - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_0(pyb_stop_obj, pyb_stop); - -STATIC mp_obj_t pyb_standby(void) { -#if 0 - PWR_EnterSTANDBYMode(); -#endif - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby); - -STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) { -#if 0 - mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4); - uint8_t data[4]; - data[0] = mp_obj_get_int(items[0]); - data[1] = mp_obj_get_int(items[1]); - data[2] = mp_obj_get_int(items[2]); - data[3] = mp_obj_get_int(items[3]); - usb_hid_send_report(data); -#endif - return mp_const_none; -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report); - -#if 0 -MP_DEFINE_CONST_FUN_OBJ_2(pyb_I2C_obj, pyb_I2C); // TODO put this in i2c.c -#endif - -extern int stdin_rx_chr(void); - -STATIC mp_obj_t pyb_input(void ) { - return mp_obj_new_int(stdin_rx_chr()); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_input_obj, pyb_input); - -MP_DECLARE_CONST_FUN_OBJ(pyb_source_dir_obj); // defined in main.c -MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c - -STATIC const mp_map_elem_t pyb_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gc), (mp_obj_t)&pyb_gc_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj }, - -#if MICROPY_HW_ENABLE_RNG - { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj }, -#endif - -#if MICROPY_HW_ENABLE_RTC - { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&pyb_rtc_read_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_rtc_info), (mp_obj_t)&pyb_rtc_info_obj }, -#endif - -#if MICROPY_HW_ENABLE_SERVO - { MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_servo_type }, -#endif - -#if MICROPY_HW_HAS_SWITCH - { MP_OBJ_NEW_QSTR(MP_QSTR_switch), (mp_obj_t)&pyb_switch_obj }, -#endif - -#if MICROPY_HW_HAS_SDCARD - { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj }, -#endif - -#if MICROPY_HW_HAS_MMA7660 - { MP_OBJ_NEW_QSTR(MP_QSTR_Accel), (mp_obj_t)&pyb_accel_type }, -#endif - -#if 0 - { MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj }, -#endif - { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_led_type }, -#if 0 - { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_I2C_obj }, -#endif - { MP_OBJ_NEW_QSTR(MP_QSTR_Usart), (mp_obj_t)&pyb_Usart_obj }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ADC_all), (mp_obj_t)&pyb_ADC_all_obj }, - -#if MICROPY_HW_ENABLE_DAC - { MP_OBJ_NEW_QSTR(MP_QSTR_DAC), (mp_obj_t)&pyb_dac_type }, -#endif - - // input - { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&pyb_input_obj }, - - // pin mapper - { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_map_obj }, - - // GPIO bindings - { MP_OBJ_NEW_QSTR(MP_QSTR_gpio), (mp_obj_t)&pyb_gpio_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gpio_in), (mp_obj_t)&pyb_gpio_input_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gpio_out), (mp_obj_t)&pyb_gpio_output_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PUSH_PULL), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) }, - - // EXTI bindings - { MP_OBJ_NEW_QSTR(MP_QSTR_Exti), (mp_obj_t)&exti_obj_type }, -}; - -STATIC const mp_map_t pyb_module_globals = { - .all_keys_are_qstrs = 1, - .table_is_fixed_array = 1, - .used = sizeof(pyb_module_globals_table) / sizeof(mp_map_elem_t), - .alloc = sizeof(pyb_module_globals_table) / sizeof(mp_map_elem_t), - .table = (mp_map_elem_t*)pyb_module_globals_table, -}; - -const mp_obj_module_t pyb_module = { - .base = { &mp_type_module }, - .name = MP_QSTR_pyb, - .globals = (mp_map_t*)&pyb_module_globals, -}; diff --git a/stmhal/pybmodule.h b/stmhal/pybmodule.h deleted file mode 100644 index 955aaefe3..000000000 --- a/stmhal/pybmodule.h +++ /dev/null @@ -1 +0,0 @@ -extern const mp_obj_module_t pyb_module; diff --git a/stmhal/timemodule.c b/stmhal/timemodule.c deleted file mode 100644 index b2dac6a54..000000000 --- a/stmhal/timemodule.c +++ /dev/null @@ -1,44 +0,0 @@ -#include - -#include "nlr.h" -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "obj.h" -#include "map.h" -#include "timemodule.h" - -STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { -#if MICROPY_ENABLE_FLOAT - if (MP_OBJ_IS_INT(seconds_o)) { -#endif - HAL_Delay(1000 * mp_obj_get_int(seconds_o)); -#if MICROPY_ENABLE_FLOAT - } else { - HAL_Delay((uint32_t)(1000 * mp_obj_get_float(seconds_o))); - } -#endif - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); - -STATIC const mp_map_elem_t time_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_time) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj }, -}; - -STATIC const mp_map_t time_module_globals = { - .all_keys_are_qstrs = 1, - .table_is_fixed_array = 1, - .used = sizeof(time_module_globals_table) / sizeof(mp_map_elem_t), - .alloc = sizeof(time_module_globals_table) / sizeof(mp_map_elem_t), - .table = (mp_map_elem_t*)time_module_globals_table, -}; - -const mp_obj_module_t time_module = { - .base = { &mp_type_module }, - .name = MP_QSTR_time, - .globals = (mp_map_t*)&time_module_globals, -}; diff --git a/stmhal/timemodule.h b/stmhal/timemodule.h deleted file mode 100644 index 70e35b1fd..000000000 --- a/stmhal/timemodule.h +++ /dev/null @@ -1 +0,0 @@ -extern const mp_obj_module_t time_module; -- cgit v1.2.3