From 1039bcaf311cc9390c12620b73a2a4dfb1f79769 Mon Sep 17 00:00:00 2001 From: Remi Bettan Date: Mon, 27 May 2024 14:02:06 +0300 Subject: [PATCH 1/5] cleaning d400 fw update code, avoid stucking of d500 w/o dfu monitoring feature --- src/ds/d500/d500-fw-update-device.cpp | 58 ++++++++++++++++++++++++++- src/ds/d500/d500-fw-update-device.h | 7 +++- src/fw-update/fw-update-device.cpp | 17 ++------ src/fw-update/fw-update-device.h | 3 +- 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/src/ds/d500/d500-fw-update-device.cpp b/src/ds/d500/d500-fw-update-device.cpp index 7687a2e977..6c6ef3c364 100644 --- a/src/ds/d500/d500-fw-update-device.cpp +++ b/src/ds/d500/d500-fw-update-device.cpp @@ -61,9 +61,12 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info // the below code avoids process stuck when using a d5XX device, // which has a fw version without the DFU progress feature - if (percentage_of_transfer == 0 && + if (percentage_of_transfer == 0 && ++iteration == max_iteration_number_for_progress_start) + { + _wait_instead_of_sampling_manifest_reset = true; return true; + } std::stringstream ss; ss << "DFU_GETSTATUS called, state is: " << to_string(dfu_state); @@ -77,7 +80,7 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info } if (sts != platform::RS2_USB_STATUS_SUCCESS) - LOG_DEBUG("control xfer error: " << platform::usb_status_to_string[sts]); + LOG_ERROR("control xfer error: " << platform::usb_status_to_string[sts]); //test for dfu error state if (status.is_error_state()) { @@ -98,4 +101,55 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info return true; } + + void ds_d500_update_device::dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const + { + // measuring the progress of the writing to flash (when enabled by FW) + if (!wait_for_manifest_completion(messenger, RS2_DFU_STATE_DFU_MANIFEST, std::chrono::seconds(200), update_progress_callback)) + throw std::runtime_error("Firmware manifest completion failed"); + + + // After the zero length DFU_DNLOAD request terminates the Transfer + // phase, the device is ready to manifest the new firmware. As described + // previously, some devices may accumulate the firmware image and perform + // the entire reprogramming operation at one time. Others may have only a + // small amount remaining to be reprogrammed, and still others may have + // none. Regardless, the device enters the dfuMANIFEST-SYNC state and + // awaits the solicitation of the status report by the host. Upon receipt + // of the anticipated DFU_GETSTATUS, the device enters the dfuMANIFEST + // state, where it completes its reprogramming operations. + + // WaitForDFU state sends several DFU_GETSTATUS requests, until we hit + // either RS2_DFU_STATE_DFU_MANIFEST_WAIT_RESET or RS2_DFU_STATE_DFU_ERROR status. + // This command also reset the device + if (!_wait_instead_of_sampling_manifest_reset) // when dfu monitoring is enabled by FW + { + if (!wait_for_state(messenger, RS2_DFU_STATE_DFU_MANIFEST_WAIT_RESET, 20000)) + throw std::runtime_error("Firmware manifest failed"); + } + else // when dfu monitoring is not enabled by FW + { + LOG_DEBUG("Waiting for the FW to be burnt"); + static constexpr int D500_FW_DFU_TIME = 120; // [sec] + report_progress_and_wait_for_fw_burn(update_progress_callback, D500_FW_DFU_TIME); + } + } + + void ds_d500_update_device::report_progress_and_wait_for_fw_burn(rs2_update_progress_callback_sptr update_progress_callback, int required_dfu_time) const + { + // We calculate the sleep time needed for each cycle to get to 100% progress bar + if (update_progress_callback) + { + float iteration_sleep_time_ms = (static_cast(required_dfu_time) / 100.0f) * 1000.0f; + for (int i = 1; i <= 100; i++) + { + auto percentage_of_transfer = i; + auto progress_for_bar = compute_progress(static_cast(percentage_of_transfer), 20.f, 100.f, 5.f) / 100.f; + update_progress_callback->on_update_progress(progress_for_bar); + std::this_thread::sleep_for(std::chrono::milliseconds(static_cast(iteration_sleep_time_ms))); + } + } + else + std::this_thread::sleep_for(std::chrono::seconds(required_dfu_time)); + } } diff --git a/src/ds/d500/d500-fw-update-device.h b/src/ds/d500/d500-fw-update-device.h index 48b18b9952..4539224762 100644 --- a/src/ds/d500/d500-fw-update-device.h +++ b/src/ds/d500/d500-fw-update-device.h @@ -16,10 +16,13 @@ namespace librealsense virtual bool check_fw_compatibility(const std::vector& image) const override; virtual void update(const void* fw_image, int fw_image_size, rs2_update_progress_callback_sptr = nullptr) const override; - virtual bool wait_for_manifest_completion(std::shared_ptr messenger, const rs2_dfu_state state, - std::chrono::seconds timeout_seconds, rs2_update_progress_callback_sptr update_progress_callback) const override; + bool wait_for_manifest_completion(std::shared_ptr messenger, const rs2_dfu_state state, + std::chrono::seconds timeout_seconds, rs2_update_progress_callback_sptr update_progress_callback) const; + virtual void dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const override; private: std::string parse_serial_number(const std::vector& buffer) const; + void report_progress_and_wait_for_fw_burn(rs2_update_progress_callback_sptr update_progress_callback, int required_dfu_time) const; + mutable bool _wait_instead_of_sampling_manifest_reset = false; }; } diff --git a/src/fw-update/fw-update-device.cpp b/src/fw-update/fw-update-device.cpp index 75141fa3c8..d1e5553d21 100644 --- a/src/fw-update/fw-update-device.cpp +++ b/src/fw-update/fw-update-device.cpp @@ -146,14 +146,6 @@ namespace librealsense return start + (ceil(progress * threshold) / threshold) * (end - start) / 100.f; } - bool update_device::wait_for_manifest_completion(std::shared_ptr messenger, const rs2_dfu_state state, - std::chrono::seconds timeout_seconds, rs2_update_progress_callback_sptr update_progress_callback) const - { - // used for devices which get the progress percentage in the GET_DFU_STATUS call - - return true; - } - update_device::update_device( std::shared_ptr< const device_info > const & dev_info, std::shared_ptr< platform::usb_device > const & usb_device, const std::string & product_line ) @@ -251,12 +243,11 @@ namespace librealsense if (sts != platform::RS2_USB_STATUS_SUCCESS) throw std::runtime_error("Failed to send final FW packet"); + dfu_process_after_download_completion(messenger, update_progress_callback); + } - // measuring the progress of the writing to flash (when enabled by FW) - if (!wait_for_manifest_completion(messenger, RS2_DFU_STATE_DFU_MANIFEST, std::chrono::seconds(200), update_progress_callback)) - throw std::runtime_error("Firmware manifest completion failed"); - - + void update_device::dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const + { // After the zero length DFU_DNLOAD request terminates the Transfer // phase, the device is ready to manifest the new firmware. As described // previously, some devices may accumulate the firmware image and perform diff --git a/src/fw-update/fw-update-device.h b/src/fw-update/fw-update-device.h index ac27eab822..12a0b30d6a 100644 --- a/src/fw-update/fw-update-device.h +++ b/src/fw-update/fw-update-device.h @@ -146,8 +146,7 @@ namespace librealsense rs2_dfu_state get_dfu_state(std::shared_ptr messenger) const; void detach(std::shared_ptr messenger) const; bool wait_for_state(std::shared_ptr messenger, const rs2_dfu_state state, size_t timeout = 1000) const; - virtual bool wait_for_manifest_completion(std::shared_ptr messenger, const rs2_dfu_state state, - std::chrono::seconds timeout_seconds, rs2_update_progress_callback_sptr update_progress_callback) const; + virtual void dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const; void read_device_info(std::shared_ptr messenger); const std::string & get_name() const { return _name; } From 1417bd9b1b3e4b3d1e3d8fa7d4876fd0cd7a1de5 Mon Sep 17 00:00:00 2001 From: Remi Bettan Date: Mon, 27 May 2024 15:40:01 +0300 Subject: [PATCH 2/5] moving code --- src/ds/d500/d500-fw-update-device.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ds/d500/d500-fw-update-device.cpp b/src/ds/d500/d500-fw-update-device.cpp index 6c6ef3c364..b7a1a12036 100644 --- a/src/ds/d500/d500-fw-update-device.cpp +++ b/src/ds/d500/d500-fw-update-device.cpp @@ -38,6 +38,13 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info void ds_d500_update_device::update(const void* fw_image, int fw_image_size, rs2_update_progress_callback_sptr update_progress_callback) const { update_device::update( fw_image, fw_image_size, update_progress_callback ); + + if (_wait_instead_of_sampling_manifest_reset) // when dfu monitoring is not enabled by FW + { + LOG_DEBUG("Waiting for the FW to be burnt"); + static constexpr int D500_FW_DFU_TIME = 120; // [sec] + report_progress_and_wait_for_fw_burn(update_progress_callback, D500_FW_DFU_TIME); + } } bool ds_d500_update_device::wait_for_manifest_completion(std::shared_ptr messenger, const rs2_dfu_state state, @@ -127,12 +134,6 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info if (!wait_for_state(messenger, RS2_DFU_STATE_DFU_MANIFEST_WAIT_RESET, 20000)) throw std::runtime_error("Firmware manifest failed"); } - else // when dfu monitoring is not enabled by FW - { - LOG_DEBUG("Waiting for the FW to be burnt"); - static constexpr int D500_FW_DFU_TIME = 120; // [sec] - report_progress_and_wait_for_fw_burn(update_progress_callback, D500_FW_DFU_TIME); - } } void ds_d500_update_device::report_progress_and_wait_for_fw_burn(rs2_update_progress_callback_sptr update_progress_callback, int required_dfu_time) const From b20bc68e6cb3f85adf0759852bab313395ef9650 Mon Sep 17 00:00:00 2001 From: Remi Bettan Date: Mon, 27 May 2024 16:00:33 +0300 Subject: [PATCH 3/5] removing warning --- common/fw-update-helper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/fw-update-helper.cpp b/common/fw-update-helper.cpp index 104d134981..ff1c538758 100644 --- a/common/fw-update-helper.cpp +++ b/common/fw-update-helper.cpp @@ -272,7 +272,7 @@ namespace rs2 if ( !log_backup_status.empty() ) log(log_backup_status); - next_progress = _progress + 10; + next_progress = static_cast(_progress) + 10; if (_is_signed) { From e4c158c655b090ea53bf54e1a99775e488eda44c Mon Sep 17 00:00:00 2001 From: Remi Bettan Date: Mon, 27 May 2024 16:16:39 +0300 Subject: [PATCH 4/5] method renaming --- src/ds/d500/d500-fw-update-device.cpp | 2 +- src/ds/d500/d500-fw-update-device.h | 2 +- src/fw-update/fw-update-device.cpp | 4 ++-- src/fw-update/fw-update-device.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ds/d500/d500-fw-update-device.cpp b/src/ds/d500/d500-fw-update-device.cpp index b7a1a12036..3c9f7a18cb 100644 --- a/src/ds/d500/d500-fw-update-device.cpp +++ b/src/ds/d500/d500-fw-update-device.cpp @@ -109,7 +109,7 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info return true; } - void ds_d500_update_device::dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const + void ds_d500_update_device::dfu_manifest_phase(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const { // measuring the progress of the writing to flash (when enabled by FW) if (!wait_for_manifest_completion(messenger, RS2_DFU_STATE_DFU_MANIFEST, std::chrono::seconds(200), update_progress_callback)) diff --git a/src/ds/d500/d500-fw-update-device.h b/src/ds/d500/d500-fw-update-device.h index 4539224762..0a7830b16d 100644 --- a/src/ds/d500/d500-fw-update-device.h +++ b/src/ds/d500/d500-fw-update-device.h @@ -18,7 +18,7 @@ namespace librealsense virtual void update(const void* fw_image, int fw_image_size, rs2_update_progress_callback_sptr = nullptr) const override; bool wait_for_manifest_completion(std::shared_ptr messenger, const rs2_dfu_state state, std::chrono::seconds timeout_seconds, rs2_update_progress_callback_sptr update_progress_callback) const; - virtual void dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const override; + virtual void dfu_manifest_phase(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const override; private: std::string parse_serial_number(const std::vector& buffer) const; diff --git a/src/fw-update/fw-update-device.cpp b/src/fw-update/fw-update-device.cpp index d1e5553d21..cfa86a3b95 100644 --- a/src/fw-update/fw-update-device.cpp +++ b/src/fw-update/fw-update-device.cpp @@ -243,10 +243,10 @@ namespace librealsense if (sts != platform::RS2_USB_STATUS_SUCCESS) throw std::runtime_error("Failed to send final FW packet"); - dfu_process_after_download_completion(messenger, update_progress_callback); + dfu_manifest_phase(messenger, update_progress_callback); } - void update_device::dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const + void update_device::dfu_manifest_phase(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const { // After the zero length DFU_DNLOAD request terminates the Transfer // phase, the device is ready to manifest the new firmware. As described diff --git a/src/fw-update/fw-update-device.h b/src/fw-update/fw-update-device.h index 12a0b30d6a..6bd18099bb 100644 --- a/src/fw-update/fw-update-device.h +++ b/src/fw-update/fw-update-device.h @@ -146,7 +146,7 @@ namespace librealsense rs2_dfu_state get_dfu_state(std::shared_ptr messenger) const; void detach(std::shared_ptr messenger) const; bool wait_for_state(std::shared_ptr messenger, const rs2_dfu_state state, size_t timeout = 1000) const; - virtual void dfu_process_after_download_completion(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const; + virtual void dfu_manifest_phase(const platform::rs_usb_messenger& messenger, rs2_update_progress_callback_sptr update_progress_callback) const; void read_device_info(std::shared_ptr messenger); const std::string & get_name() const { return _name; } From 9e5c5a137e577d0aa217554bc09063bf589a01c6 Mon Sep 17 00:00:00 2001 From: Remi Bettan Date: Tue, 28 May 2024 00:29:59 +0300 Subject: [PATCH 5/5] cr --- src/ds/d500/d500-fw-update-device.cpp | 6 +++--- src/ds/d500/d500-fw-update-device.h | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ds/d500/d500-fw-update-device.cpp b/src/ds/d500/d500-fw-update-device.cpp index 3c9f7a18cb..aa20914dfd 100644 --- a/src/ds/d500/d500-fw-update-device.cpp +++ b/src/ds/d500/d500-fw-update-device.cpp @@ -39,7 +39,7 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info { update_device::update( fw_image, fw_image_size, update_progress_callback ); - if (_wait_instead_of_sampling_manifest_reset) // when dfu monitoring is not enabled by FW + if (!_is_dfu_monitoring_enabled) { LOG_DEBUG("Waiting for the FW to be burnt"); static constexpr int D500_FW_DFU_TIME = 120; // [sec] @@ -71,7 +71,7 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info if (percentage_of_transfer == 0 && ++iteration == max_iteration_number_for_progress_start) { - _wait_instead_of_sampling_manifest_reset = true; + _is_dfu_monitoring_enabled = false; return true; } @@ -129,7 +129,7 @@ ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info // WaitForDFU state sends several DFU_GETSTATUS requests, until we hit // either RS2_DFU_STATE_DFU_MANIFEST_WAIT_RESET or RS2_DFU_STATE_DFU_ERROR status. // This command also reset the device - if (!_wait_instead_of_sampling_manifest_reset) // when dfu monitoring is enabled by FW + if (_is_dfu_monitoring_enabled) { if (!wait_for_state(messenger, RS2_DFU_STATE_DFU_MANIFEST_WAIT_RESET, 20000)) throw std::runtime_error("Firmware manifest failed"); diff --git a/src/ds/d500/d500-fw-update-device.h b/src/ds/d500/d500-fw-update-device.h index 0a7830b16d..61f5f79f09 100644 --- a/src/ds/d500/d500-fw-update-device.h +++ b/src/ds/d500/d500-fw-update-device.h @@ -23,6 +23,10 @@ namespace librealsense private: std::string parse_serial_number(const std::vector& buffer) const; void report_progress_and_wait_for_fw_burn(rs2_update_progress_callback_sptr update_progress_callback, int required_dfu_time) const; - mutable bool _wait_instead_of_sampling_manifest_reset = false; + // The following data member _is_dfu_monitoring_enabled is needed to perform DFU when + // the DFU monitoring is not enabled by FW, for D500 device. + // Its value may be changed to false after the process starts as if the DFU monitoring was + // enabled and the progress feedback that should come from the FW remains 0 after few iterations. + mutable bool _is_dfu_monitoring_enabled = true; }; }