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

firmware compatibility to device checking #8948

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
12 changes: 12 additions & 0 deletions common/fw-update-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,18 @@ namespace rs2

if (auto upd = _dev.as<updatable>())
{
// checking firmware version compatibility with device
if (_is_signed)
{
if (!upd.check_firmware_compatibility(_fw))
{
std::stringstream ss;
ss << "The firmware version is not compatible with ";
ss << _dev.get_info(RS2_CAMERA_INFO_NAME) << std::endl;
fail(ss.str());
return;
}
}
log("Backing-up camera flash memory");

std::string log_backup_status;
Expand Down
10 changes: 10 additions & 0 deletions include/librealsense2/h/rs_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,16 @@ const rs2_raw_data_buffer* rs2_create_flash_backup(const rs2_device* device, rs2
*/
void rs2_update_firmware_unsigned_cpp(const rs2_device* device, const void* fw_image, int fw_image_size, rs2_update_progress_callback* callback, int update_mode, rs2_error** error);

/**
* Checks if the device and the provided firmware image are compatible
* \param[in] device Device to update
* \param[in] fw_image Firmware image buffer
* \param[in] fw_image_size Firmware image buffer size in bytes
* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored
* \return Non-zero if the firmware is compatible with the device and 0 otherwise
*/
int rs2_check_firmware_compatibility(const rs2_device* device, const void* fw_image, int fw_image_size, rs2_error** error);

/**
* Update device to the provided firmware by writing raw data directly to the flash, this command can be executed only on unlocked camera.
* The device must be extendable to RS2_EXTENSION_UPDATABLE.
Expand Down
9 changes: 9 additions & 0 deletions include/librealsense2/hpp/rs_device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ namespace rs2
return results;
}

// check firmware compatibility with sku
bool check_firmware_compatibility(const std::vector<uint8_t>& image) const
{
rs2_error* e = nullptr;
auto res = !!rs2_check_firmware_compatibility(_dev.get(), image.data(), (int)image.size(), &e);
error::handle(e);
return res;
}

// Update an updatable device to the provided unsigned firmware. This call is executed on the caller's thread.
void update_unsigned(const std::vector<uint8_t>& image, int update_mode = RS2_UNSIGNED_UPDATE_MODE_UPDATE) const
{
Expand Down
11 changes: 11 additions & 0 deletions src/android/jni/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ Java_com_intel_realsense_librealsense_Updatable_nCreateFlashBackup(JNIEnv *env,
return rv;
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_intel_realsense_librealsense_Updatable_nCheckFirmwareCompatibility(JNIEnv *env, jobject instance,
jlong handle, jbyteArray image) {
rs2_error *e = NULL;
auto length = env->GetArrayLength(image);
int rv = rs2_check_firmware_compatibility(reinterpret_cast<const rs2_device *>(handle), image, length, &e);
handle_error(env, e);
return rv > 0;
remibettan marked this conversation as resolved.
Show resolved Hide resolved
}

extern "C"
JNIEXPORT void JNICALL
Java_com_intel_realsense_librealsense_UpdateDevice_nUpdateFirmware(JNIEnv *env, jobject instance,
Expand Down
12 changes: 11 additions & 1 deletion src/ds5/ds5-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <chrono>
#include <vector>
#include <iterator>
#include <cstddef>
#include <string>

#include "device.h"
Expand Down Expand Up @@ -329,6 +328,17 @@ namespace librealsense
});
}

bool ds5_device::check_fw_compatibility(const std::vector<uint8_t>& image) const
{
std::string fw_version = extract_firmware_version_string((const void*)image.data(), image.size());

auto it = ds::device_to_fw_min_version.find(_pid);
if (it == ds::device_to_fw_min_version.end())
throw std::runtime_error("Minimum firmware version has not been defined for this device!");

return (firmware_version(fw_version) >= firmware_version(it->second));
}

class ds5_depth_sensor : public synthetic_sensor, public video_sensor_interface, public depth_stereo_sensor, public roi_sensor_base
{
public:
Expand Down
1 change: 1 addition & 0 deletions src/ds5/ds5-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace librealsense
void enter_update_state() const override;
std::vector<uint8_t> backup_flash(update_progress_callback_ptr callback) override;
void update_flash(const std::vector<uint8_t>& image, update_progress_callback_ptr callback, int update_mode) override;
bool check_fw_compatibility(const std::vector<uint8_t>& image) const override;
protected:

std::vector<uint8_t> get_raw_calibration_table(ds::calibration_table_id table_id) const;
Expand Down
27 changes: 27 additions & 0 deletions src/ds5/ds5-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,33 @@ namespace librealsense
{ res_1152_1152,{ 1152, 1152 } },
};

static std::map<uint16_t, std::string> device_to_fw_min_version = {
{RS400_PID, "5.8.15.0"},
{RS410_PID, "5.8.15.0"},
{RS415_PID, "5.8.15.0"},
{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"},
{RS400_IMU_PID, "5.8.15.0"},
{RS420_PID, "5.8.15.0"},
{RS420_MM_PID, "5.8.15.0"},
{RS410_MM_PID, "5.8.15.0"},
{RS400_MM_PID, "5.8.15.0" },
{RS430_MM_RGB_PID, "5.8.15.0" },
{RS460_PID, "5.8.15.0" },
{RS435_RGB_PID, "5.8.15.0" },
{RS405U_PID, "5.8.15.0" },
{RS435I_PID, "5.12.7.100" },
{RS416_PID, "5.8.15.0" },
{RS430I_PID, "5.8.15.0" },
{RS465_PID, "5.12.7.100" },
{RS416_RGB_PID, "5.8.15.0" },
{RS405_PID, "5.12.11.8" },
{RS455_PID, "5.12.7.100" }
};


ds5_rect_resolutions width_height_to_ds5_rect_resolutions(uint32_t width, uint32_t height);

Expand Down
24 changes: 24 additions & 0 deletions src/fw-update/fw-update-device-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "types.h"
#include "core/streaming.h"
#include <cstddef>

namespace librealsense
{
Expand All @@ -14,6 +15,29 @@ namespace librealsense
virtual void enter_update_state() const = 0;
remibettan marked this conversation as resolved.
Show resolved Hide resolved
virtual std::vector<uint8_t> backup_flash(update_progress_callback_ptr callback) = 0;
virtual void update_flash(const std::vector<uint8_t>& image, update_progress_callback_ptr callback, int update_mode) = 0;
virtual bool check_fw_compatibility(const std::vector<uint8_t>& image) const = 0;
std::string extract_firmware_version_string(const void* fw_image, size_t fw_image_size) const
{
if (!fw_image)
throw std::runtime_error("Firmware binary image might be corrupted - null pointer");

auto version_offset = offsetof(platform::dfu_header, bcdDevice);

if (fw_image_size < (version_offset + sizeof(size_t)))
throw std::runtime_error("Firmware binary image might be corrupted - size is only: " + fw_image_size);

uint32_t version{};

memcpy(reinterpret_cast<char*>(&version), reinterpret_cast<const char*>(fw_image) +
remibettan marked this conversation as resolved.
Show resolved Hide resolved
version_offset, sizeof(version));

uint8_t major = (version & 0xFF000000) >> 24;
uint8_t minor = (version & 0x00FF0000) >> 16;
uint8_t patch = (version & 0x0000FF00) >> 8;
uint8_t build = version & 0x000000FF;

return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(patch) + "." + std::to_string(build);
}
};

class update_device_interface : public device_interface
Expand Down
15 changes: 15 additions & 0 deletions src/ivcam/sr300.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ namespace librealsense

auto fw_version = _hw_monitor->get_firmware_version_string(gvd_buff, fw_version_offset);
auto serial = _hw_monitor->get_module_serial_string(gvd_buff, module_serial_offset);
_pid = depth.pid;
auto pid_hex_str = hexify(depth.pid);

_camer_calib_params = [this]() { return get_calibration(); };
Expand Down Expand Up @@ -581,6 +582,20 @@ namespace librealsense
return command{ ivcam::FlashRead, 0x000B6000, 0x3f8 };
}

bool sr3xx_camera::check_fw_compatibility(const std::vector<uint8_t>& image) const
{
std::string fw_version = extract_firmware_version_string((const void*)image.data(), image.size());

auto min_max_fw_it = device_to_fw_min_max_version.find(_pid);
if (min_max_fw_it == device_to_fw_min_max_version.end())
throw std::runtime_error("Min and Max firmware versions have not been defined for this device!");

// advanced SR3XX devices do not fit the "old" fw versions and
// legacy SR3XX devices do not fit the "new" fw versions
return (firmware_version(fw_version) >= firmware_version(min_max_fw_it->second.first)) &&
remibettan marked this conversation as resolved.
Show resolved Hide resolved
(firmware_version(fw_version) <= firmware_version(min_max_fw_it->second.second));
}

void sr3xx_camera::create_snapshot(std::shared_ptr<debug_interface>& snapshot) const
{
//TODO: implement
Expand Down
12 changes: 11 additions & 1 deletion src/ivcam/sr300.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,22 @@ namespace librealsense
const uint16_t SR306_PID = 0x0aa3;
const uint16_t SR306_PID_DBG = 0x0aa2;
const uint16_t SR300_PID = 0x0aa5;
const uint16_t SR300v2_PID = 0x0B48;
const uint16_t SR300v2_PID = 0x0B48; //SR305
const uint16_t SR300_RECOVERY = 0x0ab3;

const double TIMESTAMP_10NSEC_TO_MSEC = 0.00001;

class sr300_camera;
class sr3xx_camera;

static std::map<uint16_t, std::pair<std::string, std::string>> device_to_fw_min_max_version = {
{ SR300_PID, {"3.21.0.0", "3.26.3.0"}},
remibettan marked this conversation as resolved.
Show resolved Hide resolved
{ SR300v2_PID, {"3.27.0.0", "99.99.99.99"}},
{ SR306_PID, {"3.28.3.0", "99.99.99.99"}},
{ SR306_PID_DBG, {"3.28.3.0", "99.99.99.99"}},
{ SR300_RECOVERY, {"3.21.0.0", "99.99.99.99"}}
};

class sr300_timestamp_reader : public frame_timestamp_reader
{
bool started;
Expand Down Expand Up @@ -420,11 +428,13 @@ namespace librealsense
void enter_update_state() const override;
std::vector<uint8_t> backup_flash(update_progress_callback_ptr callback) override;
void update_flash(const std::vector<uint8_t>& image, update_progress_callback_ptr callback, int update_mode) override;
bool check_fw_compatibility(const std::vector<uint8_t>& image) const override;

virtual std::shared_ptr<matcher> create_matcher(const frame_holder& frame) const override;

private:
const uint8_t _depth_device_idx;
uint16_t _pid;
bool _is_locked = true;

template<class T>
Expand Down
15 changes: 13 additions & 2 deletions src/l500/l500-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ namespace librealsense
_temperatures()
{
_depth_device_idx = add_sensor(create_depth_device(ctx, group.uvc_devices));
auto pid = group.uvc_devices.front().pid;
std::string device_name = (rs500_sku_names.end() != rs500_sku_names.find(pid)) ? rs500_sku_names.at(pid) : "RS5xx";
_pid = group.uvc_devices.front().pid;
std::string device_name = (rs500_sku_names.end() != rs500_sku_names.find(_pid)) ? rs500_sku_names.at(_pid) : "RS5xx";

using namespace ivcam2;

Expand Down Expand Up @@ -693,6 +693,17 @@ namespace librealsense
}
}

bool l500_device::check_fw_compatibility(const std::vector<uint8_t>& image) const
{
std::string fw_version = extract_firmware_version_string((const void*)image.data(), image.size());

auto it = ivcam2::device_to_fw_min_version.find(_pid);
if (it == ivcam2::device_to_fw_min_version.end())
throw std::runtime_error("Minimum firmware version has not been defined for this device!");

return (firmware_version(fw_version) >= firmware_version(it->second));
}

notification l500_notification_decoder::decode(int value)
{
// Anything listed in l500-private.h on l500_fw_error_report is an error; everything else is a warning
Expand Down
2 changes: 2 additions & 0 deletions src/l500/l500-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace librealsense
update_progress_callback_ptr callback, float continue_from, float ratio);
void update_flash_internal(std::shared_ptr<hw_monitor> hwm, const std::vector<uint8_t>& image, std::vector<uint8_t>& flash_backup,
update_progress_callback_ptr callback, int update_mode);
bool check_fw_compatibility(const std::vector<uint8_t>& image) const override;

ivcam2::extended_temperatures get_temperatures() const;

Expand All @@ -79,6 +80,7 @@ namespace librealsense

std::shared_ptr<hw_monitor> _hw_monitor;
uint8_t _depth_device_idx;
uint16_t _pid;

std::shared_ptr<polling_error_handler> _polling_error_handler;

Expand Down
1 change: 1 addition & 0 deletions src/l500/l500-fw-update-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ namespace librealsense

return rv.str();
}

}
10 changes: 10 additions & 0 deletions src/l500/l500-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ namespace librealsense

};

static std::map<uint16_t, std::string> device_to_fw_min_version = {
{ L500_RECOVERY_PID, "1.4.1.0"},
{ L535_RECOVERY_PID, "1.4.1.0"},
{ L500_USB2_RECOVERY_PID_OLD, "1.4.1.0"},
{ L500_PID, "1.4.1.0"},
{ L515_PID_PRE_PRQ, "1.4.1.0"},
{ L515_PID, "1.4.1.0"},
{ L535_PID, "1.4.1.0"}
};

// Known FW error codes, if we poll for errors (RS2_OPTION_ERROR_POLLING_ENABLED)
enum l500_notifications_types
{
Expand Down
1 change: 1 addition & 0 deletions src/realsense.def
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ EXPORTS
rs2_create_flash_backup_cpp
rs2_update_firmware_unsigned
rs2_update_firmware_unsigned_cpp
rs2_check_firmware_compatibility
rs2_enter_update_state
rs2_run_on_chip_calibration_cpp
rs2_run_tare_calibration_cpp
Expand Down
Loading