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

  • Update:

    I have gotten Simons sample to do its smp "list" command successfully.

    Now I have started looking into why the smp "reset" command over BLE does not work.

    "mcumgr reset" seems to work, so I know that the SMP Server can handle this command.
    So it must be something with the transfer, that makes the SMP Server never receive the "reset" command.

    I will continue looking into this next week.

    Regards,
    Sigurd Hellesvik

  • Hi,

    I am now able to reset using Simons SMP Client over BLE.
    The error was this:
    The SMP Command had the Operation(OP) Write, but the input length was configured as 0.
    Therefore, the SMP write over Bluetooth Low Energy would never happen.
    To fix this, use the following command to send an SMP Reset:

    static int send_smp_reset(struct bt_dfu_smp *dfu_smp,
    			 const char *string)
    {
    	static struct smp_buffer smp_cmd;
    	zcbor_state_t zse[CBOR_ENCODER_STATE_NUM];
    	size_t payload_len;
    
    	zcbor_new_encode_state(zse, ARRAY_SIZE(zse), smp_cmd.payload,
    			       sizeof(smp_cmd.payload), 0);
    
    	/* Stop encoding on the error. */
    	zse->constant_state->stop_on_error = true;
    
    	zcbor_map_start_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);
    	zcbor_tstr_put_lit(zse, "d");
    	zcbor_tstr_put_term(zse, string);
    	zcbor_map_end_encode(zse, CBOR_MAP_MAX_ELEMENT_CNT);
    
    	if (!zcbor_check_error(zse)) {
    		printk("Failed to encode SMP reset packet, err: %d\n", zcbor_pop_error(zse));
    		return -EFAULT;
    	}
    
    	payload_len = (size_t)(zse->payload - smp_cmd.payload);
    
    	smp_cmd.header.op = 2; /* Write */
    	smp_cmd.header.flags = 0;
    	smp_cmd.header.len_h8 = (uint8_t)((payload_len >> 8) & 0xFF);
    	smp_cmd.header.len_l8 = (uint8_t)((payload_len >> 0) & 0xFF);
    	smp_cmd.header.group_h8 = 0;
    	smp_cmd.header.group_l8 = 0; /* OS */
    	smp_cmd.header.seq = 0;
    	smp_cmd.header.id  = 5; /* RESET */
    
    
    	return bt_dfu_smp_command(dfu_smp, smp_reset_rsp_proc,
    				  sizeof(smp_cmd.header) + payload_len,
    				  &smp_cmd);
    }
    

    Does this work for you too?

    Next up: Let's try Simons SMP Client sample to do an SMP update using its internal flash.

    Regards,
    Sigurd Hellesvik

  • I just replaced the above function with our previous one and it worked and reset my sensor end unit.

    Did the list function that you changed show 2 images in two slots.

    Thanks for advancing on this.

    David

  • Hi David,

    I did not change Simons list function.

    It worked as is. But I have not tried to upload a new image yet, meaning only 1 image lives on the device.
    It only lists 1 slot in this case. I suspect it will list 2 slots if I upload an image to the secondary slot.

    I will let you know when I have tested this.

    Regards,
    Sigurd Hellesvik

  • I am able to use Simons sample to upload images in v2.0.0.

    However, it fails in v2.2.0, and I have not been able to figure out why yet.

    Regards,
    Sigurd Hellesvik

Related