• Hi,

    I want to add an option to my espruino toolset that will support a fallback app code mechanism when uploading code by both wifi and uart interfaces.

    I know there is Wifi Remote Console code available already, so there is only a fallback mechanism left to implement.

    When I upload a new code, my bootloader will boot from newly uploaded code. If some kind of heartbeat is not found for a while, it will reboot and load the last known good code.

    So the question is, how can I save/load a code to/from from a specific location of EEprom?

  • I do not exactly understand what you what to achieve. After a successful upload followed by a save(), all your code is in the FlashEEPROM. Any reset / restart / power cycle will restore (some of) the machine state and, load all code into the memory, and start with onInit() or with all functions registered with E.on("init",f...);.

    In case you plan something different, like a remote update of the saved code in form of a second version and you want to load it into the FlashEEPROM and switch over with a reset... that may be something else.

  • I'm making a plan for such a scenario:

    1. Think that I developed an application, wrote it to the device, tested it, and send to the field when it's ready.
    2. It turns out, my application had a bug.
    3. I have a very very good idea(!) that the problem is just the var x = 1;, it should be var x = {1} (watch the typo)
    4. I send the code to the device, and the device is bricked now and I have no option to fix the last wrong app...

    My plan as a precaution is the following:

    1. I can send this untested code with a mark to indicate "to be tested",
    2. device would download and save it,
    3. make it loaded on next reboot, and
    4. watch for a specific "heartbeat" sign (for example, I can set a timeout for a specific FlashEEPROM location value and set the "OK" value over socket connection, which will guarantee that my second application boots and connects correctly).
    5. If no heartbeat is found within a timeout, then old code will be loaded and new code will be discarded by the device (bootloader) itself.
  • Have you seen this?

    https://www.npmjs.com/package/node-espruĀ­ino

    Also,
    If you are using the esp8266 board, you can use the wiflash.sh script to flash firmware over wifi, no need for a serial connection.

  • @Wilberforce Yes, I've seen that module but it was too late because I've written my own toolset way before I've met Espruino (during which I was dealing with micropython). But the node-espruino doesn't offer such a fallback mechanism anyway.

  • @ceremcem, I see where you're going.

    1. Create backup of current working code
    2. Deploy new code
    3. Wait for heartbeat (and may be other signs of 'positive, successful' life of new code
      4-Y. If heartbeat arrives: keep going with new code
      5-N. If heartbeat fails to arrive: back-out from new code and re-inbstate previous version

    I'm thinking of a VM concept where there is a Host and a Guest... the Host is rock solid, always there and a minimal (communiction) environment to host Guests... and the Guests are the actual applications.

  • @allObjects This is exactly my plan. I think I can implement such a "Host" (a bootloader, or a vm kernel thing) if I could selectively load the code from specific location.

    On second thoughts: I can use FlashEEPROM. Then, I could write a code that will behave like a console (like wiflash does) and will write everything to the EEPROM. Upon a boot process, I could read the EEPROM location and directly evaluate these codes; which will exactly simulate what load() does.

    Only difference is, I can save to and load from exactly where I want.

    Hmm. Let me try something out. I'll get back to you.

  • ...modifying the load() in a backward compatible way: load() proded with an address or id/label or index could be the answer... may be @Gordon has some ideas about this...

  • You might be able to use E.enableWatchdog(seconds) - this won't work on ESP8266, but there's basically a 1 sec watchdog enabled by default.

    If Espruino doesn't get back to the idle loop within some time period it'll crash, so your code would look like:

    function onInit() {
      if (f.read(ok) == false) return; // fallback
      f.write(ok,0);
      eval(f.read(code));
      if (all ok) f.write(ok,1);
    }
    
  • There was a near-miss of RTFM issue :)

    I found this in the documentation: http://www.espruino.com/run_code_from_eeĀ­prom#line=8

  • You can also do f.readMem(...) - this will return a string directly, which can be executed from flash without being copied to RAM. It might need a newer ESP8266 build to work though.

  • On the esp8266 the built-in telnet console and the web-server used by wiflash come up immediately at boot independently of any JS code execution. If you can delay the start-up of your JS code that can give you a window to "get in".

    Also, since the port 88 web server is independent if JS you have a good chance at hitting it even if JS code is messed-up, as long as the Espressif SDK still receives packets and can make a callback. All this isn't exactly what you're looking for but it gets pretty close.

    In my experience things get really hosed if save()'ed code in flash is no longer compatible with a newer version of Espruino that just got loaded or if the esp8266 crashes and the WDT doesn't reboot it (yup, happens to me but hard to repro intentionally).

  • @tve could the ota server for firmware updates get extended to allow for the save() code to be be replaced for these lock up situations?

    There would also be another benefit - could new code be sent along with the .bin files, to get interpreted on restart after the firmware update?

  • It's all doable... The OTA update code is kept as small and simple as possible for obvious reasons. Also, the protocol is really simple to allow a bash script with a couple of curl invocations to do the upgrade. I.e., no extra binary to build or locate. (It would not be all that difficult for someone versed in powershell to write the equivalent for Windows.)

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

How to load some code from specific location from EEprom?

Posted by Avatar for ceremcem @ceremcem

Actions