How to perform an OTA update on the nRF5340 using a PC

Hi,

Currently, I know that OTA updates for the nRF5340 can be performed using Device Manager and the nRF Connect mobile application. However, if using a PC, is it possible to achieve the same functionality via the command line?

Thanks!!

Mike

Parents Reply Children
  • Hi Vidar,

    Yes, that’s correct. I am trying to run this on a Windows PC.

    I have already installed the smpmgr tool (version 0.17.0) on my Windows PC and attempted to perform FOTA on my nRF5340 device.

    However, I encountered the following issue. The error logs are shown below.

    C:\Users\user>smpmgr --ble E8:B8:C3:0E:CC:23 image upload C:\Users\user\Desktop\Mike\p1_v1.1.2_32M_12pF_dfu_application.zip
    [08:48:32] ERROR    Inspection of FW image failed - image_management:187                         image_management.py:187
                        ╭─────────────────── Traceback (most recent call last) ────────────────────╮
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-pack │
                        │ ages\smpmgr\image_management.py:184 in upload                            │
                        │                                                                          │
                        │   181 │   """Upload a FW image."""                                       │
                        │   182 │                                                                  │
                        │   183 │   try:                                                           │
                        │ ❱ 184 │   │   image_info = ImageInfo.load_file(str(file))                │
                        │   185 │   │   logger.info(str(image_info))                               │
                        │   186 │   except Exception:                                              │
                        │   187 │   │   logger.exception("Inspection of FW image failed")          │
                        │                                                                          │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-pack │
                        │ ages\smpclient\mcuboot.py:326 in load_file                               │
                        │                                                                          │
                        │   323 │   │   │   │   raise MCUBootImageError(f"hex2bin() ret: {ret}")   │
                        │   324 │   │                                                              │
                        │   325 │   │   f.seek(0)  # move to the start of the image                │
                        │ ❱ 326 │   │   image_header = ImageHeader.load_from(f)                    │
                        │   327 │   │                                                              │
                        │   328 │   │   tlv_offset = image_header.hdr_size + image_header.img_size │
                        │   329                                                                    │
                        │                                                                          │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-pack │
                        │ ages\smpclient\mcuboot.py:223 in load_from                               │
                        │                                                                          │
                        │   220 │   @staticmethod                                                  │
                        │   221 │   def load_from(file: BytesIO | BufferedReader) -> 'ImageHeader' │
                        │   222 │   │   """Load an `ImageHeader` from an open file."""             │
                        │ ❱ 223 │   │   return ImageHeader.loads(file.read(IMAGE_HEADER_STRUCT.siz │
                        │   224 │                                                                  │
                        │   225 │   @staticmethod                                                  │
                        │   226 │   def load_file(path: str) -> 'ImageHeader':                     │
                        │                                                                          │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-pack │
                        │ ages\smpclient\mcuboot.py:205 in loads                                   │
                        │                                                                          │
                        │   202 │   │   │   flags,                                                 │
                        │   203 │   │   │   *ver,                                                  │
                        │   204 │   │   ) = IMAGE_HEADER_STRUCT.unpack(data)                       │
                        │ ❱ 205 │   │   return ImageHeader(                                        │
                        │   206 │   │   │   magic=magic,                                           │
                        │   207 │   │   │   load_addr=load_addr,                                   │
                        │   208 │   │   │   hdr_size=hdr_size,                                     │
                        │                                                                          │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-pack │
                        │ ages\pydantic\_internal\_dataclasses.py:121 in __init__                  │
                        │                                                                          │
                        │   118 │   def __init__(__dataclass_self__: PydanticDataclass, *args: Any │
                        │       None:                                                              │
                        │   119 │   │   __tracebackhide__ = True                                   │
                        │   120 │   │   s = __dataclass_self__                                     │
                        │ ❱ 121 │   │   s.__pydantic_validator__.validate_python(ArgsKwargs(args,  │
                        │       self_instance=s)                                                   │
                        │   122 │                                                                  │
                        │   123 │   __init__.__qualname__ = f'{cls.__qualname__}.__init__'         │
                        │   124                                                                    │
                        │                                                                          │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-pack │
                        │ ages\smpclient\mcuboot.py:218 in __post_init__                           │
                        │                                                                          │
                        │   215 │   def __post_init__(self) -> None:                               │
                        │   216 │   │   """Do initial validation of the header."""                 │
                        │   217 │   │   if self.magic != IMAGE_MAGIC:                              │
                        │ ❱ 218 │   │   │   raise MCUBootImageError(f"Magic is {hex(self.magic)},  │
                        │       {hex(IMAGE_MAGIC)}")                                               │
                        │   219 │                                                                  │
                        │   220 │   @staticmethod                                                  │
                        │   221 │   def load_from(file: BytesIO | BufferedReader) -> 'ImageHeader' │
                        ╰──────────────────────────────────────────────────────────────────────────╯
                        MCUBootImageError: Magic is 0x4034b50, expected 0x96f3b83d
    
    C:\Users\user>

    I am not sure whether I am using the smpmgr tool correctly.

    Thanks!!
    Mike

  • Hi Mike, 

    The packaging of the DFU FW image(s) in a .zip (dfu_application.zip) is a nRF connect specific feature that only works with our DFU tools (in our mobile apps). This scripts expect to receive the binary inside the zip.

    Best regards,

    Vidar

  • Hi Vidar,

    Are you referring to directly using the zephyr.bin from the example project, or do we need to use additional tools to build the .bin file?

    Thanks!!
    Mike

  • Hi Mike,

    Just extract the dfu_application.zip file and used the bin contained in the folder. Or you can look for zephyr.signed.bin (zephyr.bin is the unsigned application) in build/<app name>/zephyr

  • Hi Vidar,

    Based on your suggestion, I extracted dfu_application.zip and used the .bin file inside to perform the update, but it seems that I am encountering a similar issue

    C:\Users\user\Desktop\Mike\p1_v1.1.2_32M_12pF_dfu_application>smpmgr --ble E8:B8:C3:0E:CC:23 image upload application.signed.bin
    [01:29:55] ERROR    Inspection of FW image failed - image_management:187                                                             image_management.py:187
                        ╭───────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────╮
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\smpmgr\image_management.py:184  │
                        │ in upload                                                                                                    │
                        │                                                                                                              │
                        │   181 │   """Upload a FW image."""                                                                           │
                        │   182 │                                                                                                      │
                        │   183 │   try:                                                                                               │
                        │ ❱ 184 │   │   image_info = ImageInfo.load_file(str(file))                                                    │
                        │   185 │   │   logger.info(str(image_info))                                                                   │
                        │   186 │   except Exception:                                                                                  │
                        │   187 │   │   logger.exception("Inspection of FW image failed")                                              │
                        │                                                                                                              │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\smpclient\mcuboot.py:331 in     │
                        │ load_file                                                                                                    │
                        │                                                                                                              │
                        │   328 │   │   tlv_offset = image_header.hdr_size + image_header.img_size                                     │
                        │   329 │   │                                                                                                  │
                        │   330 │   │   f.seek(tlv_offset)  # move to the start of the TLV area                                        │
                        │ ❱ 331 │   │   tlv_info = ImageTLVInfo.load_from(f)                                                           │
                        │   332 │   │                                                                                                  │
                        │   333 │   │   tlvs: list[ImageTLVValue] = []                                                                 │
                        │   334 │   │   while f.tell() < tlv_offset + tlv_info.tlv_tot:                                                │
                        │                                                                                                              │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\smpclient\mcuboot.py:255 in     │
                        │ load_from                                                                                                    │
                        │                                                                                                              │
                        │   252 │   @staticmethod                                                                                      │
                        │   253 │   def load_from(file: BytesIO | BufferedReader) -> 'ImageTLVInfo':                                   │
                        │   254 │   │   """Load an `ImageTLVInfo` from a file."""                                                      │
                        │ ❱ 255 │   │   return ImageTLVInfo.loads(file.read(IMAGE_TLV_INFO_STRUCT.size))                               │
                        │   256                                                                                                        │
                        │   257                                                                                                        │
                        │   258 @dataclass(frozen=True)                                                                                │
                        │                                                                                                              │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\smpclient\mcuboot.py:250 in     │
                        │ loads                                                                                                        │
                        │                                                                                                              │
                        │   247 │   @staticmethod                                                                                      │
                        │   248 │   def loads(data: bytes) -> 'ImageTLVInfo':                                                          │
                        │   249 │   │   """Load an `ImageTLVInfo` from bytes."""                                                       │
                        │ ❱ 250 │   │   return ImageTLVInfo(*IMAGE_TLV_INFO_STRUCT.unpack(data))                                       │
                        │   251 │                                                                                                      │
                        │   252 │   @staticmethod                                                                                      │
                        │   253 │   def load_from(file: BytesIO | BufferedReader) -> 'ImageTLVInfo':                                   │
                        │                                                                                                              │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\pydantic\_internal\_dataclasses │
                        │ .py:121 in __init__                                                                                          │
                        │                                                                                                              │
                        │   118 │   def __init__(__dataclass_self__: PydanticDataclass, *args: Any, **kwargs: Any) ->                  │
                        │       None:                                                                                                  │
                        │   119 │   │   __tracebackhide__ = True                                                                       │
                        │   120 │   │   s = __dataclass_self__                                                                         │
                        │ ❱ 121 │   │   s.__pydantic_validator__.validate_python(ArgsKwargs(args, kwargs),                             │
                        │       self_instance=s)                                                                                       │
                        │   122 │                                                                                                      │
                        │   123 │   __init__.__qualname__ = f'{cls.__qualname__}.__init__'                                             │
                        │   124                                                                                                        │
                        │                                                                                                              │
                        │ C:\Users\user\AppData\Local\Programs\Python\Python312\Lib\site-packages\smpclient\mcuboot.py:243 in     │
                        │ __post_init__                                                                                                │
                        │                                                                                                              │
                        │   240 │   def __post_init__(self) -> None:                                                                   │
                        │   241 │   │   """Do initial validation of the header."""                                                     │
                        │   242 │   │   if self.magic != IMAGE_TLV_INFO_MAGIC:                                                         │
                        │ ❱ 243 │   │   │   raise MCUBootImageError(                                                                   │
                        │   244 │   │   │   │   f"TLV info magic is {hex(self.magic)}, expected                                        │
                        │       {hex(IMAGE_TLV_INFO_MAGIC)}"                                                                           │
                        │   245 │   │   │   )                                                                                          │
                        │   246                                                                                                        │
                        ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
                        MCUBootImageError: TLV info magic is 0x6908, expected 0x6907
    
    C:\Users\user\Desktop\Mike\p1_v1.1.2_32M_12pF_dfu_application>
    
    

    Thanks!!
    Mike

Related