Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FW update aligned for D400/D500 #12395

Merged
merged 7 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions common/fw-update-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ namespace rs2

_progress = 30;

// Write signed firmware to appropriate file descritptor
// Write signed firmware to appropriate file descriptor
std::ofstream fw_path_in_device(_dev.get_info(RS2_CAMERA_INFO_DFU_DEVICE_PATH), std::ios::binary);
if (fw_path_in_device)
{
Expand Down Expand Up @@ -245,7 +245,7 @@ namespace rs2
}
else
{
log_backup_status = "Back-up camera flash cannot be saved";
log_backup_status = "Backup flash is not supported";
}
}
catch( const std::exception& e )
Expand All @@ -268,7 +268,9 @@ namespace rs2
}
}

log(log_backup_status);
if ( !log_backup_status.empty() )
log(log_backup_status);




Expand Down Expand Up @@ -297,6 +299,7 @@ namespace rs2
{
if (serial == d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID))
{
log( "DFU device '" + serial + "' found" );
dfu = d;
return true;
}
Expand Down Expand Up @@ -339,22 +342,10 @@ namespace rs2
_progress = ((ceil(progress * 10) / 10 * (90 - next_progress)) + next_progress);
});

// D400 devices takes 3 seconds after image transition until DFU process finish.
// D500 only starts the process after the image is transferred and it takes much time..
if( !_is_d500_device )
{
log( "Firmware Download completed, await DFU transition event" );
std::this_thread::sleep_for( std::chrono::seconds( 3 ) );
}
else
{
log( "Firmware Download completed, await DFU transition event\n"
"Internal write is in progress\n"
"Please DO NOT DISCONNECT the camera (might take a few minutes)");
std::this_thread::sleep_for( std::chrono::seconds( 60 ) );
}

log("Firmware Update completed, waiting for device to reconnect");
log( "Firmware Download completed, await DFU transition event\n"
"Internal write is in progress\n"
"Please DO NOT DISCONNECT the camera");
std::this_thread::sleep_for( std::chrono::seconds( 3 ) );
}
else
{
Expand Down Expand Up @@ -389,13 +380,14 @@ namespace rs2
}

return false;
}, cleanup, std::chrono::seconds(_is_d500_device ? 120 : 60))) // TODO: HKR DFU issue - increased timeout from 60 to 120 seconds for HKR to complete FW write to flash
}, cleanup, std::chrono::seconds(60)))
{
fail("Original device did not reconnect in time!");
return;
}

log("Device reconnected succesfully!");
log( "Device reconnected successfully!\n"
"FW update process completed successfully" );

_progress = 100;

Expand Down
2 changes: 0 additions & 2 deletions include/librealsense2/h/rs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ extern "C" {
* Firmware size constants
*/
const int signed_fw_size = 0x18031C;
const int signed_sr300_size = 0x0C025C;
const int unsigned_fw_size = 0x200000;
const int unsigned_sr300_size = 0x100000;

/**
* librealsense Recorder is intended for effective unit-testing
Expand Down
6 changes: 6 additions & 0 deletions src/ds/d400/d400-device.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2016 Intel Corporation. All Rights Reserved.

#include <librealsense2/h/rs_internal.h>
#include <src/device.h>
#include <src/image.h>
#include <src/metadata-parser.h>
Expand Down Expand Up @@ -116,6 +117,11 @@ namespace librealsense

bool d400_device::check_fw_compatibility( const std::vector< uint8_t > & image ) const
{
// check if the given FW size matches the expected FW size
if( ( static_cast< int >( image.size() ) != signed_fw_size ) )
throw librealsense::invalid_value_exception(
rsutils::string::from() << "Unsupported firmware binary image provided - " << image.size() << " bytes" );

std::string fw_version = firmware_check_interface::extract_firmware_version_string( image );

auto it = ds::d400_device_to_fw_min_version.find( _pid );
Expand Down
26 changes: 15 additions & 11 deletions src/ds/d400/d400-fw-update-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,29 @@
#include "d400-fw-update-device.h"
#include "d400-private.h"

#include <librealsense2/h/rs_internal.h>

namespace librealsense
{
ds_update_device::ds_update_device( std::shared_ptr< const device_info > const & dev_info,
std::shared_ptr< platform::usb_device > const & usb_device )
ds_d400_update_device::ds_d400_update_device( std::shared_ptr< const device_info > const & dev_info,
std::shared_ptr< platform::usb_device > const & usb_device,
std::string const & product_line)
: update_device( dev_info, usb_device )
, _product_line( "D400" )
maloel marked this conversation as resolved.
Show resolved Hide resolved
{
auto info = usb_device->get_info();
_name = ds::rs400_sku_names.find(info.pid) != ds::rs400_sku_names.end() ? ds::rs400_sku_names.at(info.pid) : "unknown";
auto info = usb_device->get_info();
_product_line = product_line;
_name = ds::rs400_sku_names.find(info.pid) != ds::rs400_sku_names.end() ? ds::rs400_sku_names.at(info.pid) : "unknown";
_serial_number = parse_serial_number(_serial_number_buffer);
}

void ds_update_device::update(const void* fw_image, int fw_image_size, rs2_update_progress_callback_sptr callback) const
{
update_device::update(fw_image, fw_image_size, callback);
}

bool ds_update_device::check_fw_compatibility(const std::vector<uint8_t>& image) const
bool ds_d400_update_device::check_fw_compatibility(const std::vector<uint8_t>& image) const
{
// check if the given FW size matches the expected FW size
if( image.size() != signed_fw_size )
throw librealsense::invalid_value_exception(
rsutils::string::from() << "Unsupported firmware binary image provided - " << image.size() << " bytes" );

std::string fw_version = extract_firmware_version_string(image);
auto it = ds::d400_device_to_fw_min_version.find(_usb_device->get_info().pid);
if (it == ds::d400_device_to_fw_min_version.end())
Expand All @@ -36,7 +40,7 @@ ds_update_device::ds_update_device( std::shared_ptr< const device_info > const &
return result;
}

std::string ds_update_device::parse_serial_number(const std::vector<uint8_t>& buffer) const
std::string ds_d400_update_device::parse_serial_number(const std::vector<uint8_t>& buffer) const
{
if (buffer.size() != sizeof(serial_number_data))
throw std::runtime_error("DFU - failed to parse serial number!");
Expand Down
20 changes: 6 additions & 14 deletions src/ds/d400/d400-fw-update-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,17 @@

namespace librealsense
{
class ds_update_device : public update_device
class ds_d400_update_device : public update_device
{
public:
ds_update_device( std::shared_ptr< const device_info > const &,
std::shared_ptr< platform::usb_device > const & usb_device );
virtual ~ds_update_device() = default;
ds_d400_update_device( std::shared_ptr< const device_info > const &,
std::shared_ptr< platform::usb_device > const & usb_device,
std::string const & product_line );
virtual ~ds_d400_update_device() = default;

void update(const void* fw_image, int fw_image_size, rs2_update_progress_callback_sptr = nullptr) const override;
virtual bool check_fw_compatibility(const std::vector<uint8_t>& image) const override;

protected:
virtual const std::string& get_name() const override { return _name; }
virtual const std::string& get_product_line() const override { return _product_line; }
virtual const std::string& get_serial_number() const override { return _serial_number; }
std::string parse_serial_number(const std::vector<uint8_t>& buffer) const;

private:
std::string _name;
std::string _product_line;
std::string _serial_number;
std::string parse_serial_number(const std::vector<uint8_t>& buffer) const;
};
}
12 changes: 6 additions & 6 deletions src/ds/d400/d400-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ namespace librealsense
const uint16_t RS430_PID = 0x0ad4; // AWG
const uint16_t RS430_MM_PID = 0x0ad5; // AWGT
const uint16_t RS_USB2_PID = 0x0ad6; // USB2
const uint16_t RS_RECOVERY_PID = 0x0adb;
const uint16_t RS_USB2_RECOVERY_PID = 0x0adc;
const uint16_t RS_D400_RECOVERY_PID = 0x0adb;
const uint16_t RS_D400_USB2_RECOVERY_PID = 0x0adc;
const uint16_t RS400_IMU_PID = 0x0af2; // IMU
const uint16_t RS420_PID = 0x0af6; // PWG
const uint16_t RS420_MM_PID = 0x0afe; // PWGT
Expand Down Expand Up @@ -111,8 +111,8 @@ namespace librealsense
{ RS430_PID, "Intel RealSense D430"},
{ RS430_MM_PID, "Intel RealSense D430 with Tracking Module"},
{ RS_USB2_PID, "Intel RealSense USB2" },
{ RS_RECOVERY_PID, "Intel RealSense D4XX Recovery"},
{ RS_USB2_RECOVERY_PID, "Intel RealSense D4XX USB2 Recovery"},
{ RS_D400_RECOVERY_PID, "Intel RealSense D4XX Recovery"},
{ RS_D400_USB2_RECOVERY_PID, "Intel RealSense D4XX USB2 Recovery"},
{ RS400_IMU_PID, "Intel RealSense IMU" },
{ RS420_PID, "Intel RealSense D420"},
{ RS420_MM_PID, "Intel RealSense D420 with Tracking Module"},
Expand All @@ -139,8 +139,8 @@ namespace librealsense
{RS430_PID, "5.8.15.0"},
{RS430_MM_PID, "5.8.15.0"},
{RS_USB2_PID, "5.8.15.0"},
{RS_RECOVERY_PID, "5.8.15.0"},
{RS_USB2_RECOVERY_PID, "5.8.15.0"},
{RS_D400_RECOVERY_PID, "5.8.15.0"},
{RS_D400_USB2_RECOVERY_PID, "5.8.15.0"},
{RS400_IMU_PID, "5.8.15.0"},
{RS420_PID, "5.8.15.0"},
{RS420_MM_PID, "5.8.15.0"},
Expand Down
2 changes: 2 additions & 0 deletions src/ds/d500/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ target_sources(${LRS_TARGET}
"${CMAKE_CURRENT_LIST_DIR}/d500-factory.cpp"
"${CMAKE_CURRENT_LIST_DIR}/hw_monitor_extended_buffers.cpp"
"${CMAKE_CURRENT_LIST_DIR}/d500-options.cpp"
"${CMAKE_CURRENT_LIST_DIR}/d500-fw-update-device.cpp"
"${CMAKE_CURRENT_LIST_DIR}/d500-device.h"
"${CMAKE_CURRENT_LIST_DIR}/d500-color.h"
"${CMAKE_CURRENT_LIST_DIR}/d500-motion.h"
Expand All @@ -18,4 +19,5 @@ target_sources(${LRS_TARGET}
"${CMAKE_CURRENT_LIST_DIR}/hw_monitor_extended_buffers.h"
"${CMAKE_CURRENT_LIST_DIR}/d500-options.h"
"${CMAKE_CURRENT_LIST_DIR}/d500-info.h"
"${CMAKE_CURRENT_LIST_DIR}/d500-fw-update-device.h"
)
18 changes: 2 additions & 16 deletions src/ds/d500/d500-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ namespace librealsense

void d500_device::update_flash(const std::vector<uint8_t>& image, rs2_update_progress_callback_sptr callback, int update_mode)
{
_ds_device_common->update_flash(image, callback, update_mode);
throw not_implemented_exception("D500 device does not support unsigned FW update");
}

class d500_depth_sensor : public synthetic_sensor, public video_sensor_interface, public depth_stereo_sensor, public roi_sensor_base
Expand Down Expand Up @@ -583,21 +583,7 @@ namespace librealsense

if ((_device_capabilities & ds_caps::CAP_INTERCAM_HW_SYNC) == ds_caps::CAP_INTERCAM_HW_SYNC)
{
if ((_device_capabilities & ds_caps::CAP_GLOBAL_SHUTTER) == ds_caps::CAP_GLOBAL_SHUTTER)
{
depth_sensor.register_option(RS2_OPTION_INTER_CAM_SYNC_MODE,
std::make_shared<external_sync_mode>(*_hw_monitor, &raw_depth_sensor, 3));
}
else if ((_device_capabilities & ds_caps::CAP_GLOBAL_SHUTTER) == ds_caps::CAP_GLOBAL_SHUTTER)
{
depth_sensor.register_option(RS2_OPTION_INTER_CAM_SYNC_MODE,
std::make_shared<external_sync_mode>(*_hw_monitor, &raw_depth_sensor, 2));
}
else
{
depth_sensor.register_option(RS2_OPTION_INTER_CAM_SYNC_MODE,
std::make_shared<external_sync_mode>(*_hw_monitor, &raw_depth_sensor, 1));
}
// Register RS2_OPTION_INTER_CAM_SYNC_MODE here if needed
maloel marked this conversation as resolved.
Show resolved Hide resolved
}

roi_sensor_interface* roi_sensor = dynamic_cast<roi_sensor_interface*>(&depth_sensor);
Expand Down
61 changes: 61 additions & 0 deletions src/ds/d500/d500-fw-update-device.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2023 Intel Corporation. All Rights Reserved.

#include "d500-fw-update-device.h"
#include "d500-private.h"


namespace librealsense
{
ds_d500_update_device::ds_d500_update_device( std::shared_ptr< const device_info > const & dev_info,
std::shared_ptr< platform::usb_device > const & usb_device,
std::string const & product_line )
: update_device( dev_info, usb_device )
{
auto info = usb_device->get_info();
_product_line = product_line;
_name = ds::rs500_sku_names.find(info.pid) != ds::rs500_sku_names.end() ? ds::rs500_sku_names.at(info.pid) : "unknown";
_serial_number = parse_serial_number(_serial_number_buffer);
}


bool ds_d500_update_device::check_fw_compatibility(const std::vector<uint8_t>& image) const
{
// Currently we cannot extract FW version from HKR FW image
bool result = true;

// TODO::: Once verified we can check against the minimal FW version map
std::string fw_version = extract_firmware_version_string(image);
LOG_INFO( "FW version extracted from the FW image is" + fw_version );

return result;
}

std::string ds_d500_update_device::parse_serial_number(const std::vector<uint8_t>& buffer) const
{
if (buffer.size() != sizeof(serial_number_data))
throw std::runtime_error("DFU - failed to parse serial number!");

std::stringstream rv;
for (auto i = 0; i < ds::module_serial_size; i++)
rv << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(buffer[i]);

return rv.str();
}

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 );

static constexpr float D500_FW_DFU_TIME = 100.0; // [sec]
// We calculate the sleep time needed for each cycle to get to 100% progress bar
// On D500 devices after transferring the FW image the internal DFU progress start on the device
float iteration_sleep_time_ms = (static_cast<float>(D500_FW_DFU_TIME) / 100.0f) * 1000.0f;
for(int i = 1; i <= 100; i++)
{
if (update_progress_callback)
update_progress_callback->on_update_progress( i / 100.f );
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int>(iteration_sleep_time_ms)));
}
}
}
24 changes: 24 additions & 0 deletions src/ds/d500/d500-fw-update-device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2023 Intel Corporation. All Rights Reserved.

#pragma once

#include "fw-update/fw-update-device.h"

namespace librealsense
{
class ds_d500_update_device : public update_device
{
public:
ds_d500_update_device( std::shared_ptr< const device_info > const &,
std::shared_ptr< platform::usb_device > const & usb_device,
std::string const & product_line );
virtual ~ds_d500_update_device() = default;

virtual bool check_fw_compatibility(const std::vector<uint8_t>& image) const override;
virtual void update(const void* fw_image, int fw_image_size, rs2_update_progress_callback_sptr = nullptr) const override;

private:
std::string parse_serial_number(const std::vector<uint8_t>& buffer) const;
};
}
4 changes: 3 additions & 1 deletion src/ds/d500/d500-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace librealsense
namespace ds
{
const uint16_t D555E_PID = 0x0B56;
const uint16_t RS_D500_RECOVERY_PID = 0x0ADD;

namespace xu_id
{
Expand All @@ -37,7 +38,8 @@ namespace librealsense
};

static const std::map< std::uint16_t, std::string > rs500_sku_names = {
{ ds::D555E_PID, "Intel RealSense D555e" }
{ ds::D555E_PID, "Intel RealSense D555e" },
{ ds::RS_D500_RECOVERY_PID, "Intel RealSense D5XX Recovery"}
};

bool d500_try_fetch_usb_device(std::vector<platform::usb_device_info>& devices,
Expand Down
8 changes: 8 additions & 0 deletions src/ds/ds-device-common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "proc/temporal-filter.h"

#include <src/backend.h>
#include <librealsense2/h/rs_internal.h>

namespace librealsense
{
Expand Down Expand Up @@ -256,6 +257,13 @@ namespace librealsense

void ds_device_common::update_flash(const std::vector<uint8_t>& image, rs2_update_progress_callback_sptr callback, int update_mode)
{
// check if the given FW size matches the expected FW size
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation off?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

if( image.size() != unsigned_fw_size )
throw librealsense::invalid_value_exception( rsutils::string::from()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent still looks off

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, now I see the indent issue, I fixed the comment indent before.
Fixed

<< "Unsupported firmware binary image (unsigned) provided - "
<< image.size() << " bytes" );


if (_is_locked)
throw std::runtime_error("this camera is locked and doesn't allow direct flash write, for firmware update use rs2_update_firmware method (DFU)");

Expand Down
Loading
Loading