simple explanation how to save code that espruino run on start? #6281
Replies: 1 comment
-
Posted at 2015-12-03 by Ollie I do it like this:
My undertstanding is that Posted at 2015-12-04 by @MaBecker I do it like this:
Posted at 2015-12-04 by @gfwilliams
Your main problem though is you're not initialising the oled display in onInit. Try:
Posted at 2015-12-04 by bigplik Oli and Gordon, the way your wrote isn't working, OLED doesn't start after reset,
btw. is this save operation store some data on the MCU every save I make? I mean should I flash espruino to save space on the mcu or during save oparation it will erase all old data and replace them with new one? Posted at 2015-12-04 by @MaBecker you can list your saved code by using dump();
and than check for the error. Posted at 2015-12-04 by DrAzzy
save() writes the current contents of all JSVars to the flash, replacing whatever was previously there. Then it resets the Espruino and runs onInit(). You can also, instead of saving, send the code and just manually kick off onInit() or the function you'd reference from E.on("init",...). Posted at 2015-12-05 by @allObjects A few things... like 2 cents :) Something most not-understood about Javascript Espruino is the fact that - with default settings - source code from within the IDE code editor is already processed - executed - by Espruino interpreter on the board on upload and *stored in the (volatile) RAM only. An upload independent Upload on Espruino uses the REPL nature and state of Espruino in connected mode and the interpretative nature of JavaScript with the small modification: no-print: echo is while uploading. About REEPL, see for example Wiki Read-eval-print_loop. Let's play out the story on 'the subject' while moving on in this post. For that, we start with a clean slate: connect to the board with the Web IDE and enter That any code is processed by Espruino on upload becomes most noticeable when sending following code source string At the very moment the code arrives - streams in - to Espruino board, Espruino's Javascript interpreter interprets it, and therefore turns LED1 on. Let's look at some more things we upload - one after the other: The code source string The code source string For the sake of understanding what Espruino treats save() just the same way as it did previous digitalWrite(..., var... and function(...: Espruino interprets save() and while doing justice to the 'command' it saves - or - simply copies the RAM content to the FLASH, which means that now the value 5 as variable named v and the source of the function body as function named turnOnLED1 are stored in Espruino's FLASH... firmly and safe from power loss... and for 're'-use... later on. Disconnect Espruino from Web IDE and de-power/unplug it, then plug it back in and re-connect. The LED1 is not/does not come on, and nothing else really visible happens... but Espruino copies the FLASH content back to RAM - restores the Espruino machine state, such as the RAM (and some other things) so they becomes accessible / usable again: Just type Looking at any of your code you upload, you will see just 'code pieces' that have either immediate effect or are 'stored' under a name for 'later' use. For example, if you want to turn on LED1 on power on, add (upload), for example, Note: If you use the Web IDE editor for entering the code, the final code you upload and save looks like the code below. The save() is NOT part of the uploaded code. You enter save() command after uploading the 'final cod version'; save() is only used when the code ready to be run in disconnected, re-powered state. To save intermediate states, use the save code to disk and load code from disk functions (buttons located just above upload to board button).
On power on, Espruino looks for onInit() function in RAM and executes it as first thing, after it has restored RAM content from FLASH. In (most) other environments, on power on, (application) code execution starts at a particular, predefined location in the FLASH. There is more to upload and save, such as uploading referenced modules and minification of uploaded code - latter to use less memory and execute/interpret faster... - ...'saved' for another post. Posted at 2015-12-05 by Spocki @allObjects great explanation, eagerly awaiting your next post about modules and hardware initialisation. Posted at 2015-12-06 by tve I'm also struggling with the save()/restore() stuff. I would like the following set-up:
I can't figure out how to make this work. When the IDE does a reset() the saved variables are not loaded. The environment is literally empty. I tried to use load() at the start of my file, but it causes a reset also, and seems to have a pile of side-effects on the parsing of the remainder of the file. Any ideas? Posted at 2015-12-07 by @gfwilliams @tve sounds like for you, the best solution would be if the Web IDE issues a A simple hack is just to do There was a post a while back about adding something like Posted at 2015-12-07 by @allObjects @tve, how about putting your default stuff in a module (in project folder modules) from where you can grab it? For example:
Posted at 2015-12-07 by tve good idea! Posted at 2015-12-22 by Ollie What is the best way to Posted at 2015-12-22 by @MaBecker I use the IDE as chrome APP and set up a project, Posted at 2015-12-22 by @gfwilliams Yep - The only thing you have to watch out for is if you've got any external components that need configuring after power-on (like a display). In that case you need to put the initialisation code in Posted at 2015-12-22 by Ollie @MaBecker @gfwilliams thank you both. This is what I thought should be happening and what I've been doing. Thanks for confirming. Posted at 2016-01-13 by @allObjects Two more cents... about save() and power-on reset / power cycle... actually only 1 cent for now, since this post covers only delays in detail. Callbacks are covered in a next post. @spocki and @marcom - and @ollie, here you go: Think about your electronics / hardware: some things you time - delay - with an RC-circuit, and some you setup for trigger - callback - on a rising or falling edge. That sums it up quite simply... and may be a bit too simply, but it is a good starting point. Complexity arises then when you want to bring a lot of these into sequence and and more so when it is a mix and match. Not much different is it with software. The means are a bit different, but you still need to do the proper setup and do the enabling for the right time. As you know from electronics, some ICs have power-on / reset sequencing /setup / stabilization dependencies, and you have to wait before you can 'use' the IC. Even Espruino with its STM MC and the elaborate Espruino firmware have a power on reset sequence. The sequence is a combination of various hardware and (low level / internal) software tasks, after which - at last - Espruino firmware invokes
All function registered with
Doing the same with
You can run the examples above one by one by pasting them into the editor pane of the Espruino Web IDE and then upload them to the board. All the above works nicely - in intended sequence - when these functions are simple, blocking, synchronous function. Blocking means:
Unfortunately - and actually fortunately - the world is not that simple: there are functions that need some time to complete and they are implemented the way that they do not block the processor so that the processor can execute other things 'at the same time'... for the common benefit. Some function may take specified time to execute, and some use some unspecified time - unspecified in the sense that they depend on something else to happen before they can complete their work. Such functions behave asynchronously, non-blocking, which means:
That puts the simple - linear, sequently - invocation into trouble! Assume that the work of
This adds some quirk to our simple initialization work, namely:
Which means - with given initialization code using
Not exactly what we expect... See yourself by using Indeed you will see the unexpected result... But: We can easily fix that, because we know what really happens. We fix it by delaying 'everything' (in the initialization) after invocation of yourStartFuncA() for as much time it takes to complete the work of yourStartFuncA(). To be safe, we chose 1100 ms. For example (using
Run the the code with above modification in
Having more than just one 'delaying' function in the initialization sequence will challenge the statement because we know what's going on therefore we can easily take care of dalays.... That's when other options have to come in, and that is a sequencer that allows timing... For additional details see posts in conversations:
To make a timed initializer - using
NOTE 1: IN NO PLACE YOU SEE save() AS PART OF THE CODE. It is though entered and executed in the console AFTER UPLOADING THE CODE. Note 2: Holding on to the module with an extra variable as in the code in the post where the
In some other place, later on, module2 would deliver the very same module - but now connected - as above:
node.js (nodejs.org)'s Posted at 2016-01-22 by zyxyz Very clear and detailed. Thanks. One small question. For the Arduino(Uno) they are distinguishing between Flash memory and EEPROM. Are they the same for the Espruino ? Posted at 2016-01-22 by DrAzzy The Arduino boards have EEPROM because it's built into AVR chips they use. The Espruino boards don't have EEPROM built in - STM32 chips don't include any EEPROM. There's a "fake EEPROM" module that uses the flash (flash that's not being used to store code, ofc) to give functionality that looks a lot like EEPROM: Or you can connect an external EEPROM: Posted at 2016-01-23 by @allObjects EEPROM is more general term for Electrically Erasable Programmable Read Only Memory, an evolution of the EPROM (which had to be reased w/ UV light), an (functional) evolution from PROM - one time programmable only, an (functional) evolution from ROM - content 'hardwired'/set in stone on 'build time'. There are various types of memory cells, wirings, and control logic in use in EEPROMs which make them either a byte-wise erasable / programmable (writeable) memory, versus a Flash one which can only block-wise erasing and (mostly) byte-wise programming. Erasing means to set all bits to 1, and programming means make some 0. Depending on cell type it can be 0 and 1 vs. 1 and 0. Depending on the 'luxuriousness' of the driver available to the application code to drive the EEPROM, the erasing and programming and byte- and block-wise operation is transparent: it is just simple read and (re)write for the application. Elaborate drivers also take care of the balanced erasing (and programming), because the prevalent EEPROMS have an 10'000...100'000 erase/write cycle limit. Technologies though get better and better and some have practically unlimited cycles and can be used like RAM (MRAM, and to a lesser extent, FRAM). Today's SSD - Solid State ('Hard') Drives fair almost unlimited. Flash vs. 'plain' EEPROM in a nutshell: Flash is a particular EEPROM (more details). Posted at 2016-06-22 by Filip The following code seems valid but the led is not blinking. The console output is correct. It is as if digitalWrite is not working.
Posted at 2016-06-22 by @allObjects Your code is absolutely 'fine'. To verify, I used onboard red
You have nothing 'active / immediate' in your code that you upload. The code just defines several functions but nothing invokes any of them.
There is an option in the settings that saves the code automatically after upload (to cater to Arduino souls...). I assume, you entered the code in the right pane of the Web IDE - the editor - and uploaded it. After doing above, you enter in the left pane - the console - My only recommended change in your code is to initialize toggle with true or false... which is perfectly understood as value by Posted at 2016-06-22 by Filip hi @allObjects , thanks for your quick response and recommendations. I just want to clarify two things.
Posted at 2016-06-22 by DrAzzy Does putting a pinMode(D5,"output"); into onInit() fix it? (if it does, it's still a bug, but at least we know which one it is). What board are you using? What version of Espruino? Posted at 2016-06-23 by @gfwilliams I imagine it could be an ESP8266 board, with an old version of Espruino? Newer versions shouldn't need you to call Posted at 2016-06-23 by Filip @drazzy thanks for the tip it has worked when I called the pinMode beforehand. Hi @gfwilliams, it seems also newer versions need pinMode call because I have a nodeMCU ESP-12E with espruino_1v85 Posted at 2016-06-24 by @gfwilliams Ahh, ok, thanks - I need to release a new version then. There are 'nightly' builds which most people use it seems, and I think those have it fixed. Posted at 2020-06-20 by @allObjects @filip (post #24), you just go lucky... it is still a bad idea to start timers in the root level / level 0... you are saving the timer in the state it was (and luckily, @gfwilliams wrote the power-up of a saved state to restart the timers...). If your code is a bit more complicated, it may not even upload properly. (Sorry for the 'delayed' response). |
Beta Was this translation helpful? Give feedback.
-
Posted at 2015-12-03 by bigplik
hi, I play now a couple hours with save and onInit function and can't run my program when my pico is starting after reset (unplug from usb), is there any simple explanation?
here is the code
Beta Was this translation helpful? Give feedback.
All reactions