From 81f72553f3a2869b8cf9e00ec45bc243a09f6171 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 29 Jun 2023 22:17:17 +0200 Subject: [PATCH 1/2] Command ``BrRestart`` to restart the Berry VM (experimental) --- CHANGELOG.md | 1 + lib/libesp32/berry_mapping/src/be_cb_module.c | 21 +++++++++++++++++++ lib/libesp32/berry_mapping/src/be_mapping.h | 2 ++ tasmota/include/i18n.h | 1 + .../tasmota_xdrv_driver/xdrv_52_9_berry.ino | 16 ++++++++++++-- 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fe6389e4812..846e61639e07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Command ``Delay -1`` to wait until next second (#18984) - Matter add option to disable bridge mode (#18992) - Support for SGP41 TVOC/NOx Sensor (#18880) +- Command ``BrRestart`` to restart the Berry VM (experimental) ### Breaking Changed - Berry `bool( [] )` and `bool( {} )` now evaluate as `false` (#18986) diff --git a/lib/libesp32/berry_mapping/src/be_cb_module.c b/lib/libesp32/berry_mapping/src/be_cb_module.c index 8054398d4956..b5e7b1427605 100644 --- a/lib/libesp32/berry_mapping/src/be_cb_module.c +++ b/lib/libesp32/berry_mapping/src/be_cb_module.c @@ -250,6 +250,7 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in bvm * vm = be_cb_hooks[num].vm; bvalue *f = &be_cb_hooks[num].f; + if (vm == NULL) { return 0; } // function is not alive anymore, don't crash // push function (don't check type) bvalue *top = be_incrtop(vm); @@ -271,6 +272,26 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in return ret; } +/*********************************************************************************************\ + * `be_cb_deinit`: + * Clean any callback for this VM, they shouldn't call the registerd function anymore +\*********************************************************************************************/ +void be_cb_deinit(bvm *vm) { + // remove all cb for this vm + for (int32_t slot = 0; slot < BE_MAX_CB; slot++) { + if (be_cb_hooks[slot].vm == vm) { + be_cb_hooks[slot].vm = NULL; + be_cb_hooks[slot].f.type == BE_NIL; + } + } + // remove the vm gen_cb for this vm + for (be_callback_handler_list_t **elt_ptr = &be_callback_handler_list_head; *elt_ptr != NULL; elt_ptr = &(*elt_ptr)->next) { + if (((*elt_ptr)->next != NULL) && ((*elt_ptr)->next->vm == vm)) { + (*elt_ptr)->next = (*elt_ptr)->next->next; + } + } +} + /* @const_object_info_begin module cb (scope: global) { gen_cb, func(be_cb_gen_cb) diff --git a/lib/libesp32/berry_mapping/src/be_mapping.h b/lib/libesp32/berry_mapping/src/be_mapping.h index 9876278f391f..f0ab9d22c56b 100644 --- a/lib/libesp32/berry_mapping/src/be_mapping.h +++ b/lib/libesp32/berry_mapping/src/be_mapping.h @@ -109,6 +109,8 @@ extern int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_ extern int be_call_c_func(bvm *vm, const void * func, const char * return_type, const char * arg_type); extern int be_call_ctype_func(bvm *vm, const void *definition); /* handler for Berry vm */ +extern void be_cb_deinit(bvm *vm); /* remove all callbacks from the VM (just before shutdown of VM) */ + #ifdef __cplusplus } #endif diff --git a/tasmota/include/i18n.h b/tasmota/include/i18n.h index 37be387fe629..1cbb6ffd4384 100644 --- a/tasmota/include/i18n.h +++ b/tasmota/include/i18n.h @@ -764,6 +764,7 @@ // Commands xdrv_52_berry.ino - Berry scripting language #define D_PRFX_BR "Br" #define D_CMND_BR_RUN "" +#define D_CMND_BR_RESTART "Restart" #define D_BR_NOT_STARTED "Berry not started" // Commands xdrv_60_shift595.ino - 74x595 family shift register driver diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino index c46606e47224..b8cf7113146d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino @@ -37,11 +37,11 @@ extern "C" { } const char kBrCommands[] PROGMEM = D_PRFX_BR "|" // prefix - D_CMND_BR_RUN + D_CMND_BR_RUN "|" D_CMND_BR_RESTART ; void (* const BerryCommand[])(void) PROGMEM = { - CmndBrRun, + CmndBrRun, CmndBrRestart }; int32_t callBerryEventDispatcher(const char *type, const char *cmd, int32_t idx, const char *payload, uint32_t data_len = 0); @@ -307,6 +307,7 @@ void BrShowState(void) { void BerryInit(void) { // clean previous VM if any if (berry.vm != nullptr) { + be_cb_deinit(berry.vm); // deregister any C callback for this VM be_vm_delete(berry.vm); berry.vm = nullptr; } @@ -367,6 +368,17 @@ void BerryInit(void) { } } +/*********************************************************************************************\ + * BrRestart - restart a fresh new Berry vm, unloading everything from previous VM +\*********************************************************************************************/ +void CmndBrRestart(void) { + if (berry.vm == nullptr) { + ResponseCmndChar_P("Berry VM not started"); + } + BerryInit(); + ResponseCmndChar_P("Berry VM restarted"); +} + /*********************************************************************************************\ * Execute a script in Flash file-system * From 4a46eb1dfe370bf153aef4043a7a1be027d4ca77 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 2 Jul 2023 21:43:34 +0200 Subject: [PATCH 2/2] Add web button for Berry Restart --- .../xdrv_52_3_berry_webserver.ino | 1 - .../tasmota_xdrv_driver/xdrv_52_9_berry.ino | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webserver.ino index f37be12b5603..7df813e3f247 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webserver.ino @@ -138,7 +138,6 @@ extern "C" { const char * uri = be_tostring(vm, 1); Webserver->sendHeader("Location", uri, true); Webserver->send(302, "text/plain", ""); - // Webserver->sendHeader(F("Location"), String(F("http://")) + Webserver->client().localIP().toString(), true); be_return_nil(vm); } be_raise(vm, kTypeError, nullptr); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino index b8cf7113146d..f39a45271536 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino @@ -310,6 +310,10 @@ void BerryInit(void) { be_cb_deinit(berry.vm); // deregister any C callback for this VM be_vm_delete(berry.vm); berry.vm = nullptr; + berry.autoexec_done = false; + berry.repl_active = false; + berry.rules_busy = false; + berry.timeout = 0; } int32_t ret_code1, ret_code2; @@ -665,14 +669,16 @@ const char HTTP_BERRY_FORM_CMND[] PROGMEM = "Check the documentation." "" "" - // "" - // "

" "
" "" - // "
" - // "" "" - "
"; + "" +#ifdef USE_BERRY_DEBUG + "

" + "" + "

" +#endif // USE_BERRY_DEBUG + ; const char HTTP_BTN_BERRY_CONSOLE[] PROGMEM = "

"; @@ -718,6 +724,12 @@ void HandleBerryConsole(void) return; } + if (Webserver->hasArg(F("rst"))) { // restart VM + BerryInit(); + Webserver->sendHeader("Location", "/bc", true); + Webserver->send(302, "text/plain", ""); + } + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Berry " D_CONSOLE)); WSContentStart_P(PSTR("Berry " D_CONSOLE));