iCub-main
main.cpp
Go to the documentation of this file.
1 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 
3 /*
4  * Copyright (C) 2008 RobotCub Consortium
5  * Author: Marco Maggiali, Marco Randazzo, Alessandro Scalzo, Marco Accame
6  * CopyPolicy: Released under the terms of the GNU GPL v2.0.
7  *
8  */
9 
132 #include "downloader.h"
133 #include "driver.h"
134 #include <yarp/os/Time.h>
135 #include <yarp/os/Log.h>
136 #include <yarp/dev/Drivers.h>
137 
138 #include <string> //stl string
139 #include <string.h> //memcpy ...
140 #include <stdlib.h>
141 
142 #include <stdio.h>
143 #include <fcntl.h>
144 
145 #include <iCubCanProtocol.h>
146 #include <iCubCanProto_types.h>
147 
149 
150 //can_parameters_type params;
151 int networkId=0;
152 int canID=1;
153 unsigned int localAddr=0;
154 unsigned int remoteAddr=0;
155 const int maxNetworks=10; //max number of can networks
156 std::string networkType;
158 bool prompt_version=false;
159 
160 //enum
161 //{
162 // COLUMN_SELECTED,
163 // COLUMN_ID,
164 // COLUMN_TYPE,
165 // COLUMN_VERSION,
166 // COLUMN_RELEASE,
167 // COLUMN_BUILD,
168 // COLUMN_SERIAL,
169 // COLUMN_STATUS,
170 // COLUMN_ADD_INFO,
171 // COLUMN_EEPROM,
172 // NUM_COLUMNS
173 //};
174 
175 #define ALL_OK 0
176 #define INVALID_CMD_STRING -1
177 #define INVALID_PARAM_CANTYPE -2
178 #define INVALID_PARAM_CANNUM -3
179 #define INVALID_PARAM_BOARDID -4
180 #define INVALID_PARAM_FILE -5
181 #define ERR_NO_BOARDS_FOUND -10
182 #define ERR_BOARD_ID_NOT_FOUND -11
183 #define ERR_UNKNOWN -12
184 #define ERR_NO_NETWORK_INTERFACE -13
185 #define DOWNLOADERR_NOT_CONNECTED -20
186 #define DOWNLOADERR_BOARD_NOT_SEL -21
187 #define DOWNLOADERR_FILE_NOT_SEL -22
188 #define DOWNLOADERR_FILE_NOT_OPEN -23
189 #define DOWNLOADERR_BOARD_NOT_START -24
190 #define DOWNLOADERR_TRANSFER_ERROR -25
191 
192 
193 
194 
195 //*********************************************************************************
196 
197 
198 static bool compile_ip_addresses(const char* addr)
199 {
200  ACE_UINT32 ip1,ip2,ip3,ip4;
201  sscanf(addr,"%d.%d.%d.%d",&ip1,&ip2,&ip3,&ip4);
202  remoteAddr=(ip1<<24)|(ip2<<16)|(ip3<<8)|ip4;
203 
204  size_t count=0;
205  ACE_INET_Addr* addr_array=NULL;
206  int ret=ACE::get_ip_interfaces(count,addr_array);
207 
208  if (ret || count<=0)
209  {
210  return false;
211  }
212 
213  localAddr=addr_array[0].get_ip_address();
214 
215  for (unsigned int a=1; a<count; ++a)
216  {
217  if ((remoteAddr & 0xFFFF0000)==(addr_array[a].get_ip_address() & 0xFFFF0000))
218  {
219  localAddr=addr_array[a].get_ip_address();
220  break;
221  }
222  }
223 
224  return true;
225 }
226 
227 
228 static void start_end_click ()
229 {
230  int ret = 0;
231 
232  if (downloader.connected==false)
233  {
234  yarp::os::Property params;
235  params.put("device", networkType.c_str());
236 
237  if (networkType=="ETH")
238  {
239  yError() << "ETH not supported yet" ;
240  }
241  else
242  {
243  params.put("canDeviceNum", networkId);
244  params.put("canTxQueue", 64);
245  params.put("canRxQueue", 64);
246  params.put("canTxTimeout", 2000);
247  params.put("canRxTimeout", 2000);
248  }
249 
250  //try to connect to the driver
251  ret = downloader.initdriver(params);
252 
253  if (ret == -1)
254  {
255  yError() << "Init driver failed" << "Hardware busy or not connected?!";
256  return;
257  }
258 
259  //drv_sleep (2000);
260  //get the infos from the board
261  ret = downloader.initschede();
262 
263  if (ret == -1)
264  {
265  yError() << "Communication error" << "No answers received (no boards found).";
267  return;
268  }
269 
270  //enable select/deselect all buttons
271  yInfo() << "Driver Connected";
272  }
273  else
274  {
276  yInfo() << "Driver Stopped";
277  }
278 }
279 
280 //*********************************************************************************
281 static int download_click (std::string* user_data)
282 {
283  double timer_start =0;
284  double timer_end =0;
285  // check if can driver is running
286  if (downloader.connected == false)
287  {
288  yError() << "Driver not running " << " Use 'Connect' button to start the driver";
290  }
291 
292  //check if at least one board was selected
293  bool at_least_one_board_selected = false;
294  int i = 0;
295 
296  for (i=0; i<downloader.board_list_size; i++)
297  {
299  downloader.board_list[i].selected==true)
300  at_least_one_board_selected = true;
301  }
302 
303  if (!at_least_one_board_selected)
304  {
305  yError() << "No Boards selected! " << "Select one or more boards to download the firmware";
307  }
308 
309  // Open the selected file
310  char* buffer=NULL;
311 
312  if (user_data==NULL)
313  {
314  yError() << "No files selected! " << "Select the file You want to download, first";
316  }
317  else
318  {
319  std::string* p = (std::string*)user_data;
320  buffer = new char[255];
321  strcpy(buffer,(p->c_str()));
322  }
323  if (downloader.open_file(buffer)!=0)
324  {
325  yError() << "Error opening the selected file!";
327  }
328 
329  // Get an identification of the firmware fot the file that you have selected
330  int firmware_board_type=0;
331  int firmware_version=0;
332  int firmware_revision=0;
333 
334  //indentify download type from the type of the selected boards
335  int download_type = icubCanProto_boardType__unknown;
336  bool download_eeprom =false;
337  for (i=0; i<downloader.board_list_size; i++)
338  {
339  if (downloader.board_list[i].selected==true)
340  {
341  download_type = downloader.board_list[i].type;
342  download_eeprom = downloader.board_list[i].eeprom;
343  }
344 
345  }
346 
347  // Start the download for the selected boards
348  for (i=0; i<downloader.board_list_size; i++)
349  {
351  downloader.board_list[i].selected==true)
352  {
354  {
355  yError() << "Unable to start the board" << "Unable to send message 'start' or no answer received";
357  }
358  else
359  {
361  }
362  }
363  }
364 
365  int ret = 0;
366  int finished = 0;
367 
368  timer_start= yarp::os::Time::now();
369 
370  bool print00 = false, print25 = false, print50 = false, print75 = false, print99 = false;
371  // Start the download for the selected boards
372  do
373  {
374  ret = downloader.download_file(CanPacket::everyCANbus, 0x0F, download_type, download_eeprom);
375  if (float(downloader.progress)/downloader.file_length >0.0 && print00==false) {yInfo ("downloading %s, 1%% done\n",buffer); print00=true;}
376  if (float(downloader.progress) / downloader.file_length >0.25 && print25 == false) { yInfo("downloading %s, 25%% done\n", buffer); print25 = true; }
377  if (float(downloader.progress) / downloader.file_length >0.50 && print50 == false) { yInfo("downloading %s, 50%% done\n", buffer); print50 = true; }
378  if (float(downloader.progress) / downloader.file_length >0.75 && print75 == false) { yInfo("downloading %s, 75%% done\n", buffer); print75 = true; }
379  if (float(downloader.progress) / downloader.file_length >0.99 && print99 == false) { yInfo("downloading %s, finished!\n", buffer); print99 = true; }
380 
381  if (ret==1)
382  {
383  //Continuing the download
384  }
385  if (ret==-1)
386  {
387  //Fatal Error during download, terminate
388  finished = 1;
389  }
390  if (ret==0)
391  {
392  //Download terminated
393  finished = 1;
394  }
395 
396  }
397  while (finished!=1);
398  timer_end= yarp::os::Time::now();
399 
400  // End the download for the selected boards
401  int errors =0;
403 
404  //Display result message
405  if (errors==0)
406  {
407  char time_text [50];
408  double download_time = (timer_end-timer_start) ;
409  sprintf (time_text, "All Board OK\nDownload Time (s): %.2f", download_time);
410  return ALL_OK;
411  }
412  else
413  {
415  }
416 
417 }
418 
419 //*********************************************************************************
420 bool validate_selection (int wanted_type)
421 {
422  int first_type = icubCanProto_boardType__unknown;
423  bool something_selected=false;
424  int i=0;
425  for (i=0; i<downloader.board_list_size; i++)
426  {
427  if (downloader.board_list[i].selected==true)
428  {
429  something_selected=true;
430  first_type = downloader.board_list[i].type;
431  }
432  }
433  //check if there is at least one board selected
434  if (something_selected == false)
435  {
436  //if not, this is sthe first board you're going to select,
437  //so it's ok, you can select it
438  return true;
439  }
440 
441  //check the compatibility of the board that you selected now, with
442  //the previous selected ones. all the boards must be of the same type.
443  if (wanted_type != first_type)
444  {
445  return false;
446  }
447  else
448  {
449  return true;
450  }
451  /*
452  switch (wanted_type)
453  {
454  case BOARD_TYPE_DSP:
455  case BOARD_TYPE_2DC:
456  case BOARD_TYPE_4DC:
457  case BOARD_TYPE_BLL:
458  if (first_type == BOARD_TYPE_DSP ||
459  first_type == BOARD_TYPE_2DC ||
460  first_type == BOARD_TYPE_4DC ||
461  first_type == BOARD_TYPE_BLL )
462  return true;
463  else return false;
464  break;
465  case BOARD_TYPE_PIC :
466  case BOARD_TYPE_SKIN :
467  case BOARD_TYPE_STRAIN :
468  case BOARD_TYPE_MAIS :
469  if (first_type == BOARD_TYPE_PIC ||
470  first_type == BOARD_TYPE_STRAIN ||
471  first_type == BOARD_TYPE_MAIS ||
472  first_type == BOARD_TYPE_SKIN )
473  return true;
474  else return false;
475  default:
476  case BOARD_UNKNOWN:
477  return false;
478  break;
479  }
480  */
481  return false;
482 }
483 
484 
485 void fatal_error(int err)
486 {
487  switch (err)
488  {
489  case INVALID_CMD_STRING:
490  yError("Unable to parse the command line. The correct format is:\n");
491  yError("canLoader --canDeviceType t --canDeviceNum x --boardId y --firmware myFirmware.out.S\n");
492  yError("canLoader --canDeviceType ETH --canDeviceNum 1|2 --boardId y --firmware myFirmware.out.S --boardIPAddr aaa.aaa.aaa.aaa\n");
493  ::exit(err);
494  break;
496  yError("invalid --canDeviceType parameter \n");
497  yError("must be 'ecan' or 'pcan' or 'cfw2' or 'socketcan'\n");
498  ::exit(err);
499  break;
501  yError("invalid --canDeviceNum parameter \n");
502  yError("must be between 0 and 3\n");
503  ::exit(err);
504  break;
506  yError("invalid --boardId parameter \n");
507  yError("must be between 0 and 15\n");
508  ::exit(err);
509  break;
510  case INVALID_PARAM_FILE:
511  yError("invalid --firmware parameter \n");
512  yError("file not found\n");
513  ::exit(err);
514  break;
515  case ERR_NO_BOARDS_FOUND:
516  yError("no boards found \n");
517  yError("check canbus cable, power supply connection etc.\n");
518  ::exit(err);
519  break;
521  yError("the specified board is not available \n");
522  ::exit(err);
523  break;
525  yError("could not find network interface\n");
526  ::exit(err);
527  case ERR_UNKNOWN:
528  default:
529  yError("Unknown error\n");
530  ::exit(ERR_UNKNOWN);
531  break;
532 
533  }
534 
535 }
536 
537 //*********************************************************************************
538 // Entry point for the application
539 int myMain( int argc, char *argv[] )
540 {
541  networkType="empty";
542 
543  #ifdef USE_ICUB_MOD
544  yarp::dev::DriverCollection dev;
545  #endif
546 
547  if (argc==2 && strcmp(argv[1],"--calib")==0)
548  {
549  calibration_enabled=true;
550  }
551  //yDebug("argc = %d\n",argc);
552  else if (argc!=1)
553  {
554  prompt_version=true;
555  yInfo("Initializing prompt version of canLoader...\n");
556  if (argc==2 && strcmp(argv[1],"--help")==0)
557  {
558  yInfo("CANLOADER APPLICATION V2.9\n");
559  yInfo("Syntax:\n");
560  yInfo("to execute the command line version of the canLoader:\n");
561  yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --discover\n");
562  yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --boardId <y> --firmware myFirmware.out.S\n");
563  yInfo("./canLoader --canDeviceType ETH --canDeviceNum 1|2 --boardId <y> --firmware myFirmware.out.S --boardIPAddr <aaa.aaa.aaa.aaa>\n");
564  yInfo("parameter <t> is the name of the CAN bus driver. It can be 'ecan' or 'pcan' or 'cfw2can' or 'socketcan'\n");
565  yInfo("parameter <x> is the number of the CAN bus (0-9)\n");
566  yInfo("parameter <y> is the CAN address of the board (0-14)\n");
567  yInfo("parameter <aaa.aaa.aaa.aaa> IP address of the board (ETH boards only)\n");
568  ::exit(0);
569  }
570 
571  //param1
572  if (strcmp(argv[1], "--canDeviceType") != 0) fatal_error(INVALID_CMD_STRING);
573 
574  //param 2
575  if (strcmp(argv[2], "ecan") != 0 &&
576  strcmp(argv[2], "pcan") != 0 &&
577  strcmp(argv[2], "cfw2can") != 0 &&
578  strcmp(argv[2], "socketcan") != 0 &&
579  strcmp(argv[2], "ETH") != 0)
580  {
582  }
583  else
584  {
585  networkType = argv[2];
586  }
587 
588  //param3
589  if (strcmp(argv[3], "--canDeviceNum") != 0) fatal_error(INVALID_CMD_STRING);
590 
591  if (argc == 6)
592  {
593  if (strcmp(argv[5], "--discover") == 0)
594  {
595  start_end_click();
596  ::exit(0);
597  }
598  }
599  if (argc==9 || argc==11)
600  {
601  //yInfo("canLoader --canDeviceType t --canDeviceNum x --boardId y --firmware myFirmware.out.S\n");
602 
603  if (strcmp(argv[5],"--boardId")!=0 &&
604  strcmp(argv[5],"--discover")!=0) fatal_error(INVALID_CMD_STRING);
605 
606  if (strcmp(argv[7],"--firmware")!=0 &&
607  strcmp(argv[7],"--calibration")!=0 &&
608  strcmp(argv[7],"--firmwareANDeeprom")!=0) fatal_error(INVALID_CMD_STRING);
609 
610  int param_board_id=0;
611  std::string param_filename = "empty";
612  int temp_val=-1;
613 
614  if (networkType=="ETH")
615  {
616  if (argc!=11 || strcmp(argv[9],"--boardIPAddr")) fatal_error(INVALID_CMD_STRING);
617 
618  if (!compile_ip_addresses(argv[10]))
619  {
621  }
622  }
623 
624  temp_val=atoi(argv[4]);
625  if (temp_val<0 || temp_val>9)
626  {
628  }
629  else
630  {
631  canID=networkId=temp_val;
632  }
633 
634  temp_val=atoi(argv[6]);
635  if (temp_val<0 || temp_val>15)
636  {
638  }
639  else
640  {
641  param_board_id=temp_val;
642  }
643 
644  param_filename=argv[8];
645  std::fstream filestr;
646  filestr.open ( param_filename.c_str(), std::fstream::in);
647  if (!filestr.is_open())
648  {
649  //file not exists
651  }
652  else
653  {
654  filestr.close();
655  }
656  yInfo("Selecting canDeviceType %s canDeviceNum %d, boardId %d, firmware %s\n", networkType.c_str(), networkId, param_board_id, param_filename.c_str());
657 
658  //eeprom check
659  bool use_eeprom=false;
660  if (strcmp(argv[7],"--firmwareANDeeprom")==0)
661  {
662  yInfo("EEprom flag is active");
663  use_eeprom=true;
664  }
665 
666  start_end_click ();
668  {
670  }
671 
672  int i;
673  bool one_selected=false;
674  for (i = 0; i < downloader.board_list_size; i++)
675  {
676  if (downloader.board_list[i].pid==param_board_id)
677  {
679  one_selected=true;
680  if (use_eeprom==true) downloader.board_list[i].eeprom=true;
681  }
682  }
683  if (one_selected==false)
684  {
686  }
687 
688  int ret=download_click(&param_filename);
689  if (ret==ALL_OK)
690  yInfo("Program terminated successfully!");
691  else
692  yError("Program terminated, DOWNLOAD FAILED!");
693  ::exit(ret);
694  }
695  if (argc!=9)
696  {
697  // fatal_error(INVALID_CMD_STRING);
698  }
699  }
700  else
701  {
702  yInfo("CANLOADER APPLICATION V2.9\n");
703  yInfo("Syntax:\n");
704  yInfo("to execute the command line version of the canLoader:\n");
705  yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --discover\n");
706  yInfo("./canLoader --canDeviceType <t> --canDeviceNum <x> --boardId <y> --firmware myFirmware.out.S\n");
707  yInfo("./canLoader --canDeviceType ETH --canDeviceNum 1|2 --boardId <y> --firmware myFirmware.out.S --boardIPAddr <aaa.aaa.aaa.aaa>\n");
708  yInfo("parameter <t> is the name of the CAN bus driver. It can be 'ecan' or 'pcan' or 'cfw2can' or 'socketcan'\n");
709  yInfo("parameter <x> is the number of the CAN bus (0-9)\n");
710  yInfo("parameter <y> is the CAN address of the board (0-14)\n");
711  yInfo("parameter <aaa.aaa.aaa.aaa> IP address of the board (ETH ethernet boards only)\n");
712  ::exit(0);
713  }
714 
715  return 0;
716 }
717 
718 int main(int argc, char* argv[])
719 {
720  return myMain(argc, argv);
721 }
722 
@ everyCANbus
Definition: driver.h:51
int open_file(std::string file)
int startscheda(int bus, int board_pid, bool board_eeprom, int download_type)
int stopscheda(int bus, int board_pid)
int file_length
Definition: downloader.h:153
int initdriver(yarp::os::Searchable &config, bool verbose=true)
Definition: downloader.cpp:142
sBoard * board_list
Definition: downloader.h:150
int stopdriver()
Definition: downloader.cpp:122
int board_list_size
Definition: downloader.h:151
int initschede()
int download_file(int bus, int board_pid, int download_type, bool eeprom)
bool connected
Definition: downloader.h:158
#define BOARD_RUNNING
Definition: downloader.h:45
#define BOARD_WAITING
Definition: downloader.h:46
int main(int argc, char *argv[])
Definition: main.cpp:31
#define INVALID_PARAM_FILE
Definition: main.cpp:180
int canID
Definition: main.cpp:152
static int download_click(std::string *user_data)
Definition: main.cpp:281
#define ERR_BOARD_ID_NOT_FOUND
Definition: main.cpp:182
#define INVALID_CMD_STRING
Definition: main.cpp:176
bool calibration_enabled
Definition: main.cpp:157
#define ERR_NO_BOARDS_FOUND
Definition: main.cpp:181
const int maxNetworks
Definition: main.cpp:155
#define DOWNLOADERR_NOT_CONNECTED
Definition: main.cpp:185
#define INVALID_PARAM_CANNUM
Definition: main.cpp:178
#define ERR_UNKNOWN
Definition: main.cpp:183
int myMain(int argc, char *argv[])
Definition: main.cpp:539
#define DOWNLOADERR_BOARD_NOT_START
Definition: main.cpp:189
#define DOWNLOADERR_FILE_NOT_OPEN
Definition: main.cpp:188
#define INVALID_PARAM_BOARDID
Definition: main.cpp:179
#define INVALID_PARAM_CANTYPE
Definition: main.cpp:177
cDownloader downloader
Definition: main.cpp:148
std::string networkType
Definition: main.cpp:156
unsigned int remoteAddr
Definition: main.cpp:154
bool prompt_version
Definition: main.cpp:158
static void start_end_click()
Definition: main.cpp:228
#define ERR_NO_NETWORK_INTERFACE
Definition: main.cpp:184
#define DOWNLOADERR_TRANSFER_ERROR
Definition: main.cpp:190
unsigned int localAddr
Definition: main.cpp:153
int networkId
Definition: main.cpp:151
#define ALL_OK
Definition: main.cpp:175
#define DOWNLOADERR_BOARD_NOT_SEL
Definition: main.cpp:186
bool validate_selection(int wanted_type)
Definition: main.cpp:420
void fatal_error(int err)
Definition: main.cpp:485
#define DOWNLOADERR_FILE_NOT_SEL
Definition: main.cpp:187
static bool compile_ip_addresses(const char *addr)
Definition: main.cpp:198
bool eeprom
Definition: downloader.h:39
int bus
Definition: downloader.h:25
int type
Definition: downloader.h:27
int pid
Definition: downloader.h:26
int status
Definition: downloader.h:37
bool selected
Definition: downloader.h:38