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

Replace GVD queries with device update notification to verify device removal during DFU #8913

Merged
merged 4 commits into from
May 4, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 0 additions & 2 deletions common/fw-update-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,6 @@ namespace rs2
// if querying devices is called while device still switching to DFU state, an exception will be thrown
// to prevent that, a blocking is added to make sure device is updated before continue to next step of querying device
upd.enter_update_state();
// Allow time for the device to disconnect before calling "query_devices"
std::this_thread::sleep_for(std::chrono::seconds(2));

if (!check_for([this, serial, &dfu]() {
auto devs = _ctx.query_devices();
Expand Down
7 changes: 4 additions & 3 deletions src/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
#include <fstream>


const uint16_t MAX_RETRIES = 100;
const uint8_t DEFAULT_V4L2_FRAME_BUFFERS = 4;
const uint16_t DELAY_FOR_RETRIES = 50;
const uint16_t MAX_RETRIES = 100;
const uint8_t DEFAULT_V4L2_FRAME_BUFFERS = 4;
const uint16_t DELAY_FOR_RETRIES = 50;
const int POLLING_DEVICES_INTERVAL_MS = 5000;

const uint8_t MAX_META_DATA_SIZE = 0xff; // UVC Metadata total length
// is limited by (UVC Bulk) design to 255 bytes
Expand Down
6 changes: 3 additions & 3 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ namespace librealsense
class device_info
{
public:
virtual std::shared_ptr<device_interface> create_device(bool register_device_notifications = false) const
virtual std::shared_ptr<device_interface> create_device() const
{
return create(_ctx, register_device_notifications);
return create(_ctx, true);
}

virtual ~device_info() = default;
Expand Down Expand Up @@ -86,7 +86,7 @@ namespace librealsense

}

std::shared_ptr<device_interface> create_device(bool) const override
std::shared_ptr<device_interface> create_device() const override
{
return _dev;
}
Expand Down
4 changes: 3 additions & 1 deletion src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ namespace librealsense

virtual void stop_activity() const;

bool device_changed_notifications_on() const { return _device_changed_notifications; }

protected:
int add_sensor(const std::shared_ptr<sensor_interface>& sensor_base);
int assign_sensor(const std::shared_ptr<sensor_interface>& sensor_base, uint8_t idx);
Expand All @@ -88,7 +90,7 @@ namespace librealsense

explicit device(std::shared_ptr<context> ctx,
const platform::backend_device_group group,
bool device_changed_notifications = false);
bool device_changed_notifications = true);

std::map<int, std::pair<uint32_t, std::shared_ptr<const stream_interface>>> _extrinsics;

Expand Down
8 changes: 3 additions & 5 deletions src/device_hub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,9 @@ namespace librealsense
return result;
}

device_hub::device_hub(std::shared_ptr<librealsense::context> ctx, int mask, int vid,
bool register_device_notifications)
device_hub::device_hub(std::shared_ptr<librealsense::context> ctx, int mask, int vid)
: _ctx(ctx), _vid(vid),
_device_changes_callback_id(0),
_register_device_notifications(register_device_notifications)
_device_changes_callback_id(0)
{
_device_list = filter_by_vid(_ctx->query_devices(mask), _vid);

Expand Down Expand Up @@ -82,7 +80,7 @@ namespace librealsense
auto d = _device_list[ (_camera_index + i) % _device_list.size()];
try
{
auto dev = d->create_device(_register_device_notifications);
auto dev = d->create_device();

if(serial.size() > 0 )
{
Expand Down
3 changes: 1 addition & 2 deletions src/device_hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace librealsense
class device_hub
{
public:
explicit device_hub(std::shared_ptr<librealsense::context> ctx, int mask = RS2_PRODUCT_LINE_ANY, int vid = 0, bool register_device_notifications = true);
explicit device_hub(std::shared_ptr<librealsense::context> ctx, int mask = RS2_PRODUCT_LINE_ANY, int vid = 0);

~device_hub();

Expand Down Expand Up @@ -54,6 +54,5 @@ namespace librealsense
int _camera_index = 0;
int _vid = 0;
uint64_t _device_changes_callback_id;
bool _register_device_notifications;
};
}
36 changes: 23 additions & 13 deletions src/ds5/ds5-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,26 +137,36 @@ namespace librealsense
using namespace std;
using namespace std::chrono;

try {
LOG_INFO("entering to update state, device disconnect is expected");
command cmd(ds::DFU);
try
{
LOG_INFO( "entering to update state, device disconnect is expected" );
command cmd( ds::DFU );
cmd.param1 = 1;
_hw_monitor->send(cmd);
std::vector<uint8_t> gvd_buff(HW_MONITOR_BUFFER_SIZE);
for (auto i = 0; i < 50; i++)
_hw_monitor->send( cmd );

// We allow 6 seconds because on Linux the removal status is updated at a 5 seconds rate.
const int MAX_ITERATIONS_FOR_DEVICE_DISCONNECTED_LOOP = (POLLING_DEVICES_INTERVAL_MS + 1000) / DELAY_FOR_RETRIES;
for( auto i = 0; i < MAX_ITERATIONS_FOR_DEVICE_DISCONNECTED_LOOP; i++ )
{
_hw_monitor->get_gvd(gvd_buff.size(), gvd_buff.data(), ds::GVD);
this_thread::sleep_for(milliseconds(50));
// If the device was detected as removed we assume the device is entering update mode
// Note: if no device status callback is registered we will wait the whole time and it is OK
if( ! is_valid() )
maloel marked this conversation as resolved.
Show resolved Hide resolved
return;

this_thread::sleep_for( milliseconds( DELAY_FOR_RETRIES ) );
}
throw std::runtime_error("Device still connected!");


if (device_changed_notifications_on())
LOG_WARNING( "Timeout waiting for device disconnect after DFU command!" );
}
catch (std::exception& e)
catch( std::exception & e )
{
LOG_WARNING(e.what());
LOG_WARNING( e.what() );
}
catch (...) {
// The set command returns a failure because switching to DFU resets the device while the command is running.
catch( ... )
{
LOG_ERROR( "Unknown error during entering DFU state" );
}
}

Expand Down
35 changes: 23 additions & 12 deletions src/ivcam/sr300.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,24 +339,35 @@ namespace librealsense
using namespace std;
using namespace std::chrono;

try {
command cmd(ivcam::GoToDFU);
try
{
command cmd( ivcam::GoToDFU );
cmd.param1 = 1;
_hw_monitor->send(cmd);
std::vector<uint8_t> gvd_buff(HW_MONITOR_BUFFER_SIZE);
for (auto i = 0; i < 50; i++)
_hw_monitor->send( cmd );

// We allow 6 seconds because on Linux the removal status is updated at a 5 seconds rate.
const int MAX_ITERATIONS_FOR_DEVICE_DISCONNECTED_LOOP = (POLLING_DEVICES_INTERVAL_MS + 1000) / DELAY_FOR_RETRIES;

for( auto i = 0; i < MAX_ITERATIONS_FOR_DEVICE_DISCONNECTED_LOOP; i++ )
{
_hw_monitor->get_gvd(gvd_buff.size(), gvd_buff.data(), ds::GVD);
this_thread::sleep_for(milliseconds(50));
// If the device was detected as removed we assume the device is entering update mode
// Note: if no device status callback is registered we will wait the whole time and it is OK
if( ! is_valid() )
return;

this_thread::sleep_for( milliseconds( DELAY_FOR_RETRIES ) );
}
throw std::runtime_error("Device still connected!");

if (device_changed_notifications_on())
LOG_WARNING("Timeout waiting for device disconnect after DFU command!");
}
catch (std::exception& e)
catch( std::exception & e )
{
LOG_WARNING(e.what());
LOG_WARNING( e.what() );
}
catch (...) {
// The set command returns a failure because switching to DFU resets the device while the command is running.
catch( ... )
{
LOG_WARNING("Timeout waiting for device disconnect after DFU command!");
maloel marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
35 changes: 22 additions & 13 deletions src/l500/l500-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,26 +456,35 @@ namespace librealsense
using namespace std;
using namespace std::chrono;

try {
LOG_INFO("entering to update state, device disconnect is expected");
command cmd(ivcam2::DFU);
try
{
LOG_INFO( "entering to update state, device disconnect is expected" );
command cmd( ivcam2::DFU );
cmd.param1 = 1;
_hw_monitor->send(cmd);
std::vector<uint8_t> gvd_buff(HW_MONITOR_BUFFER_SIZE);
for (auto i = 0; i < 50; i++)
_hw_monitor->send( cmd );

// We allow 6 seconds because on Linux the removal status is updated at a 5 seconds rate.
const int MAX_ITERATIONS_FOR_DEVICE_DISCONNECTED_LOOP = (POLLING_DEVICES_INTERVAL_MS + 1000) / DELAY_FOR_RETRIES;
for( auto i = 0; i < MAX_ITERATIONS_FOR_DEVICE_DISCONNECTED_LOOP; i++ )
{
// If the device was detected as removed we assume the device is entering update mode
// Note: if no device status callback is registered we will wait the whole time and it is OK
if( ! is_valid() )
return;

_hw_monitor->get_gvd(gvd_buff.size(), gvd_buff.data(), GVD);
this_thread::sleep_for(milliseconds(50));
this_thread::sleep_for( milliseconds(DELAY_FOR_RETRIES) );
}
throw std::runtime_error("Device still connected!");

if (device_changed_notifications_on())
LOG_WARNING("Timeout waiting for device disconnect after DFU command!");
}
catch (std::exception& e) {
LOG_WARNING(e.what());
catch( std::exception & e )
{
LOG_ERROR( e.what() );
}
catch (...) {
// The set command returns a failure because switching to DFU resets the device while the command is running.
catch( ... )
{
LOG_ERROR( "Unknown error during entering DFU state" );
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/pipeline/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ namespace librealsense
{
try
{
auto dev = dev_info->create_device(true);
auto dev = dev_info->create_device();
_resolved_profile = resolve(dev);
return _resolved_profile;
}
Expand Down Expand Up @@ -256,7 +256,7 @@ namespace librealsense
}
}

return ctx->add_device(file)->create_device(false);
return ctx->add_device(file)->create_device();
Copy link
Collaborator

Choose a reason for hiding this comment

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

So playback device will get notifications now? Can it even be "removed"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, playback device override the create_device() function and is not calling the function we change it's defaults.
So it's OK, nothing changed there.

}

std::shared_ptr<device_interface> config::resolve_device_requests(std::shared_ptr<pipeline> pipe, const std::chrono::milliseconds& timeout)
Expand Down
2 changes: 1 addition & 1 deletion src/rs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1522,7 +1522,7 @@ rs2_device* rs2_context_add_device(rs2_context* ctx, const char* file, rs2_error
VALIDATE_NOT_NULL(file);

auto dev_info = ctx->ctx->add_device(file);
return new rs2_device{ ctx->ctx, dev_info, dev_info->create_device(false) };
return new rs2_device{ ctx->ctx, dev_info, dev_info->create_device() };
}
HANDLE_EXCEPTIONS_AND_RETURN(nullptr, ctx, file)

Expand Down
2 changes: 1 addition & 1 deletion src/software-device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace librealsense
{
software_device::software_device()
: device(std::make_shared<context>(backend_type::standard), {}),
: device(std::make_shared<context>(backend_type::standard), {}, false),
_user_destruction_callback()
{
register_info(RS2_CAMERA_INFO_NAME, "Software-Device");
Expand Down
2 changes: 1 addition & 1 deletion src/software-device.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace librealsense
{
}

std::shared_ptr<device_interface> create_device(bool) const override
std::shared_ptr<device_interface> create_device() const override
{
return _dev.lock();
}
Expand Down
2 changes: 1 addition & 1 deletion src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,7 @@ namespace librealsense

void polling(dispatcher::cancellable_timer cancellable_timer)
{
if(cancellable_timer.try_sleep(5000))
if(cancellable_timer.try_sleep(POLLING_DEVICES_INTERVAL_MS))
{
platform::backend_device_group curr(_backend->query_uvc_devices(), _backend->query_usb_devices(), _backend->query_hid_devices());
if(list_changed(_devices_data.uvc_devices, curr.uvc_devices ) ||
Expand Down