Trouble uploading code to PIXL.js

Posted on
  • Hello,

    I'm having trouble uploading a bundled file to my PIXL.js. It will take a while to complete the upload, but it won't give positive feedback.

    The code which I'm trying to execute looks something like this:

    const engine = require('engine');
    
    E.on('init', () => {
      Terminal.println('Something.');
    });
    
    

    where engine is the aforementioned file and I'm running save() to save to the flash storage.
    I am already having doubts that my bundle is too big, but it would be helpful if there was an indicator for that.

    Edit:
    Output for process.memory():

    {
       free: 2348,
       usage: 152,
       total: 2500,
       history: 22
    }
    
  • If there's need for it, I can clarify what is happening in the bundled file. However I didn't seem to be relevant for uploading the code.

  • Ouch, over half a meg is definitely too big. AFAIK for any Espruino.
    Memory usage is not directly tied to file size, but to give a rough estimate: 10k JS file most likely will work on the Pixl.
    If you can get it down to 20k, probably you can try to get it working on the Pixl.

  • Sun 2019.07.28

    'but it would be helpful if there was an indicator for that.'

    Hi @Proceed, I don't have a Pixl handy, would you mind posting the results of process.memory() so that the contributors may stay on the same page to offer solutions please.

    Typically 12 byte blocks listed in number of JsVars available.

    http://www.espruino.com/Internals

    As a suggestion, as I have done so in the past, run the function above, divide the source in half and upload, then run the above function again. Wash, lather, rinse, repeat. The code wont execute of course.

    Info only a S.W.A.G. response, but for the Pico, have been able to u/l a 30K file, mixed code and comments. The Pixl, if (my) memory serves is about half that.

    >process.memory()
    ={ free: 5080, usage: 20, total: 5100, history: 0,
    
  • Hi @Robin, I edited the original post to include the process.memory() output.
    Unfortunately I am not able to get rid of parts of the code as it's an engine that needs most of it's parts running.

  • Sun 2019.07.28

    Thank you @Proceed. So we have 2500 JsVars less some overhead to work with on the Pixl.

    'I am not able to get rid of parts of the code' . . . 'needs most of it's parts'

    Understood. My point was to find a reasonable amount of code that would fit, which would provide a benchmark as a percentage of total size for the original, then make a determination as to whether parts of the source module could be removed.

    https://www.espruino.com/Performance

    Minification enabled?
    WebIDE >> Settings >> Minification


    This might provide some insight to an alternate means using additional memory:

    How-to run code from flash

    Espruino loading source code from SD card?

  • Didn't you get something like New interpreter error: LOW_MEMORY,MEMORY Explanation here

    Just some numbers: The Pixl.JS contains an nRF52832 that has 512k flash and 64k ram. And a lot of that is used by Espruino.
    So if your code is really that over half megabyte of minified JS, it won't fit in the Pixl. With some serious wizardry to store almost all of your code in some external flash (something like SD card, SPI flash), and pulling in small chunks of that to work on some piece of data, it might work. But most likely you would have to forget about 99% of JS available in NPM, because it's just too big. Or for example there is no Symbol in Espruino.

  • Do you get any error messages in the Espruino REPL at all, or is it just completely blank? I'd have definitely expected some MEMORY errors.

    Realistically around 40k of JS code is probably your limit for uploads.

    What exactly are you trying to get Pixl.js to do with your bundled file? We might be able to suggest another way of doing what you want - I've had a look but it seems to be mostly utilities (Buffer, tiny-stack, EventEmitter) for things that are already built in to Espruino, just in a slightly different form.

  • Most of the output I received was New interpreter error: Execution Interrupted. I tried running it with and without minification, but that didn't make a difference. Supposedly something could have went wrong when transpiling, as a lot of the code uses features not available on Espruino (async comes to mind).

    @Gordon the bundled file is essentially a process engine that expects the PIXL to perform certain tasks on events. An example would be the task of writing something to the screen based on an interaction with another IOT device running the engine.

    Can you elaborate what you mean by saying "around 40k JS code"? Is there a list of JavaScript features/libraries available on Espruino? Maybe I don't need to transpile the entirety of code.

  • @Proceed,

    looked at your bundle file mentioned in your initial post of this conversation, and it is close to 600K... So no surprise there...

    Browsing thru the file, it looks to me to contains things that are not applicable for Espruino... overhead y0u may not even need... it just comes in because it was configured so.

  • Mon 2019.07.29

    'Is there a list of JavaScript features/libraries available'

    https://github.com/espruino/Espruino/treĀ­e/master/libs

    Not entirely sure if this satisfies your 'features' request

    http://www.espruino.com/Reference


    'what you mean by saying "around 40k JS code"'

    In #4 my request enabled you the discovery of total space available. The suggestion of reading over the 'Internals' documentation will show a JsVar is typically 12 or 16 byte blocks. I mentioned in#4 the ability to u/l a 30K file with mixed code/comments to a Pico. Gordon suggests a possible larger file. It all depends on coding style. At roughly 30 bytes/line of code would generate ~1000 code lines file length. Gordon's estimate seems to be a direct 2500*16 bytes/JsVar == 40000 total bytes of Javascript code. Feel free to use your best estimates.

  • There's http://www.espruino.com/Features

    re 40k: It depends how you upload (to RAM or flash) - see http://www.espruino.com/Saving

    There is 40k of flash available for code so if you had 40k or under of JS file then you would be able to upload that to flash. Of course it may need more RAM when it ran.

    Please could you share your original (unbundled) source file? We might be able to suggest some things to let you fit it in since I'm sure your original 'engine' file would be small enough to fit.

    While Espruino doesn't support Async it does support promises, and I'm pretty sure a decent transpiler would be able to convert your code without much overhead. I'd be amazed if it couldn't be modified very easily to run without the Buffer, tiny-stack and EventEmitter code that you have.

  • Hello @Gordon, sorry for the late reply. Is there a documentation for how much flash is available for code? I was under the impression that 512kb Flash refers to space available for my program.

    I have tested some of the devices I have using various file sizes (see attachments). I tested them using the save() method as well as E.setBootCode(). For the Pixl.js 5.000kb using E.setBootCode() seems extremly low.

    (I generated these file sizes using a long string. I tried a different method as well, but that led to simlar results.)


    2 Attachments

    • Selection_002.png
    • Selection_003.png
  • The Pixl (and pretty much all the nRF52 based Espruino boards afaik) have 40kB of available flash for code. Sadly the rest is taken up with the interpreter and Bluetooth stack.

    The issue you're having is that by just sending a big string in one go you've got to have a bunch of available RAM - not just for the string which will come in piecemeal, but for the interpreted version of it as well.

    You could try sending code from the right-hand side of the IDE using the 'direct to flash' upload mode - the IDE will automatically split longer text up into smaller chunks in order to be able to use the 40k.

  • I have not used the IDE to test this, but the espruino npm package. As far as I understood the "direct to flash" method uses E.setBootCode() under the hood, which I have used in the second attachment as well.

    What would be the difference between a long string and code for the interpreter? Is there a reasonable way to benchmark this?

  • Exact numbers can be read via Storage.getFree and Flash.getFree "Storage" size is configured at firmware build time to 40KB, "Flash" is unallocated free space between end of interpreter code and beginning of Storage that could be added to Storage if configured so. So to guess the maximum possible size add those two sizes (could be e.g. 60-70KB instead of 40) . If it is still not enough then custom build with reduced functionality may give you even more.

    Minification and maybe also pretokenization ("Pretokenise code before upload (BETA)" choice in web IDE) will help too.

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

Trouble uploading code to PIXL.js

Posted by Avatar for Proceed @Proceed

Actions