What happens when you upload code

Posted on
  • Nowadays, when working with computers - and micro controllers in Arduino style or context, we use some kind of editor where we enter the (source) code or program, then we run it thru some steps, like building an executable, then copy that executable to the computer or micro controller where we want to run it - when the runtime computer is a different one form the one we developed the code on, and finally, we invoke the run-ready code - or bring it to live, so to speak. We consider the source code and also the file with the executable as static - non active - sequence of bytes or code up to the point of executing / invoking / starting / running it.

    But with Espruino - an interpretative system - there is no concept of static code... all is active, because it is not like uploading an .exe file and then later make the computer to load and execute / invoke / start / run it. Even more confusing because not obviously visible: Espruino IDE uses the one and same channel - serial / USB - for communicating directly your entries in the left pane - the console or terminal - to Espruino as well for the uploading of your code from the edit pane - the code editor (and for even more things, such as inspecting variables, sophisticated step-by-step walking through the code for debugging, and for the testing feature... that by the way can draw nice graphs of values and functions at custom defined time ticks).

    You can make a simple test (on a freshly flashed or empty code saved) Espruino device that you just plugged-in/wired to your computer with the IDE and connected in the IDE.

    I the phase 1 - steps a thru c - we work in the left pane of the IDE - the terminal or console (Enter means type and at the end press Enter key):

    a. Enter just myGlobalVar;: the response is something like second last line of:

     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     1v99 (c) 2018 G.Williams
    >
    Connected to port /dev/cu.usbmodem1421
    >myGlobalVar;
    Uncaught ReferenceError: "myGlobalVar" is not defined
    > 
    

    This is a short for of print(myGlobalVar); or console.log(myGlobalVar); and means: show me the value of global variable named 'myGlobalVar'. Since Espruino does not know yet about myGlobalVar it reports an ReferenceError exception, because the variable is not defined yet. (Errors are also called Exceptions to indicate 'negative exceptional' outcome or event, which usually stops code execution. To prevent stopping execution, JavaScript - like many other languages - provides a try-catch construct to catch the exception, handle it, and resume accordingly: 'try { ...code... } catch(x) { console.log("Exception: " + x); } ).

    b. Enter var myGlobalVar = "myStringValueAsAssignedToGlobalVariable­NamedMyGlobalVariable";: the response is something like 2nd line of:

    >var myGlobalVar = "myStringValueAsAssignedToGlobalVariable­NamedMyGlobalVariable";
    ="myStringValueAsAs" ... "dMyGlobalVariable"
    > 
    

    This expression defines the variable and assigns the value. Since the assignment as as the last part of the expression returns the assigned value, the result is shown as ="... in the console.

    c. Now you enter again just myGlobalVar;: the response is something like 2nd line of:

    >myGlobalVar;
    ="myStringValueAsAs" ... "dMyGlobalVariable"
    > 
    

    This shows that Espruino has obviously remembered the variable and its value from execution of var .... statement from before. It is somewhat expected.

    Unplug your Espruino device, so it looses all what is in RAM..., then replug and reconnect for phase 2:

    For phase 2 - step d thru i - we work in both sides of the IDE and use also the upload button:

    1. one step - d - in the left side
    2. two steps - e and f - in the right side of the IDE - the code editor
    3. one step - g - in the left side
    4. one step - h- using the upload button in the vertical bar between left and right side of the IDE
    5. one step - i - in the left side, again

    So there we go:

    d. In the left side, enter just myGlobalVar;: the response is the same as we got in step a: ReferenceError; it shows that Espruino has lost its mind... eh, memory ;-)

    e. Delete what may be in the editor pane on the right side.

    f. In the right side, enter as only line (the line number - 1 - is not part of it):

    var myGlobalVar = "myStringValueAsAssignedToGlobalVariable­NamedMyGlobalVariable";
    

    g. Repeat step d. As expected, we get still ReferenceError exception, because we entered just some text in a code editor.

    h. Click the "Upload" button in the middle vertical bar: the response - in the left side - is this:

    >
     ____                 _
    |  __|___ ___ ___ _ _|_|___ ___
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     1v99 (c) 2018 G.Williams
    >
    =undefined
    > 
    

    The output indicates, that any eventual code still left in Espruino RAM has been cleared and the code from the right side has been uploaded...

    i. In the left side, enter just myGlobalVar;: the response is:

    >myGlobalVar;
    ="myStringValueAsAs" ... "dMyGlobalVariable"
    > 
    

    which proofs that something substantial happened on upload 'in' the Espruino board... and not just copying of some bytes to it.

    *** So, what happened in phase 1: ***

    Espruino is listening to what you type in left pane. Every key you type, is directly sent to Espruino, and Espruino echoes it back to the console so you can see what you typed. In addition to just echoing it back, it checks if it was an Enter key. If so, it looks at it and tries to make sense out of it in the sense of JavaScript... since JavaScript is all it understands. If it can make sense out of it and it is a complete JavaScript expression, it executes it and shows the response in the console... and there is always a response: the value returned by the expression... and if the expression does not return nothing, undefined is returned.

    If what you entered makes sense in JavaScript but is not a complete expression yet, Espruino continues to prompt you to enter more, until you complete the expression for exection.

    In step a you entered myGlobalVariable which is the short form of print(myGlobalVariable); or console.log(myGlobalVariable); - print the value of myGlobalVariable in the console. It seems that print is a command that Espruino understands, but you well know, that print(...) and console.log(...) are expressions - or statements - in the JavaScript language. Therefore, you rightly conclude commands and statements are the same... and they are. They are as long as you are in the JavaScript interpreter; and with Espruino, there is no other state you are in when it is powered on and connected with the IDE... even when something of yours - some code - is running and you are connected, you can give / enter commands - or statements - in the left side and Espruino acts on it (...a bit simplified, but good enough for your test here).

    For step b, you now corollary conclude: var is a command or statement too, that expects at mandatory parameter - so to speak - the name of the variable to declare ***AND establish in memory with a value - to be precise though: with the pointer to the location in memory where the value is stored. var myGlobalVar = "myStringVAATGVNMyGlobalVariable"; makes Espruino to actually create a global variable in memory with the name myGlobalVar and a pointer to the string in memory that holds myStringVAATGVNMyGlobalVariable. If you leave out the assignment by entering only var myGlobalVar;, Espruino still creates the variable in memory but with a pointer to point to nothing, and that's why you also get undefined returned, even though it is defined as a variable but has not value assigned yet... (to be precise here as well: Espruino goes even a step further than JavaScript and tells you the difference between a variable that is "not known" vs. a variable that is "not initialized" with a value... (which is the same as assigning undefined to a variable with var myGlobalVar = undefined; - or later in the code (just): var myGlobalVar = undefined;

    I guess we are clear with that now.

    *** Let's look what happened in phase 2: ***

    If I tell you that in phase two happens nothing different that what happens in phase 1, step b, you say: 'piece of cake'... and you even get to eat it... including great Espruino icing! (Others = such as a public speaker - would now make a Lumberjack joke here to pay homage to @Gordon!):

    Upload button takes your code from the right side - edit pane - and 'feeds it up - or down - the console throat piece by piece automatically... Before it does do so, it does some more house keeping to keep Espruino clean and your life easy.

    Clicking the Upload button does:

    1. switch echo off in the console - sneaky with: echo(0); (just another command or JavaScript statement that tells Espruino NOT TO RETURN / ECHO every character it receives...)
    2. then it sends the reset() command (btw. configurable in the IDE settings) to clear all code that may possibly be in the RAM from a previous upload or load or start)
    3. then it sends junk by junk (line by line) of your code in the console...
    4. then it sends as last echo(1) - no explanation needed for that - which makes Espruino to return the (regular) prompt, and thus the IDE knows that Espruino has gotten everything 'just fine'... and not only that, but has also executed what the code told to do, such as establishing variables by the var ... statement.

    You can validate that the line(s) has(have) been sent 'thru the console', when - subsequently to the upload - you click into the console area and use the arrow up to recall the last entered line... and you will be shown the single line that you just have uploaded.

    Same execution as for var ... happens also for function(...) {....}, including other commands / statements / expressions (for immediate execution / in level 0 / when not 'buried' in functions), such as pinMode(...), setTimeout(...), setInterval(...), require(...).connect(...).

    Now you can easy imagine, if some of these statements including setTimeout(...), setInterval(...), require(...).connect(...) keep Espruino (in JavaScript) very busy, IDE does not in time or never get the (regular) 'prompt', and then struggles to get other things done in order... and you get all kinds of weird side-effects, of which the upload-timeout error is the least difficult to (humanly) interpret...

    That function(...) {...} shows similar behavior as var ..., enter in the left the following code - even after uploading the code from the edit pane - in one line: function printMyGlobalVar() { console.log(myGlobalVar); }. This just adds to the code already in the RAM a globally known function with name printMyGlobalVar linked to the (source) code of the function as string, which consists the (empty) parameter list () and the body {...} (simplified). Now you call on this function in the left side by entering printMyGlobalVar();, and you will get the same result back as asking for the variable name directly with myGlobalVar;. If you forget the parenthesis / parameter list after the function name by just entering printMyGlobalVar, Espruino responds to you with function {... to tell you that it is a function.

    If you add the function definition for printMyGlobalVar in the right pane and upload the code again, you end up in the same state as just before, and you can invoke the function as well in the right hand side.

    And with that, you proofed to yourself, that Espruino executes code (on level 0) on upload.

    As a bonus, use LED1.set(); and LED1.reset() in a self guided test and observe when happens when entering in the console or upload it from the code editor. Then make variation of them: have them a) as single statement, b) 'buried' in (a) function(s) called ledOn(){...}; and ledOff(){...};, c) add additional line after the function invoking the ledOn(); function. Finally, you play with / invoke the function(s) in the left side to turn the LED1 on an off.

    PS: This tutorial was triggered by post of this conversation about ...WebIDE Connect - Unable to retrieve board information. Connection Error?, in which @Gordon posts as #6 the perfect example / analogy with JavaScript embedded in html, an example very well known and understood by Web (page) developers...

    What happens when you save code will come in a future conversation.

  • Tue 2018.08.21

    Goody-Goody - now we have great Espruino icing! Love the allegory @allObjects

    Will we get sprinkles in a future conversation?

    Informative and easy to grasp concepts. Nicely done. . . .

  • Updated initial post #1 with exact responses from Espruino (1v99).

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

What happens when you upload code

Posted by Avatar for allObjects @allObjects

Actions