mp_flipper_runtime.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include <string.h>
  2. #include "py/compile.h"
  3. #include "py/runtime.h"
  4. #include "py/persistentcode.h"
  5. #include "py/gc.h"
  6. #include "py/stackctrl.h"
  7. #include "shared/runtime/gchelper.h"
  8. #include "mp_flipper_runtime.h"
  9. #include "mp_flipper_halport.h"
  10. const char* mp_flipper_root_module_path;
  11. void* mp_flipper_context;
  12. void mp_flipper_set_root_module_path(const char* path) {
  13. mp_flipper_root_module_path = path;
  14. }
  15. void mp_flipper_init(void* heap, size_t heap_size, size_t stack_size, void* stack_top) {
  16. mp_flipper_context = mp_flipper_context_alloc();
  17. mp_stack_set_top(stack_top);
  18. mp_stack_set_limit(stack_size);
  19. gc_init(heap, (uint8_t*)heap + heap_size);
  20. mp_init();
  21. }
  22. void mp_flipper_exec_mpy_file(const char* file_path) {
  23. #ifdef MP_FLIPPER_MPY_SUPPORT
  24. #if MP_FLIPPER_IS_RUNTIME
  25. nlr_buf_t nlr;
  26. if(nlr_push(&nlr) == 0) {
  27. do {
  28. // check if file exists
  29. if(mp_flipper_import_stat(file_path) == MP_FLIPPER_IMPORT_STAT_NO_EXIST) {
  30. mp_raise_OSError_with_filename(MP_ENOENT, file_path);
  31. break;
  32. }
  33. // Execute the given .mpy file
  34. mp_module_context_t* context = m_new_obj(mp_module_context_t);
  35. context->module.globals = mp_globals_get();
  36. mp_compiled_module_t compiled_module;
  37. compiled_module.context = context;
  38. mp_raw_code_load_file(qstr_from_str(file_path), &compiled_module);
  39. mp_obj_t f = mp_make_function_from_proto_fun(compiled_module.rc, context, MP_OBJ_NULL);
  40. mp_call_function_0(f);
  41. } while(false);
  42. nlr_pop();
  43. } else {
  44. // Uncaught exception: print it out.
  45. mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
  46. }
  47. #endif
  48. #endif
  49. }
  50. void mp_flipper_deinit() {
  51. mp_deinit();
  52. mp_flipper_context_free(mp_flipper_context);
  53. }
  54. // Called if an exception is raised outside all C exception-catching handlers.
  55. void nlr_jump_fail(void* val) {
  56. mp_flipper_nlr_jump_fail(val);
  57. }
  58. #if MICROPY_ENABLE_GC
  59. // Run a garbage collection cycle.
  60. void gc_collect(void) {
  61. gc_collect_start();
  62. gc_helper_collect_regs_and_stack();
  63. gc_collect_end();
  64. }
  65. #endif
  66. #ifndef NDEBUG
  67. // Used when debugging is enabled.
  68. void __assert_func(const char* file, int line, const char* func, const char* expr) {
  69. mp_flipper_assert(file, line, func, expr);
  70. }
  71. void NORETURN __fatal_error(const char* msg) {
  72. mp_flipper_fatal_error(msg);
  73. }
  74. #endif
  75. void mp_flipper_raise_os_error(int error) {
  76. mp_raise_OSError(error);
  77. }
  78. void mp_flipper_raise_os_error_with_filename(int error, const char* filename) {
  79. mp_raise_OSError_with_filename(error, filename);
  80. }