This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Updating nrf9160 modem firmware through the command line

We are producing a batch of nrf9160 based devices and will need to upgrade the modem firmware, this will be much easier if we could do this through the command but I saw on modem firmware version 1.0.0  and after, you no longer provide a flashing tool and recommend nRF Programmer.

Can the old nrf9160_mdm_dfu be used with the newer modem firmware or how would you recommend upgrading modems through the command line?

  • Hi,

    It's possible to use a python script with pynrfjprog to flash the modem. 

    Simple example:

    #!/usr/bin/env python3
    #
    # Copyright (c) 2019 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
    
    
    from pynrfjprog import HighLevel
    api = HighLevel.API()
    api.open()
    snr = api.get_connected_probes()
    for s in snr:
        probe = HighLevel.IPCDFUProbe(api, s, HighLevel.CoProcessor.CP_MODEM)
        probe.program("mfw_nrf9160_1.0.1.zip")
        probe.verify("mfw_nrf9160_1.0.1.zip")
        print("Done")
     
    api.close()

    With threading[experimental]

    #!/usr/bin/env python3
    #
    # Copyright (c) 2019 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
    
    from pynrfjprog import HighLevel
    import threading
     
    class myThread (threading.Thread):
       def __init__(self, threadID, name, counter):
          threading.Thread.__init__(self)
          self.threadID = threadID
          self.name = name
          self.counter = counter
       def run(self):
          print ("Starting " + self.name)
          update_fw(self.name)
          print ("Exiting " + self.name)
     
    def update_fw(snr):
        print("updating FW in {}".format(snr))
        probe = HighLevel.IPCDFUProbe(api, int(snr), HighLevel.CoProcessor.CP_MODEM)
        print("{} probe initialized". format(snr))
        probe.program("mfw_nrf9160_1.0.1.zip")
        print("{} programmed".format(snr))
        probe.verify("mfw_nrf9160_1.0.1.zip")
        print("{} verified".format(snr))
     
    # Create new threads
    api = HighLevel.API()
    api.open()
    devices = api.get_connected_probes()
    threads = list()
    for idx, device in enumerate(devices):
        threads.append(myThread(idx, device, idx))
     
    # Start new Threads
    for thread in threads:
        thread.start()
     
    print("waiting for all threads to complete")
    #wait for threads to finish
    for t in threads:
        t.join()
     
    api.close()
    print("Exiting Main Thread")

  • I'm having issues with the DLL file on "HighLevel.IPCDFUProbe(...)", I'm on Linux so guessing it means the .so file

    import argparse
    import os
    from pynrfjprog import HighLevel
    
    
    def main():
        parser = argparse.ArgumentParser(description='Update modem firmware of nrf9160 devices.')
        parser.add_argument('-f', '--firmware', dest='firmware', type=str, help='Absolute path to modem firmware zip')
        args = parser.parse_args()
        if args.firmware is None:
            print("ERROR: Path to firmware was not given")
            return -1
        if not os.path.exists(args.firmware):
            print("ERROR: {} does not exist".format(args.firmware))
            return -1
    
        api = HighLevel.API()
        api.open()
        snr = api.get_connected_probes()
        for s in snr:
            probe = HighLevel.IPCDFUProbe(api, s, HighLevel.CoProcessor.CP_MODEM, jlink_arm_dll_path="/opt/nrfjprog")
            probe.program(args.firmware)
            probe.verify(args.firmware)
            print("Done")
    
        api.close()
        return 0
    
    
    if __name__ == "__main__":
        main()
    

    I get -100 JLINKARM_DLL_NOT_FOUND when I point to a folder containing some .so files. I also tried pointing to /opt/SEGGER/Jlink

    I get -151 NRFJPROG_SUB_DLL_COULD_NOT_BE_OPENED if don't specify the path

  • What version of nrfjprog and pynrfjprog are you using ?

    There are some reported issues with nrfjrpog 10.4.0 on Linux, so at the moment you should try to use 10.3.0 on linux for nrfjprog and pynrfjprog.

    It could be that you have an older pynrfjprog installed. Try to run this:

    pip3 install pynrfjprog==10.3.0 -U

  • Ok that seemed to work, is there a way to add some debug information during the flashing and verifying?

    I see within IPCDFUProbe, logging is enabled by default but I don't see any logging

  • Hi,

    is there a way to add some debug information during the flashing and verifying?

    Yes.

    Take look at this file. Logging level is set to INFO here.

    #!/usr/bin/env python3
    #
    # Copyright (c) 2019 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
    
    import os
    import time
    import argparse
    import subprocess
    import logging
    from tempfile import TemporaryDirectory, mkstemp
    from pynrfjprog import HighLevel
    
    logging.basicConfig(level=logging.INFO)
    log = logging.getLogger('modem_update')
    
    
    def flash_modem_pkg(modem_zip, verify):
        start = time.time()
        with HighLevel.API(True) as api:
            snr = api.get_connected_probes()
            for s in snr:
                log.info("Establish board connection")
                log.info(f"Flashing '{modem_zip}' to board {s}")
                with HighLevel.IPCDFUProbe(api, s, HighLevel.CoProcessor.CP_MODEM) as probe:
                    log.info(f"Programming '{modem_zip}'")
                    probe.program(modem_zip)
                    log.info("Programming complete")
                    if verify:
                        log.info("Verifying")
                        probe.verify(modem_zip)
                        log.info("Verifying complete")
            api.close()
            log.info(f"Completed in {time.time() - start} seconds")
    
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument("modem_pkg")
        args = parser.parse_args()
        log.info("Modem firmware upgrade")
        flash_modem_pkg(args.modem_pkg,True)
    
    if __name__ == '__main__':
        main()

    (Using f-Strings(introduced in python 3.6))

Related