boot.py versus main.py



  • Folks:

    I’m having a little trouble understanding why there are separate boot.py and main.py files. In my testing, both are executed every time the board boots, is reset, and wakes from deep sleep. Is there ever a time when one is executed and not the other? Any guidelines or rules of thumb on when to prefer putting code in one over the other? Barring that, my inclination is to leave boot.py stock and put all of my application in main.py.

    Cheers,
    Tim



  • @reidfo I use the boot.py to mount the SD card just once. When I mounted the SD card in the main.py I encountered OSError when re-running my code in the REPL (OSError: the requested operation is not possible) due to the fact that I cannot check the status of the SD card.



  • @reidfo We haven't gotten to the stage of OTA upgrades, so I hadn't thought about it that way. Thanks for the great tip!



  • @robert-hh For one of our main uses, the last line of boot.py is deepsleep so technically boot.py never exits, but I hear what you are saying.


  • Global Moderator

    @reidfo That sounds OK, but technically is not necessary. Once a file is imported or loaded, it can be replaced. So boot.py could replace itself, even if that is not recommended for a fail safe operation.



  • @tshead One of the reasons to separate boot and main is in the case of OTA upgrades. In my application, I have a function (in main.py) that downloads and stages an application upgrade, including a new boot.py, then resets the device. Boot.py sees the upgrade has been staged and installs it, including a new main.py, then resets the device again. Doing it in two stages like this allows updating the code in both boot.py and main.py while the device is running and not worrying about side effects of replacing code that is currently executing.


  • Global Moderator

    @john-baird You do not need it, but an attempt will be made to run it, if eventually boot.py finishes. If it not exists, an error is raised. But main.py just have to exist as a file. It can be empty.



  • @robert-hh said in boot.py versus main.py:

    1. main.py (or other) which again must be in the file system.

    Would it be clearer to say:

    1. main.py (or other) which is expected in the file system

    As I understand it, technically you don't need a main.py at all. If the function is small and self-contained the entirety of the code could be placed into boot.py. For example, a simple task that wakes, reads a sensor, reports the value, goes back to sleep and then repeats forever doesn't really need a main.py

    Or have I missed something?


  • Global Moderator

    @tshead Boot.py and main.py are executed in exactly the same context one after the other. So you can put your code into either one. To be more detailed, there are four scripts which are potentially run on boot:

    1. _boot.py which has to reside in flash
    2. boot.py which must be in the file system
    3. _main.py which is expected inside the flash
    4. main.py (or other) which again must be in the file system.

    Steps 2. -4. are skipped during safeboot. step 4 is only executed in the so called PYEXEC_MODE_FRIENDLY_REPL, which is the normal REPL mode after boot. 3. was added to allow people to put their main.py into the flash memory.



  • @robert-hh - thanks for the clarification, I hadn’t noticed machine.main(). While it’s nice that you can choose to execute a different file, that doesn’t really address the question of why I’d split my app into two separate files to begin with. Are there operations that can only be performed in boot.py? Operations that can’t be performed there? Does something special happen between execution of boot.py and main.py?

    Many thanks,
    Tim


  • Global Moderator

    @tshead boot.py is executed always. In boot.py you can define another script to be executed instead of main.py. The command to do so is machine.main().



Pycom on Twitter