diff --git a/Core/Src/main.c b/Core/Src/main.c index afd6a75..d2cb472 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -28,6 +28,10 @@ #include "mruby.h" #include "mruby/compile.h" +#include "mruby/dump.h" +#include "mruby/string.h" +#include "mruby/variable.h" +#include "mruby/presym.h" /* USER CODE END Includes */ @@ -354,12 +358,6 @@ static void report_card_info(void) { ); } - -static void report_heap(void) { - struct mallinfo mi = mallinfo(); - printf("\r\nHeap usage: %d bytes.\r\n", mi.uordblks); -} - /** * @brief Load a script called boot.rb from SD card * It's caller free. @@ -383,7 +381,7 @@ static char *load_boot_script(void) { } UINT boot_file_size = f_size(&boot_file); - ret = malloc(boot_file_size + 1); + ret = pvPortMalloc(boot_file_size + 1); if(ret == NULL) { printf("Failed to allocate memory for script.\r\n"); goto out_close; @@ -392,7 +390,7 @@ static char *load_boot_script(void) { UINT read_size; if(f_read(&boot_file, ret, boot_file_size, &read_size) != FR_OK) { printf("Failed to read script.\r\n"); - free(ret); + vPortFree(ret); ret = NULL; } else { ret[read_size] = '\0'; @@ -421,11 +419,10 @@ void RunMRBTask(void *argument) { /* USER CODE BEGIN 5 */ - report_heap(); - mrb_state *mrb = mrb_open(); if(mrb == NULL) { printf("Failed to open mruby core.\r\n"); + goto dead_loop; } mrbc_context *cxt = mrbc_context_new(mrb); @@ -440,18 +437,27 @@ void RunMRBTask(void *argument) struct mrb_parser_state *parser_state = mrb_parse_string(mrb, boot_script, cxt); if(parser_state == NULL) { printf("Failed to parse main script.\r\n"); + vPortFree(boot_script); + mrb_parser_free(parser_state); } else { - free(boot_script); + vPortFree(boot_script); + mrb_load_exec(mrb, parser_state, cxt); + + if(mrb->exc) { + printf("Exception occured, script not finished.\r\n"); + } } } + printf("Boot script exited, cleaning up.\r\n"); cleanup_mrb: mrb_close(mrb); - report_heap(); +dead_loop: + /* Infinite loop */ for(;;) { diff --git a/example/boot.rb b/example/boot.rb new file mode 100644 index 0000000..d6e9d38 --- /dev/null +++ b/example/boot.rb @@ -0,0 +1,28 @@ +i = 0 + +puts "mRuby v#{RUBY_VERSION} on STM32!\r\n" + +2.times do + puts "Hello world #{i}\r\n" + i += 1 + + puts "MRB Heap usage: #{OSUtil.heap_usage.to_s}\r\n" + + OSUtil.sleep_ms(500) +end + +begin + puts "#{Gpio}\r\n" + pin = Gpio::Pin.new({:port => 0, :pin => 16}, {:mode => 0, :pull => 0}) + puts "#{pin}\r\n" + + puts "#{Gpio::Port::A}\r\n" +rescue Exception => e + puts "Exception: #{e.inspect}\r\n" +end + + + +puts "MRB Heap usage: #{OSUtil.heap_usage.to_s}\r\n" + +puts "Main script ended.\r\n" \ No newline at end of file diff --git a/lib/linenoise/CMakeLists.txt b/lib/linenoise/CMakeLists.txt deleted file mode 100644 index d507f67..0000000 --- a/lib/linenoise/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(linenoise) - -set(LINENOISE_SOURCES - "linenoise/linenoise.c" -) - -set(LINENOISE_INCLUDES - "linenoise" -) - -add_library(${PROJECT_NAME} ${LINENOISE_SOURCES}) -target_include_directories(${PROJECT_NAME} PUBLIC ${LINENOISE_INCLUDES}) \ No newline at end of file diff --git a/lib/mruby/CMakeLists.txt b/lib/mruby/CMakeLists.txt index b3720f2..a43e639 100644 --- a/lib/mruby/CMakeLists.txt +++ b/lib/mruby/CMakeLists.txt @@ -29,7 +29,7 @@ set_target_properties(mruby PROPERTIES IMPORTED_LOCATION ) set_target_properties(mruby PROPERTIES INTERFACE_INCLUDE_DIRECTORIES - "${CMAKE_CURRENT_SOURCE_DIR}/mruby/include" + "${CMAKE_CURRENT_SOURCE_DIR}/mruby/include;${CMAKE_CURRENT_SOURCE_DIR}/mruby/build/STM32H750/include" ) set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES diff --git a/lib/mruby/build_config.rb b/lib/mruby/build_config.rb index f6e08a4..234b17c 100644 --- a/lib/mruby/build_config.rb +++ b/lib/mruby/build_config.rb @@ -47,6 +47,7 @@ MRuby::CrossBuild.new("STM32H750") do |conf| #gems from core conf.gem :core => "mruby-compiler" conf.gem :core => "mruby-enum-ext" + conf.gem :core => "mruby-hash-ext" conf.gem :core => "mruby-math" conf.gem :core => "mruby-numeric-ext" conf.gem :core => "mruby-print" diff --git a/lib/mruby/gems/stm32_gpio/mrblib/stm32_gpio.rb b/lib/mruby/gems/stm32_gpio/mrblib/stm32_gpio.rb new file mode 100644 index 0000000..8a27c38 --- /dev/null +++ b/lib/mruby/gems/stm32_gpio/mrblib/stm32_gpio.rb @@ -0,0 +1,24 @@ +module Gpio + module Port + A = 0 + B = 1 + C = 2 + D = 3 + E = 4 + F = 5 + G = 6 + H = 7 + end + + module Mode + INPUT = 0 + OUTPUT_PP = 1 + OUTPUT_OD = 2 + end + + module Pull + NONE = 0 + UP = 1 + DOWN = 2 + end +end diff --git a/lib/mruby/gems/stm32_gpio/src/stm32_gpio.c b/lib/mruby/gems/stm32_gpio/src/stm32_gpio.c index c66f59e..e2d09a3 100644 --- a/lib/mruby/gems/stm32_gpio/src/stm32_gpio.c +++ b/lib/mruby/gems/stm32_gpio/src/stm32_gpio.c @@ -1,41 +1,49 @@ #include #include +#include +#include #include "stm32h7xx_hal.h" static mrb_value stm32_gpio_init_c_method(mrb_state *mrb, mrb_value self) { - -} - -static mrb_value stm32_gpio_deinit_c_method(mrb_state *mrb, mrb_value self) { + printf("Init called.\r\n"); + return mrb_nil_value(); } static mrb_value stm32_gpio_read_c_method(mrb_state *mrb, mrb_value self) { + printf("Read called.\r\n"); + return mrb_nil_value(); } static mrb_value stm32_gpio_write_c_method(mrb_state *mrb, mrb_value self) { + printf("Write called.\r\n"); + return mrb_nil_value(); } static mrb_value stm32_gpio_toggle_c_method(mrb_state *mrb, mrb_value self) { + printf("Toggle called.\r\n"); + return mrb_nil_value(); } void mrb_stm32_gpio_gem_init(mrb_state *mrb) { - struct RClass *stm32_gpio_cextension = mrb_define_class(mrb, "stm32_gpio", mrb->object_class); - /* _init(port, pin, mode) */ - mrb_define_method(mrb, stm32_gpio_cextension, "_init", stm32_gpio_init_c_method, MRB_ARGS_REQ(3)); - /* _deinit(port, pin) */ - mrb_define_method(mrb, stm32_gpio_cextension, "_deinit", stm32_gpio_deinit_c_method, MRB_ARGS_REQ(2)); - /* _read(port, pin) */ - mrb_define_method(mrb, stm32_gpio_cextension, "_read", stm32_gpio_read_c_method, MRB_ARGS_REQ(2)); - /* _write(port, pin, value) */ - mrb_define_method(mrb, stm32_gpio_cextension, "_write", stm32_gpio_write_c_method, MRB_ARGS_REQ(3)); - /* _toggle(port, pin) */ - mrb_define_method(mrb, stm32_gpio_cextension, "_toggle", stm32_gpio_toggle_c_method, MRB_ARGS_REQ(2)); + struct RClass *stm32_gpio_module = mrb_define_module(mrb, "Gpio"); + struct RClass *stm32_pin_class = mrb_define_class_under(mrb, stm32_gpio_module, "Pin", mrb->object_class); + + MRB_SET_INSTANCE_TT(stm32_pin_class, MRB_TT_DATA); + + /* initialize(port, pin, mode) */ + mrb_define_method(mrb, stm32_pin_class, "initialize", stm32_gpio_init_c_method, MRB_ARGS_ARG(1, 1)); + /* _read(port, pin) */ + mrb_define_method(mrb, stm32_pin_class, "read", stm32_gpio_read_c_method, MRB_ARGS_NONE()); + /* _write(port, pin, value) */ + mrb_define_method(mrb, stm32_pin_class, "write", stm32_gpio_write_c_method, MRB_ARGS_NONE()); + /* _toggle(port, pin) */ + mrb_define_method(mrb, stm32_pin_class, "toggle", stm32_gpio_toggle_c_method, MRB_ARGS_NONE()); } void mrb_stm32_gpio_gem_final(mrb_state *mrb) { diff --git a/lib/mruby/gems/stm32_osutil/src/stm32_osutil.c b/lib/mruby/gems/stm32_osutil/src/stm32_osutil.c index 670faf0..5e0c459 100644 --- a/lib/mruby/gems/stm32_osutil/src/stm32_osutil.c +++ b/lib/mruby/gems/stm32_osutil/src/stm32_osutil.c @@ -1,16 +1,15 @@ +#include #include #include #include "cmsis_os.h" -static mrb_value stm32_osutil_sleep_ms_c_method(mrb_state* mrb, mrb_value self) { - mrb_value* argv; +static mrb_value stm32_osutil_sleep_ms_c_method(mrb_state *mrb, mrb_value self) { + mrb_value *argv; mrb_int argc; mrb_get_args(mrb, "*", &argv, &argc); - int iargc = (int)argc; - - if (iargc == 0 || iargc >= 2) { + if (argc != 1) { mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); } @@ -20,13 +19,23 @@ static mrb_value stm32_osutil_sleep_ms_c_method(mrb_state* mrb, mrb_value self) mrb_raise(mrb, E_ARGUMENT_ERROR, "sleep duration must be positive integer"); } - return self; + return mrb_nil_value(); } -void mrb_stm32_osutil_gem_init(mrb_state* mrb) { - struct RClass* class_cextension = mrb_define_module(mrb, "OSUtil"); +static mrb_value stm32_osutil_heap_usage_c_method(mrb_state *mrb, mrb_value self) { + struct mallinfo mi = mallinfo(); + return mrb_int_value(mrb, mi.uordblks); +} + +void mrb_stm32_osutil_gem_init(mrb_state *mrb) { + struct RClass *class_cextension = mrb_define_module(mrb, "OSUtil"); + /* OSUtil.sleep_ms(msec) => nil */ mrb_define_class_method(mrb, class_cextension, "sleep_ms", stm32_osutil_sleep_ms_c_method, MRB_ARGS_REQ(1)); + /* OSUtil.heap_usage() => usage in bytes */ + mrb_define_class_method(mrb, class_cextension, "heap_usage", stm32_osutil_heap_usage_c_method, MRB_ARGS_NONE()); } -void mrb_stm32_osutil_gem_final(mrb_state* mrb) { /* finalizer */ +void mrb_stm32_osutil_gem_final(mrb_state *mrb) { + /* Finalizer */ + /* No resources needs cleanup. */ }