Over the air (OTA) firmware update (LoPy4)

  • Hi

    I am trying to do a OTA firmware update using this guide, where I ran into some issues.

    From the docs:
    Firmware: These files should be named in the format firmware_VERSION.bin, where VERSION is a a version number compatible with the python LooseVersion versioning scheme (http://epydoc.sourceforge.net/stdlib/distutils.version.LooseVersion-class.html).

    This file should be in the format of the appimg.bin created by the Pycm firmware build scripts.

    I downloaded 1.18.1.r1 firmware from here and got the following files after unpackaging:
    appimg.bin, bootloader.bin, lopy.bin, partitions.bin and script.file
    Do I simply rename the appimg.bin to firmware_1.18.1.r1.bin and place it in the directory specified in the docs?


  • Has anyone runs the ota service without errors?

    My ota service ran into an error at rename files from boot.py to boot.py.new

    But why??

  • This post is deleted!

  • Additional info:
    I am able to do an OTA update, i.e. changing from green to blue light as in the script/guide previously linked. However, its when I add the firmware.bin files to the directory I get errors, like the one shown in the post before this one.

  • @iwahdan @rskoniec thanks.
    I am however still having problems.
    I just renamed all the 1.16.0.b1 files to 1.0.0 and 1.18.1.r1 to 1.0.1 to avoid this as stated in the OTA_server.py (because I dont know how to):

    # In order for the URL's to be properly formatted you are required to send a
    # "host" header along with your HTTP get request e.g:
    # GET /manifest.json?current_ver=1.0.0 HTTP/1.0\r\nHost:\r\n\

    In my IDE where I am running the OTA_server.py I get the following error message when requesting:

    Got query for: /manifest.json?current_ver=1.0.0
    192.xxx.xx.xx - - [26/Oct/2018 11:12:31] "GET /manifest.json?current_ver=1.0.0 HTTP/1.0" 200 -
    Generating a manifest from version: 1.0.0
    Exception happened during processing of request from ('192.xx.xx.xx', 53954)
    Traceback (most recent call last):
      File "C:\Python37\lib\socketserver.py", line 313, in _handle_request_noblock
        self.process_request(request, client_address)
      File "C:\Python37\lib\socketserver.py", line 344, in process_request
        self.finish_request(request, client_address)
      File "C:\Python37\lib\socketserver.py", line 357, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "C:\Python37\lib\socketserver.py", line 717, in __init__
      File "C:\Python37\lib\http\server.py", line 426, in handle
      File "C:\Python37\lib\http\server.py", line 414, in handle_one_request
      File "C:\Users\user\Desktop\OTA\OTA_server.py", line 156, in do_GET
        manifest = generate_manifest(current_ver, host)
      File "C:\Users\user\Desktop\OTA\OTA_server.py", line 278, in generate_manifest
        latest = get_latest_version()
      File "C:\Users\user\Desktop\OTA\OTA_server.py", line 184, in get_latest_version
        if latest is None or LooseVersion(latest) < LooseVersion(d):
      File "C:\Python37\lib\distutils\version.py", line 52, in __lt__
        c = self._cmp(other)
      File "C:\Python37\lib\distutils\version.py", line 337, in _cmp
        if self.version < other.version:
    TypeError: '<' not supported between instances of 'str' and 'int'

    I placed some x's in my IP adress to hide it, and replaced my username with "user" in the code block above, fyi.

  • @asb yes, Also make sure your Lopy4 is on the same network as your OTA server.

  • @asb I thing that version folder names should correspond with the fw file names (firmware_VERSION.bin = folder name VERSION) so:
    for firmware_1.16.0.b1.bin your version folder name should be 1.16.0.b1
    for firmware_1.18.1.r1.bin your version folder name should be 1.18.1.r1

  • @iwahdan
    I tried again today, but got the same error, this time my SERVER_IP was the one I found after writing ipconfig in cmd (IPv4 address).
    Is this the correct address to use?

  • @Asb I think you are putting the wrong Server IP, the local host and you are running this code from LoPy4 so you must enter correct Server IP.

  • @iwahdan, @robert-hh Thanks.

    I renamed the lopy4.bin to firmware_1.18.1.r1.bin, similar for the 1.16.0.b1 firmware and have the following directory:

      - server directory
        |- OTA_server.py
        |- 1.0.0
        |  |- flash
        |  |   |- lib
        |  |   |  |- OTA.py
        |  |   |- main.py
        |  |   |- boot.py
        |  |   |- config.py
        |- 1.0.1
        |  |- flash
        |  |   |- lib
        |  |   |  |- OTA.py
        |  |   |- main.py
        |  |   |- boot.py
        |  |   |- config.py
        |- firmware_1.16.0.b1.bin
        |- firmware_1.18.1.r1.bin

    Inside config.py (in both 1.0.0 and 1.0.1 folder) I have the following:

    WIFI_SSID = "not show here"
    WIFI_PW = "not shown here"
    SERVER_IP = ""

    My main.py is the same as the one shown in the docs, only thing I've changed is removing the need to send a downlink message from the things network to initiate the OTA update, therefore my main loop looks like this:

    while True:
        print("Performing OTA")
        # Perform OTA

    When I try to initiate the OTA update:
    I run the OTA_server.py script using Python 3.7.1 and get no errors. Then I upload the project folder to the lopy like this (folder 1.0.0):

    Then I get this following error:
    0_1540448208051_firmware_error http.PNG


  • @robert-hh yes sure, but using OTA update via the HTTP server, only require firmware to be named firmware_VERSION where VERSION should be following python LooseVersion versioning scheme, so it is the same weather to rename appimg.bin or lopy4.bin
    As for ftp updater, considering removing appimg.bin from FW packages, will require update to ftp server for sure.


  • @iwahdan The ftp.updater expects the target name to be:
    So you are not free to give the image any name when uploading. Of coures you can do that on your PC, but it should include the target platform. And when uploading, the file name for storing must also be pre-defined.

  • Hi @Asb , actually appimg.bin and lopy4.bin , are identical (redundant) binarys, I recommend you rename the lopy4.bin to firmware_1.18.1.r1.bin because we are planning to remove the appimg.bin from the firmware package eventually.

Log in to reply

Pycom on Twitter