This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Init Packet

I'm referring this

https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.2.0%2Flib_dfu_transport_ble.html

which states that when in bootloader mode, I've to send the init packet first & then the firmware image.

So what happens after I send 06 01 command. What is init packet? How do I create one? The response received for each command - is it written over a characteristic or a descriptor inside characteristic? My understanding is DFU Control Point & DFU Packet characteristics do not support read property. So where can I see the response received for every command sent by host to BLE device?

Sorry I could not understand a thing from the sniffer trace which I captured while executing the actual DFU procedure listed on Nordic Infocenter. I'm using SDK 15.2 & nrf52832.

5875.original.pcapng

  • Thanks Bjorn, I could successfully send the init packet with your help! Can you tell me how is the CRC32 response calculated?

  • HI Sonal, 

    Happy to hear that you're able to send the init packet successfully now. The CRC32 request is handled by the on_data_obj_crc_request() callback in nrf_dfu_req_handler.c. It simply retrieves the CRC stored on the bootloader settings page, see snippet below

    static void on_data_obj_crc_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
    {
        NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (data)");
        NRF_LOG_DEBUG("Offset:%d, CRC:0x%08x",
                     s_dfu_settings.progress.firmware_image_offset,
                     s_dfu_settings.progress.firmware_image_crc);
    
        p_res->crc.crc    = s_dfu_settings.progress.firmware_image_crc;
        p_res->crc.offset = s_dfu_settings.progress.firmware_image_offset;
    }

    The CRC value is updated on every write request to the DFU packet characteristic, which is handled by the  on_data_obj_write_request() callback

    static void on_data_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
    {
        NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (data)");
    
        if (!nrf_dfu_validation_init_cmd_present())
        {
            /* Can't accept data because DFU isn't initialized by init command. */
            p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
            return;
        }
    
        uint32_t const data_object_offset = s_dfu_settings.progress.firmware_image_offset -
                                            s_dfu_settings.progress.firmware_image_offset_last;
    
        if ((p_req->write.len + data_object_offset) > s_dfu_settings.progress.data_object_size)
        {
            /* Can't accept data because too much data has been received. */
            NRF_LOG_ERROR("Write request too long");
            p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
            return;
        }
    
        uint32_t const write_addr = m_firmware_start_addr + s_dfu_settings.write_offset;
        /* CRC must be calculated before handing off the data to fstorage because the data is
         * freed on write completion.
         */
        uint32_t const next_crc =
            crc32_compute(p_req->write.p_data, p_req->write.len, &s_dfu_settings.progress.firmware_image_crc);
    
        ASSERT(p_req->callback.write);
    
        ret_code_t ret =
            nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write);
    
        if (ret != NRF_SUCCESS)
        {
            /* When nrf_dfu_flash_store() fails because there is no space in the queue,
             * stop processing the request so that the peer can detect a CRC error
             * and retransmit this object. Remember to manually free the buffer !
             */
            p_req->callback.write((void*)p_req->write.p_data);
            return;
        }
    
        /* Update the CRC of the firmware image. */
        s_dfu_settings.write_offset                   += p_req->write.len;
        s_dfu_settings.progress.firmware_image_offset += p_req->write.len;
        s_dfu_settings.progress.firmware_image_crc     = next_crc;
    
        /* This is only used when the PRN is triggered and the 'write' message
         * is answered with a CRC message and these field are copied into the response.
         */
        p_res->write.crc    = s_dfu_settings.progress.firmware_image_crc;
        p_res->write.offset = s_dfu_settings.progress.firmware_image_offset;
    }

    It calls crc32_compute to compute the CRC.

    Best regards

    Bjørn

  • Thanks!! I'm facing problems sending the firmware image. After I send 06 02, I receive 60-06-01-00-10-00-00-00-00-00-00-00-00-00-00. Does that mean each data object can only be 0x1000 bytes long? Can you please tell me the sequence of commands to send the firmware image? Should I send create command, CRC command & execute command separately for every data object or do I send it just once?

    Also I never really get this response for both init packet & firmware image.

  • bscdb said:
    I'm facing problems sending the firmware image. After I send 06 02, I receive 60-06-01-00-10-00-00-00-00-00-00-00-00-00-00. Does that mean each data object can only be 0x1000 bytes long?

     Yes, the maximum object size is 4kB (0x1000 bytes). 

    bscdb said:
    Can you please tell me the sequence of commands to send the firmware image? Should I send create command, CRC command & execute command separately for every data object or do I send it just once?

     This is described in the Transfer of a firmware image message sequence chart. The Select command should only be sent once in the beginning, then you will have to create data objects , transfer the data and send CRC requests until all the objects have been transferred. 

    Once all objects have been received you send the Execute command. 

    Best regards

    Bjørn

  • I followed the sequence which you mentioned above. Could you please tell me the location where the packets from firmware file being received are handled in bootloader code? For me, the DFU process stops midway, like only 50% of the firmware file is sent OTA.

    How come nRFConnect sends 244 byte packets? The connection diagram in the documentation mentions sending only 20 bytes. Also the sdk config file in the bootloader has 27 bytes set for BLE packet.

Related