nrf52840 S140 Central DFU Bluetooth Zephyr 2.0.0 nrf52840 peripheral

We have nrf52840 S140 BLE Central device that currently connects to TI based sensors. I have implemented code that can upgrade those TI sensors' firmware using the TI BLE protocol.

Now we are developing our own BLE peripheral sensors also based on the nrf52840 but now using the newly supported Zephyr 2.0.0. RF connect stuff. I can update the sensors using the Nordic Android program (unauthenticated for now) and now need to implement upgrading BLE DFU using our central device which connects to a cellular gateway.

I do not want to reinvent the wheel, writing existing code, like I had to do with the TI sensors.

Could you point me to code that allows a Central device to update a peripheral device BLE DFU?

If not where can I look to reinvent another wheel?

Thanks David

Parents Reply Children
  • I started to check this when I was pulled back off it for other critical things.

    Maybe tomorrow.

    I have three questions

    1) send_smp_reset

     In the Github code it looks like the fix you made to this function was not updated:

    Fix:
    smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF);
    smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF);

     GitHub;

    smp_cmd.header.len_h8 = 0;
    smp_cmd.header.len_l8 = 0;

    2) send_upload2

     In the packet format, the len should be always 0x5B68?

     I thought it was the image length but your image size in the example is not this.

       zcbor_tstr_put_lit(zse, "len");
       // zcbor_uint64_put(zse, (uint64_t)ami_state->dfu.ImageSize.ulong);
        zcbor_uint64_put(zse, (uint64_t)0x5B68);
    3) When I compile, I get a warning when string compare is used with a word and not a string.
    I guess this is OK from my previous debugging, I just try to get rid of warning so I will notice new ones.

    ami_smp.c:752:35: warning: multi-character character constant [-Wmultichar]
    752 | } else if(!strncmp(value.value, 'rc', 2)){


    zcbor_uint64_put(zse, (uint64_t)0x5B68);

    Thanks David

  • Another question.

    In send_upload2(), the start and last addresses are taken from the bootloader partisan.

    The image uploaded is of variable size.

    Does the current code just return with "flash_read failed with error:" ?

    Or where is the image file length used?

    int last_addr = PM_MCUBOOT_SECONDARY_END_ADDRESS;
    int start_addr = PM_MCUBOOT_SECONDARY_ADDRESS;

    ...

    err = flash_read(flash_dev, curr_addr, data, upload_chunk);
    if (err != 0) {
      printk("flash_read failed with error: %d\n", err);
      return;
    }

    Thanks David

  • Thanks for the feedback!

    DavidKaplan said:
     In the Github code it looks like the fix you made to this function was not updated:

    I forgot this, but I have now added a fix in https://github.com/hellesvik-nordic/samples_for_nrf_connect_sdk/commit/5ef3f25e179bb92c218433b95f0ebb874d66dfd5.

    DavidKaplan said:

    2) send_upload2

     In the packet format, the len should be always 0x5B68?

    I copied this example from Simon.
    Therefore, I do not know what the length is supposed to be.
    I suspect that he just set it to something for testing.
    Likely, the len should be found dynamically from the image.

    DavidKaplan said:
    3) When I compile, I get a warning when string compare is used with a word and not a string.
    I guess this is OK from my previous debugging, I just try to get rid of warning so I will notice new ones.

    ami_smp.c:752:35: warning: multi-character character constant [-Wmultichar]
    752 | } else if(!strncmp(value.value, 'rc', 2)){

    Should compare with "rc" instead of 'rc'.

    Fixed in https://github.com/hellesvik-nordic/samples_for_nrf_connect_sdk/commit/39946de56c0c325d5833fd581ba2a40f14267491

    DavidKaplan said:

    Does the current code just return with "flash_read failed with error:" ?

    Or where is the image file length used?

    You are right, we should be able to find the size of the uploaded image somehow, but I do not know how yet.

    I will look for it.
    Let me know if you figure out how.

    Regards,
    Sigurd Hellesvik

  • I am using ncsv2.0.2 and not ncsv2.2.0 so I tried to upgrade the projects and as usual, have a million compile errors. I just wish Zephyr understood that "improvements" should be backwards compatible or have a compatibility layer.

    I thought I got the sensor (smp server end unit to be upgraded) to compile and run (not checking current consumption).

    In my central code (smp client), I could not get the img_mgmt_impl_write_image_data() & img_mgmt_impl_erase_slot() to link. I use them when updating the central itself by uart serial connection. I did not see any new CONFIG defines. I commented out this code.

    I tried to perform an upgrade and the first time it seemed to upload the image without error but

    the test function returned an error.

    02-05 07:21 05/02/2023 05:21:20 |  04/02/2023 19:20:59[.ami_vibe.c:1941] ...[ami_smp.c:1249] DFU:374450/374648
    02-05 07:21 05/02/2023 05:21:20 |  04/02/2023 19:20:59[.ami_vibe.c:1941] ...[ami_smp.c:1249] DFU:374550/374648
    02-05 07:21 05/02/2023 05:21:20 |  04/02/2023 19:20:59[.ami_vibe.c:1941] ...[ami_smp.c:1692] ImageList
    02-05 07:21 05/02/2023 05:21:20 |  04/02/2023 19:20:59[.ami_vibe.c:1941] ...[ami_smp.c:1695] ImageTest
    02-05 07:21 05/02/2023 05:21:20 |  04/02/2023 19:20:59[.ami_vibe.c:1941] ...[ami_ble.c:2578] DFUConnectFinishedErr:11
    

    My error 11 is in the smp_list_rsp_proc() function when called by Test.

    		memcpy(images_key, value.value, value.len);
    		images_key[value.len] = '\0';
    		//d_printf(LINE_INFO,kDbg_Error,"Images key: %s",images_key);
    		ok = zcbor_list_start_decode(zsd);
    		if (!ok) {
    			d_printf(LINE_INFO,kDbg_Error,"Decoding error, start_decode images->list  (err: %d)", zcbor_pop_error(zsd));
    			ami_state->DFUErr = AMI_SMP_DFU_ERR_LIST_IMAGE_LIST;
    			goto smp_list_rsp_proc_end;
    		}
    

    The problem is also that I could not reproduce the upload success.

    When I run my v2.0.2 code setup and connect the debugged to the sensor, I get a hard fault.

     01/01/2004 00:03:11[ami_main.c: 142] Connected
    00> 
    00> 01/01/2004 00:03:12[ami_main.c: 197] LE PHY updated: TX PHY LE 2M, RX PHY LE 2M
    00> 
    00> [00:03:57.440,734] <err> bt_keys: Failed to save keys (err -2)
    00> 01/01/2004 00:03:12[ami_main.c: 258] Pairing completed:F5:62:56:E5:1A:0C (random), bonded:1
    00> 
    00> 01/01/2004 00:03:12[ami_main.c: 226] Security changed: F5:62:56:E5:1A:0C (random) level:2
    00> 
    00> 01/01/2004 00:03:17[ami_main.c: 174] Connection parameters updated.
    00> 
    00>  interval: 40, latency: 0, timeout: 42
    00> 
    00> 01/01/2004 00:03:21[ami_main.c: 174] Connection parameters updated.
    00> 
    00>  interval: 9, latency: 0, timeout: 42
    00> 
    00> [00:04:07.005,218] <inf> mcumgr_img_mgmt: Erased 0x6000 bytes of image slot
    00> [00:04:07.117,706] <inf> mcumgr_img_mgmt: Erased 0x1000 bytes of image slot trailer
    00> [00:04:07.117,736] <err> os: ***** BUS FAULT *****
    00> [00:04:07.117,736] <err> os:   Precise data bus error
    00> [00:04:07.117,767] <err> os:   BFAR Address: 0x2c6972cc
    00> [00:04:07.117,797] <err> os: r0/a1:  0x20017288  r1/a2:  0x00000df4  r2/a3:  0x0c680044
    00> [00:04:07.117,797] <err> os: r3/a4:  0x00000010 r12/ip:  0x00000046 r14/lr:  0x0004b2b9
    00> [00:04:07.117,828] <err> os:  xpsr:  0x01000000
    00> [00:04:07.117,828] <err> os: s[ 0]:  0x00000000  s[ 1]:  0x00000000  s[ 2]:  0x00000000  s[ 3]:  0x00000000
    00> [00:04:07.117,858] <err> os: s[ 4]:  0x00000000  s[ 5]:  0x00000000  s[ 6]:  0x00000000  s[ 7]:  0x00000000
    00> [00:04:07.117,889] <err> os: s[ 8]:  0x00000000  s[ 9]:  0x00000000  s[10]:  0x00000000  s[11]:  0x00000000
    00> [00:04:07.117,889] <err> os: s[12]:  0x00000000  s[13]:  0x00000000  s[14]:  0x00000000  s[15]:  0x00000000
    00> [00:04:07.117,919] <err> os: fpscr:  0x0004bb9f
    00> [00:04:07.117,919] <err> os: Faulting instruction address (r15/pc): 0x0004b1f2
    00> [00:04:07.117,950] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
    00> [00:04:07.117,950] <err> os: Current thread: 0x200036a8 (sysworkq)
    00> [00:04:07.710,906] <err> fatal_error: Resetting system
    00> *** Booting Zephyr OS build v3.0.99-ncs1-1  ***
    00> 
    00> 

    Since I transfer the image serially from my cellular host to the central, I know the actual image size if that is what I am supposed to use.

    Thanks David

  • DavidKaplan said:
    I am using ncsv2.0.2 and not ncsv2.2.0

    I think it also works for me in 2.0.2, so for the record: I do not think you have to upgrade the version for this feature.¨

    I will help you make it work for v2.2.0 as well, though.

    DavidKaplan said:
    My error 11 is in the smp_list_rsp_proc() function when called by Test.

    Error 11 looks like ZCBOR_ERR_WRONG_VALUE.
    This is what the patch fixes, I think. Are you sure that the patch is still there after your update?

    DavidKaplan said:
    The problem is also that I could not reproduce the upload success.

    To check if I understand correctly:
    So it works the first time, but the upload fails if you already have an image in the secondary slot?

    Do you get the debugging error when uploading the first time?

    DavidKaplan said:
    Since I transfer the image serially from my cellular host to the central, I know the actual image size if that is what I am supposed to use.

    That would make sense to me.

    Regards,
    Sigurd Hellesvik

Related