• In a very early state I found a way to switch BLE on or off under testing.
    Workflow right now is like this

    • added an ESP32 specific command (ESP32enableBLE(mode);)
    • this functions stores a flag in Flash (in the moment partition free)
    • HWreset the board
    • during startup, read the flag from Flash, and according to that init BLE, or not
      Results in my test environment is heap of 103388 to 74252.
      This would be around 2000 additional jsVars, if BLE is not used

    Before making this nicer, better tested etc, I've some questions

    1. Should we use partition free, or is there a better place ?
    2. Do we need a message during startup, that BLE is disabled ?
    3. Is there a way to make NRF, Bluetooth and others inactive, so they cannot be called by accident ?
    4. Is there an option to use of HWReset ?
    5. some other questions, not comin to my mind right now ;-)
    6. what should be default setting, with or without BLE ?
  • Should we use partition free, or is there a better place ?

    Use a 'file' in require("Storage") - so use jsfFindFile. jsfReadFile would be perfect but you can't use it because you won't have any JsVars available :)

    bool shouldDisableBLE() {
      JsfFileHeader header;
      uint32_t addr = jsfFindFile(jsfNameFromString(".ble-dis"­), &header);
      if (!addr) return false; // no file - default
      char isOn;
      jshFlashRead(&isOn, addr, 1);
      return isOn;
    }
    

    Then require("Storage").write(".ble-dis",[1])­ would disable it. That could obviously be wrapped up a bit better though :)

    Do we need a message during startup, that BLE is disabled ?

    I doubt it. If the flag has been set then people will know. I guess BLE functions may need a check & exception in there to ensure they can't be used if BLE hasn't been enabled?

    Is there a way to make NRF, Bluetooth and others inactive, so they cannot be called by accident ?

    Not easily. You could add a if (!jsBleActive()) return 0 to every function, and then do:

    bool bleActive() {
    [#ifdef](http://forum.espruino.com/searc­h/?q=%23ifdef) NRF52
      return true;
    [#elif](http://forum.espruino.com/search­/?q=%23elif) defined(ESP32)
      if (active) {
       return true;
      } else {
       jsExceptionHere(JSET_ERROR,"BLE has been disabled");
       return false;
      }
    [#else](http://forum.espruino.com/search­/?q=%23else)
      jsExceptionHere(JSET_ERROR,"BLE not implemented");
      return false;
    [#endif](http://forum.espruino.com/searc­h/?q=%23endif)
    }
    

    Is there an option to use of HWReset ?

    http://www.espruino.com/Reference#l_ESP3­2_reboot ?

    what should be default setting, with or without BLE ?

    I'd say with BLE. We have the feature, so most people will want to be able to 'just use' it.

    1. Should we use partition free, or is there a better place ?

    That 'free' paritition is actually in use! Or it's labelled as such as it's in the flash available list...
    And 1 page for a single var is a littlw wasteful!

    The wifi config is actually stored in esp-idf nvs (non-volatile-storage ) area. There is a partition set up for this (12K) .

    http://esp-idf.readthedocs.io/en/latest/­api-reference/storage/nvs_flash.html?hig­hlight=nvs

    So it would be easy to use this library to store blu config details.

    However, as @Gordon has said above - the Storage module might be better.

    @MaBe has ported the ESP8266 to store the wifi details in the Storage module:
    https://github.com/MaBecker/Espruino/blo­b/33fa7dcfbb30a2e253416c7e73a89a3fe922ef­e8/libs/network/esp8266/jswrap_esp8266_n­etwork.c#L870-L887

    So this might be the better way to go. I was considering porting the ESP32 wifi config to use this, as it we can extend the fuctionality to store multiple AP details etc.

    Gordon >Use a 'file' in require("Storage") - so use jsfFindFile. jsfReadFile would be perfect but
    you can't use it because you won't have any JsVars available :)

    One way of dealing with this would be that if this setting is changed, the board saves the setting. Then a reboot - is forced - so the system then starts with the new setting?

    The number of jsvars could be varied at this point.

    1. Do we need a message during startup, that BLE is disabled ? and 3. Is there a way to make NRF, Bluetooth and others inactive, so they cannot be called by accident ?
      Gordon > Not easily. You could add a if (!jsBleActive()) return 0 to every function, and then do:
      How about undefining the BLE var ?
      Then any use would fail... the exception could have a help message?

    2. Is there an option to use of HWReset ?
      You mean like a reboot - like I mentioned above?
      I don't think it is unreasonable to reboot on a config change if you free up a heap of memory in the process.

    3. what should be default setting, with or without BLE ?
      Probably on - We have wifi and AP on at the moment and you have to turn off AP, so BLE on by default make sense.

  • One way of dealing with this would be that if this setting is changed, the board saves the setting. Then a reboot - is forced - so the system then starts with the new setting?

    Yes, that sounds like a good plan.

    How about undefining the BLE var ? ... the exception could have a help message?

    I'm not sure how we'd do that without modifying the interpreter internals (especially the help message). It's also likely someone may have retained a reference to the function - eg var go = NRF.findDevices.bind(NRF,myFunction).

    I don't think it is unreasonable to reboot on a config change if you free up a heap of memory in the process.

    Totally - or even just display a message saying Now call ESP32.reboot() for changes to take effect

    Just a quick gotcha here: save() saves an image of RAM to flash - if you save a large image and then load it when you have less RAM something will break. You probably want to call jsfRemoveCodeFromFlash whenever you change BLE to avoid this (or you could remove just SAVED_CODE_VARIMAGE - but there's no special function for this AFAIK).

  • Worked a bit on a switch for BLE.
    To be prepared for surprises, the idea is to calculate available jsVars.
    Assumptions are:

    • heap of 50000 bytes is sufficient
    • use steps of 100
    • maximum no. of JsVars is 20000
      Do you guys agree ?

    int heapVars;
    
    heapVars = (esp_get_free_heap_size() - 50000) / 16;
    heapVars = heapVars - heapVars % 100;
    if(heapVars > 20000) heapVars = 20000;
    jsVarsSize = heapVars;
    
    jsvInit();
    

    One more question could we do something like
    Bluetooth = nothing;
    NRF = nothing;

    or with a new (empty) object called isDisabled
    Bluetooth = new(isDisabled());
    NRF = new(isDisabled());

  • Yes, you could calculate the vars - but as I said above it'll mess up saving/loading if there isn't a fixed number of vars.

    One more question could we do something like Bluetooth = nothing;

    This is what @Wilberforce suggested. If you had saved code there are still ways to keep access to that object so it can be used - but I guess if you're destroying any saved code when you update it's ok. On boot you'd need to jsvObjectSetChild(execInfo.root,"Bluetoo­th",0) - it can still be worked around though.

    Personally I'd recommend modifying each function - that way the user actually gets a Bluetooth not enabled message.

  • Is there an (easy) way to calculate how many vars would be needed, based on saved ?

  • You could copy jsfLoadStateFromFlash and then make it decompress all the code without writing it anywhere.

    Personally I'd say this is all getting a bit too complicated though - in a way it's nice just to have two clear numbers of vars available that you can tell people: It's X with, Y without.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Switching BLE on/off and get additional 29KB into heap

Posted by Avatar for JumJum @JumJum

Actions