Adding 'Built-in' code

Posted on
  • @tve just asked about how it might be possible to build code into Espruino such that after the board was reset(), it was still there - and it seems it might be worth thinking about here.

    The initial reasons I can think of are:

    • The ability to boot right up, connect to a network, and then be able to connect to the Espruino and program it (@tve's suggestion)
    • Same thing, but with some random radio connection of your choice (NRF24, RFM69, etc)
    • An 'Espruino PC' - Since Espruino can do VGA output, and the console can be redirected, we could actually have a proper all-in-one Espruino-based PC.
    • Maybe you have some teaching tool and you want some things pre-initialised (like an LCD that says 'hello')

    The obvious one is to build C code into the firmware - but then you need separate firmware for each type of device (and in the WiFi case you still have to store WiFi credentials somewhere), and also C knowledge.

    Another option is to allow user-defined JS code to be written into flash memory, in the same area that the existing saved code is stored in. Then when initialising, Espruino would load that code up before anything else - even if it was right after a reset() call.

    Because of the way Espruino works, any functions that got defined would still take up RAM, and it'd eat into the amount of code that you could save to flash. I think in a lot of cases that wouldn't be too bad though?

    It seems like a neat solution anyway, and it's not too evil to implement. You'd just have a function like E.setBootupCode("...."), and if required you could still build that into the binary.

    Only bad point as far as I can see is that in the WiFi case, reset() would reset all the open socket connections (unless we had a 'special' connection type that could survive?). It probably makes sense to build in Telnet console functionality (it'd be easy in the firmware, and might help with debugging if there was buggy JS code), and to expose it via some function call. That special connection type could then persist through resets, and the code that you upload would be simply:

    E.setBootupCode(
      "require('WiFi').connect(wifi, credentials, function(){"
     +"E.enableTelnetServer('mypassword')"
    +"});");
    

    Any thoughts about this? Does there seem to be a better way of handling it?

  • ...sounds structurally similar to onInit() as just in acute conversation: what about multiple piece of boot up code?

    I feel like a layering - with possible overlap - is goin on here: boodloader, firmware (Espruino), boot up codes, on init codes,...

    How is the bootup code removed: reset() vs reset(someParmValue)?

  • sounds structurally similar to onInit

    Yes - although more advanced. I'd actually like it to be slightly 'hidden' - because I think the main use-case is to set it up, and then to have it working in the background without it being apparent.

    How is the bootup code removed

    E.setBootupCode("")?

    what about multiple piece of boot up code?

    I think, given the advanced nature, we'd ignore that. If there was a 'getter', you'd do:

    E.setBootupCode(E.getBootupCode()+"print('Hello');")

  • This E.setBootupCode("...") would have to happen in a separate step and has to trigger a reset(). If part of a 'sketch' in IDE's edit pane vs. executed from the console, it would be kind of 'transient' like the require("literalName") - forgotten after execute and not saved as literal part of the uploaded code,... and fort to make it simple for the upload, it would have to be the first thing in the 'sketch'.

  • I wasn't planning on making it reset the board. That'd be up to the user.

    As I say - it's advanced. I imagine a developer might run it once to enable something like a console on TCP/IP. It's not something they'd do repeatedly.

  • To me the whole point is to have bootup code that is not part of the sketch being uploaded via the IDE. This way I can have some init code that enables the IDE in the first place and that stays in place while I'm wildly editing and testing.

  • WRT JS vs C, I'm getting the feeling that some things will have to be pushed down into C to save memory. What would be neat is if one could use the generic interfaces that make the JS stuff work from C. For example, for the network stuff it ought to be possible to call the functions exported via a JsNetwork (https://github.com/espruino/Espruino/blob/master/libs/network/network.h#L51-L73) from other C code and thereby make that somewhat target independent.

  • @tve, I see that... but how do you get it 'there'.... usually with a 'sketch' you build in a supporting environment such as the IDE... and the 'daily' things using it as a base do not include it your 'regular sketches'. It could be considered something like dynamically extend the build...

    Delivering though a finished package - which makes both parts a one-time things - could support this funcitonality. It is then just one file (sketch) to upload and save(), and the espruino is 'programmed'.

  • @allObjects, I think @tve is talking about uploading a program via WiFi. To do that, Espruino needs WiFI credentials built into it - it's no good if they disappear when you reset() the board because then you won't be able to program it again.

    @tve I'm not quite sure I understand. You can use things like jspCallFunction to call into JS pretty easily as-is - I'm not sure what else apart from the network (which is sorted) would be needed.

    As far as the WiFi terminal, I added some notes here about it. I think C is sensible for that - actually getting it running should be relatively straightforward.

    It'd be nice if the firmware (as flashed) put the ESP8266 into AP mode with a Telnet server running. Hopefully we could tweak the socketserver code such that the server would survive a soft reset().

  • There is already some code in the esp8266 target, I have not looked at it more closely though. See https://github.com/espruino/Espruino/blob/master/targets/esp8266/telnet_client.c

  • Hmm - that looks like a bit of debug stuff from @Kolban that probably shouldn't be in there?

    There's a lot more magic that goes into the Espruino console (multi-line, command history, etc). It'd be much better not to duplicate that - especially in an ESP8266-specific way :)

  • Either way - priming Espruino with wifi for connecting/programming, or - just put some basic stuff on it in order to not have to load it every time on upload - both need a way to get the code there, and that would be conveniently through an upload / run from within the IDE's edit pane.

  • Continuing from the other thread, I think this would be great:

    //Your networking code here
    
    var bootcode = require('bootcode').init();
    

    Where init goes through and takes a record of the existing modules, vars, etc and stores them. Then it links bootcode.reset to the native reset function, replaces reset() with a function that resets and deletes everything that's not required. If your networking code is all stored in a module too, you only need to put this into your Espruino when you first run it:

    var wifi = require('my network').init();var bootcode = require('bootcode').init();
    

    @Gordon - Coming from someone who doesn't know a lot about the internals, would it be possible to add a step in compilation that writes a .js file into the binary as an initial program? It would also be useful for the boards you sell, as you could send them out with a tutorial built into them.

  • You'll be able to do E.setBootupCode(E.dumpStr()) which will have pretty much the same effect.

    Actually avoiding the problem by just not totally resetting is a really interesting thought though - it solves a whole lot of problems.

    would it be possible to add a step in compilation that writes a .js file into the binary as an initial program?

    Yep - that's kind of the idea with E.setBootupCode - what is does could also be done in the compilation process... or, like you can do right now you can actually just save() your code, and can then go into bootloader mode and read the whole binary out (including your saved code).

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

Adding 'Built-in' code

Posted by Avatar for Gordon @Gordon

Actions