rs-fw-update.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2015 Intel Corporation. All Rights Reserved.
3 
4 #include <librealsense2/rs.hpp>
5 
6 #include <vector>
7 #include <map>
8 #include <string>
9 #include <iostream>
10 #include <fstream>
11 #include <thread>
12 #include <mutex>
13 #include <chrono>
14 #include <condition_variable>
15 
16 #include "tclap/CmdLine.h"
17 #include "tclap/ValueArg.h"
18 
19 using namespace TCLAP;
20 
21 #define WAIT_FOR_DEVICE_TIMEOUT 10
22 
23 std::vector<uint8_t> read_fw_file(std::string file_path)
24 {
25  std::vector<uint8_t> rv;
26 
27  std::ifstream file(file_path, std::ios::in | std::ios::binary | std::ios::ate);
28  if (file.is_open())
29  {
30  rv.resize(file.tellg());
31 
32  file.seekg(0, std::ios::beg);
33  file.read((char*)rv.data(), rv.size());
34  file.close();
35  }
36 
37  return rv;
38 }
39 
41 {
42  std::map<rs2_camera_info, std::string> camera_info;
43 
44  for (int i = 0; i < RS2_CAMERA_INFO_COUNT; i++)
45  {
46  auto info = (rs2_camera_info)i;
47  camera_info[info] = d.supports(info) ? d.get_info(info) : "unknown";
48  }
49 
50  std::cout << "Name: " << camera_info[RS2_CAMERA_INFO_NAME] <<
51  ", serial number: " << camera_info[RS2_CAMERA_INFO_SERIAL_NUMBER] <<
52  ", update serial number: " << camera_info[RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID] <<
53  ", firmware version: " << camera_info[RS2_CAMERA_INFO_FIRMWARE_VERSION] <<
54  ", USB type: " << camera_info[RS2_CAMERA_INFO_USB_TYPE_DESCRIPTOR] << std::endl;
55 }
56 
57 std::vector<uint8_t> read_firmware_data(bool is_set, const std::string& file_path)
58 {
59  if (!is_set)
60  {
61  throw rs2::error("firmware file must be selected");
62  }
63 
64  std::vector<uint8_t> fw_image = read_fw_file(file_path);
65 
66  if (fw_image.size() == 0)
67  {
68  throw rs2::error("failed to read firmware file");
69  }
70 
71  return fw_image;
72 }
73 
74 
75 void update(rs2::update_device fwu_dev, std::vector<uint8_t> fw_image)
76 {
77  std::cout << std::endl << "firmware update started"<< std::endl << std::endl;
78 
79  fwu_dev.update(fw_image, [&](const float progress)
80  {
81  printf("\rfirmware update progress: %d[%%]", (int)(progress * 100));
82  });
83  std::cout << std::endl << std::endl << "firmware update done" << std::endl;
84 }
85 
87 {
88  auto devs = ctx.query_devices();
89  if (devs.size() == 0)
90  {
91  std::cout << std::endl << "there are no connected devices" << std::endl;
92  return;
93  }
94 
95  std::cout << std::endl << "connected devices:" << std::endl;
96 
97 
98  int counter = 0;
99  for (auto&& d : devs)
100  {
101  std::cout << ++counter << ") ";
103  }
104 }
105 
106 int main(int argc, char** argv) try
107 {
108 #ifdef BUILD_EASYLOGGINGPP
110 #endif
111 
113 
114  std::condition_variable cv;
115  std::mutex mutex;
116  std::string selected_serial_number;
117 
118  rs2::device new_device;
119  rs2::update_device new_fw_update_device;
120 
121  bool done = false;
122 
123  CmdLine cmd("librealsense rs-fw-update tool", ' ', RS2_API_VERSION_STR);
124 
125  SwitchArg list_devices_arg("l", "list_devices", "List all available devices");
126  SwitchArg recover_arg("r", "recover", "Recover all connected devices which are in recovery mode");
127  SwitchArg unsigned_arg("u", "unsigned", "Update unsigned firmware, available only for unlocked cameras");
128  ValueArg<std::string> backup_arg("b", "backup", "Create a backup to the camera flash and saved it to the given path", false, "", "string");
129  ValueArg<std::string> file_arg("f", "file", "Path of the firmware image file", false, "", "string");
130  ValueArg<std::string> serial_number_arg("s", "serial_number", "The serial number of the device to be update, this is mandetory if more than one device is connected", false, "", "string");
131 
132  cmd.add(list_devices_arg);
133  cmd.add(recover_arg);
134  cmd.add(unsigned_arg);
135  cmd.add(file_arg);
136  cmd.add(serial_number_arg);
137  cmd.add(backup_arg);
138 
139  cmd.parse(argc, argv);
140 
141  bool recovery_request = recover_arg.getValue();
142 
143  if (list_devices_arg.isSet())
144  {
145  list_devices(ctx);
146  return EXIT_SUCCESS;
147  }
148 
149  if (!file_arg.isSet() && !backup_arg.isSet())
150  {
151  std::cout << std::endl << "nothing to do, run again with -h for help" << std::endl;
152  return EXIT_FAILURE;
153  }
154 
155  if (serial_number_arg.isSet())
156  {
157  selected_serial_number = serial_number_arg.getValue();
158  std::cout << std::endl << "search for device with serial number: " << selected_serial_number << std::endl;
159  }
160 
161  std::string update_serial_number;
162 
163  // Recovery
164  bool recovery_executed = false;
165  if (recover_arg.isSet() )
166  {
167  std::vector<uint8_t> fw_image = read_firmware_data(file_arg.isSet(), file_arg.getValue());
168 
169  std::cout << std::endl << "update to FW: " << file_arg.getValue() << std::endl;
170  auto devs = ctx.query_devices(RS2_PRODUCT_LINE_DEPTH);
171  for (auto&& d : devs)
172  {
173  if (!d.is<rs2::update_device>())
174  continue;
175  try
176  {
177  std::cout << std::endl << "recovering device: " << std::endl;
179  update(d, fw_image);
180  recovery_executed = true;
181  }
182  catch (...)
183  {
184  std::cout << std::endl << "failed to recover device" << std::endl;
185  }
186  }
187  if (recovery_executed)
188  {
189  std::cout << std::endl << "recovery done" << std::endl;
190  return EXIT_SUCCESS;
191  }
192  return EXIT_FAILURE;
193  }
194 
195  // Update device
197  {
198  if (info.get_new_devices().size() == 0)
199  {
200  return;
201  }
202 
203  for (auto&& d : info.get_new_devices())
204  {
205  std::lock_guard<std::mutex> lk(mutex);
206  if (d.is<rs2::update_device>() && (d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID) == update_serial_number))
207  new_fw_update_device = d;
208  else
209  new_device = d;
210  }
211  if(new_fw_update_device || new_device)
212  cv.notify_one();
213  });
214 
215  auto devs = ctx.query_devices(RS2_PRODUCT_LINE_DEPTH);
216 
217  if (!serial_number_arg.isSet() && devs.size() > 1)
218  {
219  std::cout << std::endl << "more than one device is connected, serial number must be selected" << std::endl << std::endl;
220  return EXIT_FAILURE;
221  }
222 
223  bool device_found = false;
224 
225  for (auto&& d : devs)
226  {
228  continue;
229 
231  {
233  if (usb_type.find("2.") != std::string::npos) {
234  std::cout << std::endl << "Warning! the camera is connected via USB 2 port, in case the process fails, connect the camera to a USB 3 port and try again" << std::endl;
235  }
236  }
237 
238  update_serial_number = d.get_info(RS2_CAMERA_INFO_FIRMWARE_UPDATE_ID);
239 
240  auto sn = d.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
241  if (sn != selected_serial_number && devs.size() != 1)
242  continue;
243  device_found = true;
244  auto fw = d.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION);
245 
246  if (backup_arg.isSet())
247  {
248  std::cout << std::endl << "backing-up device flash: " << std::endl;
249 
250  auto flash = d.as<rs2::updatable>().create_flash_backup([&](const float progress)
251  {
252  printf("\rflash backup progress: %d[%%]", (int)(progress * 100));
253  });
254 
255  auto temp = backup_arg.getValue();
256  std::ofstream file(temp.c_str(), std::ios::binary);
257  file.write((const char*)flash.data(), flash.size());
258  }
259 
260  if (!file_arg.isSet())
261  continue;
262 
263  std::vector<uint8_t> fw_image = read_firmware_data(file_arg.isSet(), file_arg.getValue());
264 
265  std::cout << std::endl << "updating device: " << std::endl;
267 
268  if (unsigned_arg.isSet())
269  {
270  std::cout << std::endl << "firmware update started" << std::endl << std::endl;
271 
272  d.as<rs2::updatable>().update_unsigned(fw_image, [&](const float progress)
273  {
274  printf("\rfirmware update progress: %d[%%]", (int)(progress * 100));
275  });
276  std::cout << std::endl << std::endl << "firmware update done" << std::endl;
277  }
278  else
279  {
280  d.as<rs2::updatable>().enter_update_state();
281 
282  std::unique_lock<std::mutex> lk(mutex);
283  if (!cv.wait_for(lk, std::chrono::seconds(WAIT_FOR_DEVICE_TIMEOUT), [&] { return new_fw_update_device; }))
284  {
285  std::cout << std::endl << "failed to locate a device in FW update mode" << std::endl;
286  return EXIT_FAILURE;
287  }
288 
289  update(new_fw_update_device, fw_image);
290  done = true;
291  break;
292  }
293  }
294 
295  if (!device_found)
296  {
297  if(serial_number_arg.isSet())
298  std::cout << std::endl << "couldn't find the requested serial number" << std::endl;
299  else if (devs.size() == 1)
300  {
301  std::cout << std::endl << "nothing to do, run again with -h for help" << std::endl;
302  }
303  return EXIT_FAILURE;
304  }
305 
306  std::unique_lock<std::mutex> lk(mutex);
307  cv.wait_for(lk, std::chrono::seconds(WAIT_FOR_DEVICE_TIMEOUT), [&] { return !done || new_device; });
308 
309  if (done)
310  {
311  auto devs = ctx.query_devices();
312  for (auto&& d : devs)
313  {
314  auto sn = d.supports(RS2_CAMERA_INFO_SERIAL_NUMBER) ? d.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER) : "unknown";
315  if (serial_number_arg.isSet() && sn != selected_serial_number)
316  continue;
317 
318  auto fw = d.supports(RS2_CAMERA_INFO_FIRMWARE_VERSION) ? d.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION) : "unknown";
319  std::cout << std::endl << "device " << sn << " successfully updated to FW: " << fw << std::endl;
320  }
321  }
322 
323  return EXIT_SUCCESS;
324 }
325 catch (const rs2::error & e)
326 {
327  std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
328  return EXIT_FAILURE;
329 }
std::vector< uint8_t > read_fw_file(std::string file_path)
rs2_camera_info
Read-only strings that can be queried from the device. Not all information attributes are available o...
Definition: rs_sensor.h:22
int main(int argc, char **argv)
#define WAIT_FOR_DEVICE_TIMEOUT
std::vector< uint8_t > read_firmware_data(bool is_set, const std::string &file_path)
device_list query_devices() const
Definition: rs_context.hpp:112
uint32_t size() const
Definition: rs_device.hpp:711
def progress(args)
Definition: log.py:43
GLsizei const GLchar *const * string
d
Definition: rmse.py:171
e
Definition: rmse.py:177
void print_device_info(rs2::device d)
static const textual_icon usb_type
Definition: model-views.h:249
def info(name, value, persistent=False)
Definition: test.py:301
const std::string & get_failed_args() const
Definition: rs_types.hpp:117
void update(rs2::update_device fwu_dev, std::vector< uint8_t > fw_image)
void update(const std::vector< uint8_t > &fw_image) const
Definition: rs_device.hpp:267
std::ostream & cout()
GLuint counter
Definition: glext.h:5684
const char * get_info(rs2_camera_info info) const
Definition: rs_device.hpp:79
static std::condition_variable cv
bool isSet() const
Definition: Arg.h:575
static int done
device_list get_new_devices() const
Definition: rs_context.hpp:57
bool supports(rs2_camera_info info) const
Definition: rs_device.hpp:66
#define RS2_PRODUCT_LINE_DEPTH
Definition: rs_context.h:98
T & getValue()
Definition: ValueArg.h:322
void log_to_console(rs2_log_severity min_severity)
Definition: rs.hpp:19
void list_devices(rs2::context ctx)
void parse(int argc, const char *const *argv)
Definition: CmdLine.h:433
GLuint in
Definition: glext.h:8859
const GLuint GLenum const void * binary
Definition: glext.h:1882
#define RS2_API_VERSION_STR
Definition: rs.h:43
std::ostream & cerr()
void add(Arg &a)
Definition: CmdLine.h:413
void set_devices_changed_callback(T callback)
Definition: rs_context.hpp:169
int i
Definition: Arg.h:57
const std::string & get_failed_function() const
Definition: rs_types.hpp:112


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:40